PageRenderTime 85ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 1ms

/indra/newview/llviewertexture.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 2430 lines | 1914 code | 309 blank | 207 comment | 327 complexity | 0741c41b5059d516ab42952772805c6b MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llviewertexture.cpp
  3. * @brief Object which handles a received image (and associated texture(s))
  4. *
  5. * $LicenseInfo:firstyear=2000&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 "llviewertexture.h"
  28. // Library includes
  29. #include "imageids.h"
  30. #include "llmath.h"
  31. #include "llerror.h"
  32. #include "llgl.h"
  33. #include "llglheaders.h"
  34. #include "llhost.h"
  35. #include "llimage.h"
  36. #include "llimagebmp.h"
  37. #include "llimagej2c.h"
  38. #include "llimagetga.h"
  39. #include "llmemtype.h"
  40. #include "llstl.h"
  41. #include "llvfile.h"
  42. #include "llvfs.h"
  43. #include "message.h"
  44. #include "lltimer.h"
  45. // viewer includes
  46. #include "llimagegl.h"
  47. #include "lldrawpool.h"
  48. #include "lltexturefetch.h"
  49. #include "llviewertexturelist.h"
  50. #include "llviewercontrol.h"
  51. #include "pipeline.h"
  52. #include "llappviewer.h"
  53. #include "llface.h"
  54. #include "llviewercamera.h"
  55. #include "lltextureatlas.h"
  56. #include "lltextureatlasmanager.h"
  57. #include "lltextureentry.h"
  58. #include "llmediaentry.h"
  59. #include "llvovolume.h"
  60. #include "llviewermedia.h"
  61. ///////////////////////////////////////////////////////////////////////////////
  62. // statics
  63. LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL;
  64. LLPointer<LLViewerTexture> LLViewerTexture::sBlackImagep = NULL;
  65. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sMissingAssetImagep = NULL;
  66. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
  67. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
  68. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
  69. LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap ;
  70. LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL ;
  71. const std::string sTesterName("TextureTester");
  72. S32 LLViewerTexture::sImageCount = 0;
  73. S32 LLViewerTexture::sRawCount = 0;
  74. S32 LLViewerTexture::sAuxCount = 0;
  75. LLFrameTimer LLViewerTexture::sEvaluationTimer;
  76. F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
  77. F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
  78. S32 LLViewerTexture::sBoundTextureMemoryInBytes = 0;
  79. S32 LLViewerTexture::sTotalTextureMemoryInBytes = 0;
  80. S32 LLViewerTexture::sMaxBoundTextureMemInMegaBytes = 0;
  81. S32 LLViewerTexture::sMaxTotalTextureMemInMegaBytes = 0;
  82. S32 LLViewerTexture::sMaxDesiredTextureMemInBytes = 0 ;
  83. S8 LLViewerTexture::sCameraMovingDiscardBias = 0 ;
  84. S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size
  85. const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64 ;
  86. const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez ;
  87. const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128 ;
  88. S32 LLViewerTexture::sMinLargeImageSize = 65536 ; //256 * 256.
  89. S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA ;
  90. BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE ;
  91. F32 LLViewerTexture::sCurrentTime = 0.0f ;
  92. BOOL LLViewerTexture::sUseTextureAtlas = FALSE ;
  93. const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by
  94. const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by
  95. const F64 log_2 = log(2.0);
  96. //----------------------------------------------------------------------------------------------
  97. //namespace: LLViewerTextureAccess
  98. //----------------------------------------------------------------------------------------------
  99. LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,
  100. S32 discard_level,
  101. BOOL need_imageraw, // Needs image raw for the callback
  102. void* userdata,
  103. LLLoadedCallbackEntry::source_callback_list_t* src_callback_list,
  104. LLViewerFetchedTexture* target,
  105. BOOL pause)
  106. : mCallback(cb),
  107. mLastUsedDiscard(MAX_DISCARD_LEVEL+1),
  108. mDesiredDiscard(discard_level),
  109. mNeedsImageRaw(need_imageraw),
  110. mUserData(userdata),
  111. mSourceCallbackList(src_callback_list),
  112. mPaused(pause)
  113. {
  114. if(mSourceCallbackList)
  115. {
  116. mSourceCallbackList->insert(target->getID());
  117. }
  118. }
  119. LLLoadedCallbackEntry::~LLLoadedCallbackEntry()
  120. {
  121. }
  122. void LLLoadedCallbackEntry::removeTexture(LLViewerFetchedTexture* tex)
  123. {
  124. if(mSourceCallbackList)
  125. {
  126. mSourceCallbackList->erase(tex->getID()) ;
  127. }
  128. }
  129. //static
  130. void LLLoadedCallbackEntry::cleanUpCallbackList(LLLoadedCallbackEntry::source_callback_list_t* callback_list)
  131. {
  132. //clear texture callbacks.
  133. if(callback_list && !callback_list->empty())
  134. {
  135. for(LLLoadedCallbackEntry::source_callback_list_t::iterator iter = callback_list->begin();
  136. iter != callback_list->end(); ++iter)
  137. {
  138. LLViewerFetchedTexture* tex = gTextureList.findImage(*iter) ;
  139. if(tex)
  140. {
  141. tex->deleteCallbackEntry(callback_list) ;
  142. }
  143. }
  144. callback_list->clear() ;
  145. }
  146. }
  147. LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID &media_id, BOOL usemipmaps, LLImageGL* gl_image)
  148. {
  149. return new LLViewerMediaTexture(media_id, usemipmaps, gl_image) ;
  150. }
  151. LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id)
  152. {
  153. LLViewerTexture* tex ;
  154. //search fetched texture list
  155. tex = gTextureList.findImage(id) ;
  156. //search media texture list
  157. if(!tex)
  158. {
  159. tex = LLViewerTextureManager::findMediaTexture(id) ;
  160. }
  161. return tex ;
  162. }
  163. LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID &media_id)
  164. {
  165. return LLViewerMediaTexture::findMediaTexture(media_id) ;
  166. }
  167. LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id, BOOL usemipmaps, LLImageGL* gl_image)
  168. {
  169. LLViewerMediaTexture* tex = LLViewerMediaTexture::findMediaTexture(id) ;
  170. if(!tex)
  171. {
  172. tex = LLViewerTextureManager::createMediaTexture(id, usemipmaps, gl_image) ;
  173. }
  174. tex->initVirtualSize() ;
  175. return tex ;
  176. }
  177. LLViewerFetchedTexture* LLViewerTextureManager::staticCastToFetchedTexture(LLTexture* tex, BOOL report_error)
  178. {
  179. if(!tex)
  180. {
  181. return NULL ;
  182. }
  183. S8 type = tex->getType() ;
  184. if(type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
  185. {
  186. return static_cast<LLViewerFetchedTexture*>(tex) ;
  187. }
  188. if(report_error)
  189. {
  190. llerrs << "not a fetched texture type: " << type << llendl ;
  191. }
  192. return NULL ;
  193. }
  194. LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(BOOL usemipmaps, BOOL generate_gl_tex)
  195. {
  196. LLPointer<LLViewerTexture> tex = new LLViewerTexture(usemipmaps) ;
  197. if(generate_gl_tex)
  198. {
  199. tex->generateGLTexture() ;
  200. tex->setCategory(LLViewerTexture::LOCAL) ;
  201. }
  202. return tex ;
  203. }
  204. LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID& id, BOOL usemipmaps, BOOL generate_gl_tex)
  205. {
  206. LLPointer<LLViewerTexture> tex = new LLViewerTexture(id, usemipmaps) ;
  207. if(generate_gl_tex)
  208. {
  209. tex->generateGLTexture() ;
  210. tex->setCategory(LLViewerTexture::LOCAL) ;
  211. }
  212. return tex ;
  213. }
  214. LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps)
  215. {
  216. LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps) ;
  217. tex->setCategory(LLViewerTexture::LOCAL) ;
  218. return tex ;
  219. }
  220. LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex)
  221. {
  222. LLPointer<LLViewerTexture> tex = new LLViewerTexture(width, height, components, usemipmaps) ;
  223. if(generate_gl_tex)
  224. {
  225. tex->generateGLTexture() ;
  226. tex->setCategory(LLViewerTexture::LOCAL) ;
  227. }
  228. return tex ;
  229. }
  230. LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
  231. const LLUUID &image_id,
  232. BOOL usemipmaps,
  233. LLViewerTexture::EBoostLevel boost_priority,
  234. S8 texture_type,
  235. LLGLint internal_format,
  236. LLGLenum primary_format,
  237. LLHost request_from_host)
  238. {
  239. return gTextureList.getImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
  240. }
  241. LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
  242. const std::string& filename,
  243. BOOL usemipmaps,
  244. LLViewerTexture::EBoostLevel boost_priority,
  245. S8 texture_type,
  246. LLGLint internal_format,
  247. LLGLenum primary_format,
  248. const LLUUID& force_id)
  249. {
  250. return gTextureList.getImageFromFile(filename, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
  251. }
  252. //static
  253. LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
  254. BOOL usemipmaps,
  255. LLViewerTexture::EBoostLevel boost_priority,
  256. S8 texture_type,
  257. LLGLint internal_format,
  258. LLGLenum primary_format,
  259. const LLUUID& force_id
  260. )
  261. {
  262. return gTextureList.getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
  263. }
  264. LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, LLHost host)
  265. {
  266. return gTextureList.getImageFromHost(image_id, host) ;
  267. }
  268. void LLViewerTextureManager::init()
  269. {
  270. {
  271. LLPointer<LLImageRaw> raw = new LLImageRaw(1,1,3);
  272. raw->clear(0x77, 0x77, 0x77, 0xFF);
  273. LLViewerTexture::sNullImagep = LLViewerTextureManager::getLocalTexture(raw.get(), TRUE) ;
  274. }
  275. const S32 dim = 128;
  276. LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
  277. U8* data = image_raw->getData();
  278. memset(data, 0, dim * dim * 3) ;
  279. LLViewerTexture::sBlackImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE) ;
  280. #if 1
  281. LLPointer<LLViewerFetchedTexture> imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT);
  282. LLViewerFetchedTexture::sDefaultImagep = imagep;
  283. for (S32 i = 0; i<dim; i++)
  284. {
  285. for (S32 j = 0; j<dim; j++)
  286. {
  287. #if 0
  288. const S32 border = 2;
  289. if (i<border || j<border || i>=(dim-border) || j>=(dim-border))
  290. {
  291. *data++ = 0xff;
  292. *data++ = 0xff;
  293. *data++ = 0xff;
  294. }
  295. else
  296. #endif
  297. {
  298. *data++ = 0x7f;
  299. *data++ = 0x7f;
  300. *data++ = 0x7f;
  301. }
  302. }
  303. }
  304. imagep->createGLTexture(0, image_raw);
  305. //cache the raw image
  306. imagep->setCachedRawImage(0, image_raw) ;
  307. image_raw = NULL;
  308. #else
  309. LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI);
  310. #endif
  311. LLViewerFetchedTexture::sDefaultImagep->dontDiscard();
  312. LLViewerFetchedTexture::sDefaultImagep->setCategory(LLViewerTexture::OTHER) ;
  313. LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI);
  314. LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ;
  315. LLViewerTexture::initClass() ;
  316. if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
  317. {
  318. sTesterp = new LLTexturePipelineTester() ;
  319. if (!sTesterp->isValid())
  320. {
  321. delete sTesterp;
  322. sTesterp = NULL;
  323. }
  324. }
  325. }
  326. void LLViewerTextureManager::cleanup()
  327. {
  328. stop_glerror();
  329. LLImageGL::sDefaultGLTexture = NULL ;
  330. LLViewerTexture::sNullImagep = NULL;
  331. LLViewerTexture::sBlackImagep = NULL;
  332. LLViewerFetchedTexture::sDefaultImagep = NULL;
  333. LLViewerFetchedTexture::sSmokeImagep = NULL;
  334. LLViewerFetchedTexture::sMissingAssetImagep = NULL;
  335. LLViewerFetchedTexture::sWhiteImagep = NULL;
  336. LLViewerMediaTexture::cleanUpClass() ;
  337. }
  338. //----------------------------------------------------------------------------------------------
  339. //----------------------------------------------------------------------------------------------
  340. //start of LLViewerTexture
  341. //----------------------------------------------------------------------------------------------
  342. // static
  343. void LLViewerTexture::initClass()
  344. {
  345. LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture() ;
  346. if(gAuditTexture)
  347. {
  348. LLImageGL::setHighlightTexture(LLViewerTexture::OTHER) ;
  349. }
  350. }
  351. // static
  352. S32 LLViewerTexture::getTotalNumOfCategories()
  353. {
  354. return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ;
  355. }
  356. // static
  357. //index starts from zero.
  358. S32 LLViewerTexture::getIndexFromCategory(S32 category)
  359. {
  360. return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ;
  361. }
  362. //static
  363. S32 LLViewerTexture::getCategoryFromIndex(S32 index)
  364. {
  365. return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ;
  366. }
  367. // tuning params
  368. const F32 discard_bias_delta = .25f;
  369. const F32 discard_delta_time = 0.5f;
  370. const S32 min_non_tex_system_mem = (128<<20); // 128 MB
  371. // non-const (used externally
  372. F32 texmem_lower_bound_scale = 0.85f;
  373. F32 texmem_middle_bound_scale = 0.925f;
  374. static LLFastTimer::DeclareTimer FTM_TEXTURE_MEMORY_CHECK("Memory Check");
  375. //static
  376. bool LLViewerTexture::isMemoryForTextureLow()
  377. {
  378. const F32 WAIT_TIME = 1.0f ; //second
  379. static LLFrameTimer timer ;
  380. if(timer.getElapsedTimeF32() < WAIT_TIME) //call this once per second.
  381. {
  382. return false;
  383. }
  384. timer.reset() ;
  385. LLFastTimer t(FTM_TEXTURE_MEMORY_CHECK);
  386. const S32 MIN_FREE_TEXTURE_MEMORY = 5 ; //MB
  387. const S32 MIN_FREE_MAIN_MEMORy = 100 ; //MB
  388. bool low_mem = false ;
  389. if (gGLManager.mHasATIMemInfo)
  390. {
  391. S32 meminfo[4];
  392. glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
  393. if(meminfo[0] / 1024 < MIN_FREE_TEXTURE_MEMORY)
  394. {
  395. low_mem = true ;
  396. }
  397. if(!low_mem) //check main memory, only works for windows.
  398. {
  399. LLMemory::updateMemoryInfo() ;
  400. if(LLMemory::getAvailableMemKB() / 1024 < MIN_FREE_MAIN_MEMORy)
  401. {
  402. low_mem = true ;
  403. }
  404. }
  405. }
  406. #if 0 //ignore nVidia cards
  407. else if (gGLManager.mHasNVXMemInfo)
  408. {
  409. S32 free_memory;
  410. glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
  411. if(free_memory / 1024 < MIN_FREE_TEXTURE_MEMORY)
  412. {
  413. low_mem = true ;
  414. }
  415. }
  416. #endif
  417. return low_mem ;
  418. }
  419. static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_MEDIA("Media");
  420. static LLFastTimer::DeclareTimer FTM_TEXTURE_UPDATE_TEST("Test");
  421. //static
  422. void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity)
  423. {
  424. sCurrentTime = gFrameTimeSeconds ;
  425. LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
  426. if (tester)
  427. {
  428. LLFastTimer t(FTM_TEXTURE_UPDATE_TEST);
  429. tester->update() ;
  430. }
  431. {
  432. LLFastTimer t(FTM_TEXTURE_UPDATE_MEDIA);
  433. LLViewerMediaTexture::updateClass() ;
  434. }
  435. sBoundTextureMemoryInBytes = LLImageGL::sBoundTextureMemoryInBytes;//in bytes
  436. sTotalTextureMemoryInBytes = LLImageGL::sGlobalTextureMemoryInBytes;//in bytes
  437. sMaxBoundTextureMemInMegaBytes = gTextureList.getMaxResidentTexMem();//in MB
  438. sMaxTotalTextureMemInMegaBytes = gTextureList.getMaxTotalTextureMem() ;//in MB
  439. sMaxDesiredTextureMemInBytes = MEGA_BYTES_TO_BYTES(sMaxTotalTextureMemInMegaBytes) ; //in Bytes, by default and when total used texture memory is small.
  440. if (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) >= sMaxBoundTextureMemInMegaBytes ||
  441. BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) >= sMaxTotalTextureMemInMegaBytes)
  442. {
  443. //when texture memory overflows, lower down the threashold to release the textures more aggressively.
  444. sMaxDesiredTextureMemInBytes = llmin((S32)(sMaxDesiredTextureMemInBytes * 0.75f) , MEGA_BYTES_TO_BYTES(MAX_VIDEO_RAM_IN_MEGA_BYTES)) ;//512 MB
  445. // If we are using more texture memory than we should,
  446. // scale up the desired discard level
  447. if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
  448. {
  449. sDesiredDiscardBias += discard_bias_delta;
  450. sEvaluationTimer.reset();
  451. }
  452. }
  453. else if(sEvaluationTimer.getElapsedTimeF32() > discard_delta_time && isMemoryForTextureLow())
  454. {
  455. sDesiredDiscardBias += discard_bias_delta;
  456. sEvaluationTimer.reset();
  457. }
  458. else if (sDesiredDiscardBias > 0.0f &&
  459. BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < sMaxBoundTextureMemInMegaBytes * texmem_lower_bound_scale &&
  460. BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < sMaxTotalTextureMemInMegaBytes * texmem_lower_bound_scale)
  461. {
  462. // If we are using less texture memory than we should,
  463. // scale down the desired discard level
  464. if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
  465. {
  466. sDesiredDiscardBias -= discard_bias_delta;
  467. sEvaluationTimer.reset();
  468. }
  469. }
  470. sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
  471. LLViewerTexture::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ;
  472. F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ;
  473. F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed();
  474. sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ;
  475. LLViewerTexture::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) &&
  476. (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ;
  477. }
  478. //end of static functions
  479. //-------------------------------------------------------------------------------------------
  480. const U32 LLViewerTexture::sCurrentFileVersion = 1;
  481. LLViewerTexture::LLViewerTexture(BOOL usemipmaps)
  482. {
  483. init(true);
  484. mUseMipMaps = usemipmaps ;
  485. mID.generate();
  486. sImageCount++;
  487. }
  488. LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps)
  489. : mID(id)
  490. {
  491. init(true);
  492. mUseMipMaps = usemipmaps ;
  493. sImageCount++;
  494. }
  495. LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
  496. {
  497. init(true);
  498. mFullWidth = width ;
  499. mFullHeight = height ;
  500. mUseMipMaps = usemipmaps ;
  501. mComponents = components ;
  502. setTexelsPerImage();
  503. mID.generate();
  504. sImageCount++;
  505. }
  506. LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps)
  507. {
  508. init(true);
  509. mUseMipMaps = usemipmaps ;
  510. mGLTexturep = new LLImageGL(raw, usemipmaps) ;
  511. // Create an empty image of the specified size and width
  512. mID.generate();
  513. sImageCount++;
  514. }
  515. LLViewerTexture::~LLViewerTexture()
  516. {
  517. cleanup();
  518. sImageCount--;
  519. }
  520. void LLViewerTexture::init(bool firstinit)
  521. {
  522. mBoostLevel = LLViewerTexture::BOOST_NONE;
  523. mFullWidth = 0;
  524. mFullHeight = 0;
  525. mTexelsPerImage = 0 ;
  526. mUseMipMaps = FALSE ;
  527. mComponents = 0 ;
  528. mTextureState = NO_DELETE ;
  529. mDontDiscard = FALSE;
  530. mMaxVirtualSize = 0.f;
  531. mNeedsGLTexture = FALSE ;
  532. mMaxVirtualSizeResetInterval = 1;
  533. mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;
  534. mAdditionalDecodePriority = 0.f ;
  535. mParcelMedia = NULL ;
  536. mNumFaces = 0 ;
  537. mNumVolumes = 0;
  538. mFaceList.clear() ;
  539. mVolumeList.clear();
  540. }
  541. //virtual
  542. S8 LLViewerTexture::getType() const
  543. {
  544. return LLViewerTexture::LOCAL_TEXTURE ;
  545. }
  546. void LLViewerTexture::cleanup()
  547. {
  548. mFaceList.clear() ;
  549. mVolumeList.clear();
  550. if(mGLTexturep)
  551. {
  552. mGLTexturep->cleanup();
  553. }
  554. }
  555. // virtual
  556. void LLViewerTexture::dump()
  557. {
  558. if(mGLTexturep)
  559. {
  560. mGLTexturep->dump();
  561. }
  562. llinfos << "LLViewerTexture"
  563. << " mID " << mID
  564. << llendl;
  565. }
  566. void LLViewerTexture::setBoostLevel(S32 level)
  567. {
  568. if(mBoostLevel != level)
  569. {
  570. mBoostLevel = level ;
  571. if(mBoostLevel != LLViewerTexture::BOOST_NONE)
  572. {
  573. setNoDelete() ;
  574. }
  575. if(gAuditTexture)
  576. {
  577. setCategory(mBoostLevel);
  578. }
  579. }
  580. }
  581. bool LLViewerTexture::bindDefaultImage(S32 stage)
  582. {
  583. if (stage < 0) return false;
  584. bool res = true;
  585. if (LLViewerFetchedTexture::sDefaultImagep.notNull() && (this != LLViewerFetchedTexture::sDefaultImagep.get()))
  586. {
  587. // use default if we've got it
  588. res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep);
  589. }
  590. if (!res && LLViewerTexture::sNullImagep.notNull() && (this != LLViewerTexture::sNullImagep))
  591. {
  592. res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep);
  593. }
  594. if (!res)
  595. {
  596. llwarns << "LLViewerTexture::bindDefaultImage failed." << llendl;
  597. }
  598. stop_glerror();
  599. //check if there is cached raw image and switch to it if possible
  600. switchToCachedImage() ;
  601. LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
  602. if (tester)
  603. {
  604. tester->updateGrayTextureBinding() ;
  605. }
  606. return res;
  607. }
  608. //virtual
  609. BOOL LLViewerTexture::isMissingAsset()const
  610. {
  611. return FALSE;
  612. }
  613. //virtual
  614. void LLViewerTexture::forceImmediateUpdate()
  615. {
  616. }
  617. void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) const
  618. {
  619. if(needs_gltexture)
  620. {
  621. mNeedsGLTexture = TRUE ;
  622. }
  623. if(!mMaxVirtualSizeResetCounter)
  624. {
  625. //flag to reset the values because the old values are used.
  626. resetMaxVirtualSizeResetCounter() ;
  627. mMaxVirtualSize = virtual_size;
  628. mAdditionalDecodePriority = 0.f ;
  629. mNeedsGLTexture = needs_gltexture ;
  630. }
  631. else if (virtual_size > mMaxVirtualSize)
  632. {
  633. mMaxVirtualSize = virtual_size;
  634. }
  635. }
  636. void LLViewerTexture::resetTextureStats()
  637. {
  638. mMaxVirtualSize = 0.0f ;
  639. mAdditionalDecodePriority = 0.f ;
  640. mMaxVirtualSizeResetCounter = 0 ;
  641. }
  642. //virtual
  643. F32 LLViewerTexture::getMaxVirtualSize()
  644. {
  645. return mMaxVirtualSize ;
  646. }
  647. //virtual
  648. void LLViewerTexture::setKnownDrawSize(S32 width, S32 height)
  649. {
  650. //nothing here.
  651. }
  652. //virtual
  653. void LLViewerTexture::addFace(LLFace* facep)
  654. {
  655. if(mNumFaces >= mFaceList.size())
  656. {
  657. mFaceList.resize(2 * mNumFaces + 1) ;
  658. }
  659. mFaceList[mNumFaces] = facep ;
  660. facep->setIndexInTex(mNumFaces) ;
  661. mNumFaces++ ;
  662. mLastFaceListUpdateTimer.reset() ;
  663. }
  664. //virtual
  665. void LLViewerTexture::removeFace(LLFace* facep)
  666. {
  667. if(mNumFaces > 1)
  668. {
  669. S32 index = facep->getIndexInTex() ;
  670. mFaceList[index] = mFaceList[--mNumFaces] ;
  671. mFaceList[index]->setIndexInTex(index) ;
  672. }
  673. else
  674. {
  675. mFaceList.clear() ;
  676. mNumFaces = 0 ;
  677. }
  678. mLastFaceListUpdateTimer.reset() ;
  679. }
  680. S32 LLViewerTexture::getNumFaces() const
  681. {
  682. return mNumFaces ;
  683. }
  684. //virtual
  685. void LLViewerTexture::addVolume(LLVOVolume* volumep)
  686. {
  687. if( mNumVolumes >= mVolumeList.size())
  688. {
  689. mVolumeList.resize(2 * mNumVolumes + 1) ;
  690. }
  691. mVolumeList[mNumVolumes] = volumep ;
  692. volumep->setIndexInTex(mNumVolumes) ;
  693. mNumVolumes++ ;
  694. mLastVolumeListUpdateTimer.reset() ;
  695. }
  696. //virtual
  697. void LLViewerTexture::removeVolume(LLVOVolume* volumep)
  698. {
  699. if(mNumVolumes > 1)
  700. {
  701. S32 index = volumep->getIndexInTex() ;
  702. mVolumeList[index] = mVolumeList[--mNumVolumes] ;
  703. mVolumeList[index]->setIndexInTex(index) ;
  704. }
  705. else
  706. {
  707. mVolumeList.clear() ;
  708. mNumVolumes = 0 ;
  709. }
  710. mLastVolumeListUpdateTimer.reset() ;
  711. }
  712. S32 LLViewerTexture::getNumVolumes() const
  713. {
  714. return mNumVolumes ;
  715. }
  716. void LLViewerTexture::reorganizeFaceList()
  717. {
  718. static const F32 MAX_WAIT_TIME = 20.f; // seconds
  719. static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
  720. if(mNumFaces + MAX_EXTRA_BUFFER_SIZE > mFaceList.size())
  721. {
  722. return ;
  723. }
  724. if(mLastFaceListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
  725. {
  726. return ;
  727. }
  728. mLastFaceListUpdateTimer.reset() ;
  729. mFaceList.erase(mFaceList.begin() + mNumFaces, mFaceList.end());
  730. }
  731. void LLViewerTexture::reorganizeVolumeList()
  732. {
  733. static const F32 MAX_WAIT_TIME = 20.f; // seconds
  734. static const U32 MAX_EXTRA_BUFFER_SIZE = 4 ;
  735. if(mNumVolumes + MAX_EXTRA_BUFFER_SIZE > mVolumeList.size())
  736. {
  737. return ;
  738. }
  739. if(mLastVolumeListUpdateTimer.getElapsedTimeF32() < MAX_WAIT_TIME)
  740. {
  741. return ;
  742. }
  743. mLastVolumeListUpdateTimer.reset() ;
  744. mVolumeList.erase(mVolumeList.begin() + mNumVolumes, mVolumeList.end());
  745. }
  746. //virtual
  747. void LLViewerTexture::switchToCachedImage()
  748. {
  749. //nothing here.
  750. }
  751. void LLViewerTexture::forceActive()
  752. {
  753. mTextureState = ACTIVE ;
  754. }
  755. void LLViewerTexture::setActive()
  756. {
  757. if(mTextureState != NO_DELETE)
  758. {
  759. mTextureState = ACTIVE ;
  760. }
  761. }
  762. //set the texture to stay in memory
  763. void LLViewerTexture::setNoDelete()
  764. {
  765. mTextureState = NO_DELETE ;
  766. }
  767. void LLViewerTexture::generateGLTexture()
  768. {
  769. if(mGLTexturep.isNull())
  770. {
  771. mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
  772. }
  773. }
  774. LLImageGL* LLViewerTexture::getGLTexture() const
  775. {
  776. llassert(mGLTexturep.notNull()) ;
  777. return mGLTexturep ;
  778. }
  779. BOOL LLViewerTexture::createGLTexture()
  780. {
  781. if(mGLTexturep.isNull())
  782. {
  783. generateGLTexture() ;
  784. }
  785. return mGLTexturep->createGLTexture() ;
  786. }
  787. BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
  788. {
  789. llassert(mGLTexturep.notNull()) ;
  790. BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
  791. if(ret)
  792. {
  793. mFullWidth = mGLTexturep->getCurrentWidth() ;
  794. mFullHeight = mGLTexturep->getCurrentHeight() ;
  795. mComponents = mGLTexturep->getComponents() ;
  796. setTexelsPerImage();
  797. }
  798. return ret ;
  799. }
  800. //virtual
  801. void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
  802. {
  803. //nothing here.
  804. }
  805. void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
  806. {
  807. llassert(mGLTexturep.notNull()) ;
  808. mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
  809. }
  810. void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
  811. {
  812. llassert(mGLTexturep.notNull()) ;
  813. mGLTexturep->setAddressMode(mode) ;
  814. }
  815. void LLViewerTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
  816. {
  817. llassert(mGLTexturep.notNull()) ;
  818. mGLTexturep->setFilteringOption(option) ;
  819. }
  820. //virtual
  821. S32 LLViewerTexture::getWidth(S32 discard_level) const
  822. {
  823. llassert(mGLTexturep.notNull()) ;
  824. return mGLTexturep->getWidth(discard_level) ;
  825. }
  826. //virtual
  827. S32 LLViewerTexture::getHeight(S32 discard_level) const
  828. {
  829. llassert(mGLTexturep.notNull()) ;
  830. return mGLTexturep->getHeight(discard_level) ;
  831. }
  832. S32 LLViewerTexture::getMaxDiscardLevel() const
  833. {
  834. llassert(mGLTexturep.notNull()) ;
  835. return mGLTexturep->getMaxDiscardLevel() ;
  836. }
  837. S32 LLViewerTexture::getDiscardLevel() const
  838. {
  839. llassert(mGLTexturep.notNull()) ;
  840. return mGLTexturep->getDiscardLevel() ;
  841. }
  842. S8 LLViewerTexture::getComponents() const
  843. {
  844. llassert(mGLTexturep.notNull()) ;
  845. return mGLTexturep->getComponents() ;
  846. }
  847. LLGLuint LLViewerTexture::getTexName() const
  848. {
  849. llassert(mGLTexturep.notNull()) ;
  850. return mGLTexturep->getTexName() ;
  851. }
  852. BOOL LLViewerTexture::hasGLTexture() const
  853. {
  854. if(mGLTexturep.notNull())
  855. {
  856. return mGLTexturep->getHasGLTexture() ;
  857. }
  858. return FALSE ;
  859. }
  860. BOOL LLViewerTexture::getBoundRecently() const
  861. {
  862. if(mGLTexturep.notNull())
  863. {
  864. return mGLTexturep->getBoundRecently() ;
  865. }
  866. return FALSE ;
  867. }
  868. LLTexUnit::eTextureType LLViewerTexture::getTarget(void) const
  869. {
  870. llassert(mGLTexturep.notNull()) ;
  871. return mGLTexturep->getTarget() ;
  872. }
  873. BOOL LLViewerTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
  874. {
  875. llassert(mGLTexturep.notNull()) ;
  876. return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
  877. }
  878. BOOL LLViewerTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
  879. {
  880. llassert(mGLTexturep.notNull()) ;
  881. return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
  882. }
  883. void LLViewerTexture::setGLTextureCreated (bool initialized)
  884. {
  885. llassert(mGLTexturep.notNull()) ;
  886. mGLTexturep->setGLTextureCreated (initialized) ;
  887. }
  888. void LLViewerTexture::setCategory(S32 category)
  889. {
  890. llassert(mGLTexturep.notNull()) ;
  891. mGLTexturep->setCategory(category) ;
  892. }
  893. LLTexUnit::eTextureAddressMode LLViewerTexture::getAddressMode(void) const
  894. {
  895. llassert(mGLTexturep.notNull()) ;
  896. return mGLTexturep->getAddressMode() ;
  897. }
  898. S32 LLViewerTexture::getTextureMemory() const
  899. {
  900. llassert(mGLTexturep.notNull()) ;
  901. return mGLTexturep->mTextureMemory ;
  902. }
  903. LLGLenum LLViewerTexture::getPrimaryFormat() const
  904. {
  905. llassert(mGLTexturep.notNull()) ;
  906. return mGLTexturep->getPrimaryFormat() ;
  907. }
  908. BOOL LLViewerTexture::getIsAlphaMask() const
  909. {
  910. llassert(mGLTexturep.notNull()) ;
  911. return mGLTexturep->getIsAlphaMask() ;
  912. }
  913. BOOL LLViewerTexture::getMask(const LLVector2 &tc)
  914. {
  915. llassert(mGLTexturep.notNull()) ;
  916. return mGLTexturep->getMask(tc) ;
  917. }
  918. F32 LLViewerTexture::getTimePassedSinceLastBound()
  919. {
  920. llassert(mGLTexturep.notNull()) ;
  921. return mGLTexturep->getTimePassedSinceLastBound() ;
  922. }
  923. BOOL LLViewerTexture::getMissed() const
  924. {
  925. llassert(mGLTexturep.notNull()) ;
  926. return mGLTexturep->getMissed() ;
  927. }
  928. BOOL LLViewerTexture::isJustBound() const
  929. {
  930. llassert(mGLTexturep.notNull()) ;
  931. return mGLTexturep->isJustBound() ;
  932. }
  933. void LLViewerTexture::forceUpdateBindStats(void) const
  934. {
  935. llassert(mGLTexturep.notNull()) ;
  936. return mGLTexturep->forceUpdateBindStats() ;
  937. }
  938. U32 LLViewerTexture::getTexelsInAtlas() const
  939. {
  940. llassert(mGLTexturep.notNull()) ;
  941. return mGLTexturep->getTexelsInAtlas() ;
  942. }
  943. U32 LLViewerTexture::getTexelsInGLTexture() const
  944. {
  945. llassert(mGLTexturep.notNull()) ;
  946. return mGLTexturep->getTexelsInGLTexture() ;
  947. }
  948. BOOL LLViewerTexture::isGLTextureCreated() const
  949. {
  950. llassert(mGLTexturep.notNull()) ;
  951. return mGLTexturep->isGLTextureCreated() ;
  952. }
  953. S32 LLViewerTexture::getDiscardLevelInAtlas() const
  954. {
  955. llassert(mGLTexturep.notNull()) ;
  956. return mGLTexturep->getDiscardLevelInAtlas() ;
  957. }
  958. void LLViewerTexture::destroyGLTexture()
  959. {
  960. if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
  961. {
  962. mGLTexturep->destroyGLTexture() ;
  963. mTextureState = DELETED ;
  964. }
  965. }
  966. void LLViewerTexture::setTexelsPerImage()
  967. {
  968. S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
  969. S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
  970. mTexelsPerImage = (F32)fullwidth * fullheight;
  971. }
  972. BOOL LLViewerTexture::isLargeImage()
  973. {
  974. return (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize ;
  975. }
  976. //virtual
  977. void LLViewerTexture::updateBindStatsForTester()
  978. {
  979. LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
  980. if (tester)
  981. {
  982. tester->updateTextureBindingStats(this) ;
  983. }
  984. }
  985. //----------------------------------------------------------------------------------------------
  986. //end of LLViewerTexture
  987. //----------------------------------------------------------------------------------------------
  988. //----------------------------------------------------------------------------------------------
  989. //start of LLViewerFetchedTexture
  990. //----------------------------------------------------------------------------------------------
  991. LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps)
  992. : LLViewerTexture(id, usemipmaps),
  993. mTargetHost(host)
  994. {
  995. init(TRUE) ;
  996. generateGLTexture() ;
  997. }
  998. LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps)
  999. : LLViewerTexture(raw, usemipmaps)
  1000. {
  1001. init(TRUE) ;
  1002. }
  1003. LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps)
  1004. : LLViewerTexture(id, usemipmaps),
  1005. mUrl(url)
  1006. {
  1007. init(TRUE) ;
  1008. generateGLTexture() ;
  1009. }
  1010. void LLViewerFetchedTexture::init(bool firstinit)
  1011. {
  1012. mOrigWidth = 0;
  1013. mOrigHeight = 0;
  1014. mNeedsAux = FALSE;
  1015. mRequestedDiscardLevel = -1;
  1016. mRequestedDownloadPriority = 0.f;
  1017. mFullyLoaded = FALSE;
  1018. mCanUseHTTP = true ;
  1019. mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
  1020. mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
  1021. mDecodingAux = FALSE;
  1022. mKnownDrawWidth = 0;
  1023. mKnownDrawHeight = 0;
  1024. mKnownDrawSizeChanged = FALSE ;
  1025. if (firstinit)
  1026. {
  1027. mDecodePriority = 0.f;
  1028. mInImageList = 0;
  1029. }
  1030. // Only set mIsMissingAsset true when we know for certain that the database
  1031. // does not contain this image.
  1032. mIsMissingAsset = FALSE;
  1033. mLoadedCallbackDesiredDiscardLevel = S8_MAX;
  1034. mPauseLoadedCallBacks = TRUE ;
  1035. mNeedsCreateTexture = FALSE;
  1036. mIsRawImageValid = FALSE;
  1037. mRawDiscardLevel = INVALID_DISCARD_LEVEL;
  1038. mMinDiscardLevel = 0;
  1039. mHasFetcher = FALSE;
  1040. mIsFetching = FALSE;
  1041. mFetchState = 0;
  1042. mFetchPriority = 0;
  1043. mDownloadProgress = 0.f;
  1044. mFetchDeltaTime = 999999.f;
  1045. mRequestDeltaTime = 0.f;
  1046. mForSculpt = FALSE ;
  1047. mIsFetched = FALSE ;
  1048. mCachedRawImage = NULL ;
  1049. mCachedRawDiscardLevel = -1 ;
  1050. mCachedRawImageReady = FALSE ;
  1051. mSavedRawImage = NULL ;
  1052. mForceToSaveRawImage = FALSE ;
  1053. mSaveRawImage = FALSE ;
  1054. mSavedRawDiscardLevel = -1 ;
  1055. mDesiredSavedRawDiscardLevel = -1 ;
  1056. mLastReferencedSavedRawImageTime = 0.0f ;
  1057. mKeptSavedRawImageTime = 0.f ;
  1058. mLastCallBackActiveTime = 0.f;
  1059. }
  1060. LLViewerFetchedTexture::~LLViewerFetchedTexture()
  1061. {
  1062. //*NOTE getTextureFetch can return NULL when Viewer is shutting down.
  1063. // This is due to LLWearableList is singleton and is destroyed after
  1064. // LLAppViewer::cleanup() was called. (see ticket EXT-177)
  1065. if (mHasFetcher && LLAppViewer::getTextureFetch())
  1066. {
  1067. LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
  1068. }
  1069. cleanup();
  1070. }
  1071. //virtual
  1072. S8 LLViewerFetchedTexture::getType() const
  1073. {
  1074. return LLViewerTexture::FETCHED_TEXTURE ;
  1075. }
  1076. void LLViewerFetchedTexture::cleanup()
  1077. {
  1078. for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
  1079. iter != mLoadedCallbackList.end(); )
  1080. {
  1081. LLLoadedCallbackEntry *entryp = *iter++;
  1082. // We never finished loading the image. Indicate failure.
  1083. // Note: this allows mLoadedCallbackUserData to be cleaned up.
  1084. entryp->mCallback( FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData );
  1085. entryp->removeTexture(this) ;
  1086. delete entryp;
  1087. }
  1088. mLoadedCallbackList.clear();
  1089. mNeedsAux = FALSE;
  1090. // Clean up image data
  1091. destroyRawImage();
  1092. mCachedRawImage = NULL ;
  1093. mCachedRawDiscardLevel = -1 ;
  1094. mCachedRawImageReady = FALSE ;
  1095. mSavedRawImage = NULL ;
  1096. }
  1097. void LLViewerFetchedTexture::setForSculpt()
  1098. {
  1099. static const S32 MAX_INTERVAL = 8 ; //frames
  1100. mForSculpt = TRUE ;
  1101. if(isForSculptOnly() && !getBoundRecently())
  1102. {
  1103. destroyGLTexture() ; //sculpt image does not need gl texture.
  1104. }
  1105. checkCachedRawSculptImage() ;
  1106. setMaxVirtualSizeResetInterval(MAX_INTERVAL) ;
  1107. }
  1108. BOOL LLViewerFetchedTexture::isForSculptOnly() const
  1109. {
  1110. return mForSculpt && !mNeedsGLTexture ;
  1111. }
  1112. BOOL LLViewerFetchedTexture::isDeleted()
  1113. {
  1114. return mTextureState == DELETED ;
  1115. }
  1116. BOOL LLViewerFetchedTexture::isInactive()
  1117. {
  1118. return mTextureState == INACTIVE ;
  1119. }
  1120. BOOL LLViewerFetchedTexture::isDeletionCandidate()
  1121. {
  1122. return mTextureState == DELETION_CANDIDATE ;
  1123. }
  1124. void LLViewerFetchedTexture::setDeletionCandidate()
  1125. {
  1126. if(mGLTexturep.notNull() && mGLTexturep->getTexName() && (mTextureState == INACTIVE))
  1127. {
  1128. mTextureState = DELETION_CANDIDATE ;
  1129. }
  1130. }
  1131. //set the texture inactive
  1132. void LLViewerFetchedTexture::setInactive()
  1133. {
  1134. if(mTextureState == ACTIVE && mGLTexturep.notNull() && mGLTexturep->getTexName() && !mGLTexturep->getBoundRecently())
  1135. {
  1136. mTextureState = INACTIVE ;
  1137. }
  1138. }
  1139. BOOL LLViewerFetchedTexture::isFullyLoaded() const
  1140. {
  1141. // Unfortunately, the boolean "mFullyLoaded" is never updated correctly so we use that logic
  1142. // to check if the texture is there and completely downloaded
  1143. return (mFullWidth != 0) && (mFullHeight != 0) && !mIsFetching && !mHasFetcher;
  1144. }
  1145. // virtual
  1146. void LLViewerFetchedTexture::dump()
  1147. {
  1148. LLViewerTexture::dump();
  1149. llinfos << "Dump : " << mID
  1150. << ", mIsMissingAsset = " << (S32)mIsMissingAsset
  1151. << ", mFullWidth = " << (S32)mFullWidth
  1152. << ", mFullHeight = " << (S32)mFullHeight
  1153. << ", mOrigWidth = " << (S32)mOrigWidth
  1154. << ", mOrigHeight = " << (S32)mOrigHeight
  1155. << llendl;
  1156. llinfos << " : "
  1157. << " mFullyLoaded = " << (S32)mFullyLoaded
  1158. << ", mFetchState = " << (S32)mFetchState
  1159. << ", mFetchPriority = " << (S32)mFetchPriority
  1160. << ", mDownloadProgress = " << (F32)mDownloadProgress
  1161. << llendl;
  1162. llinfos << " : "
  1163. << " mHasFetcher = " << (S32)mHasFetcher
  1164. << ", mIsFetching = " << (S32)mIsFetching
  1165. << ", mIsFetched = " << (S32)mIsFetched
  1166. << ", mBoostLevel = " << (S32)mBoostLevel
  1167. << llendl;
  1168. }
  1169. ///////////////////////////////////////////////////////////////////////////////
  1170. // ONLY called from LLViewerFetchedTextureList
  1171. void LLViewerFetchedTexture::destroyTexture()
  1172. {
  1173. if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
  1174. {
  1175. return ;
  1176. }
  1177. if (mNeedsCreateTexture)//return if in the process of generating a new texture.
  1178. {
  1179. return ;
  1180. }
  1181. destroyGLTexture() ;
  1182. mFullyLoaded = FALSE ;
  1183. }
  1184. void LLViewerFetchedTexture::addToCreateTexture()
  1185. {
  1186. bool force_update = false ;
  1187. if (getComponents() != mRawImage->getComponents())
  1188. {
  1189. // We've changed the number of components, so we need to move any
  1190. // objects using this pool to a different pool.
  1191. mComponents = mRawImage->getComponents();
  1192. mGLTexturep->setComponents(mComponents) ;
  1193. force_update = true ;
  1194. for(U32 i = 0 ; i < mNumFaces ; i++)
  1195. {
  1196. mFaceList[i]->dirtyTexture() ;
  1197. }
  1198. //discard the cached raw image and the saved raw image
  1199. mCachedRawImageReady = FALSE ;
  1200. mCachedRawDiscardLevel = -1 ;
  1201. mCachedRawImage = NULL ;
  1202. mSavedRawDiscardLevel = -1 ;
  1203. mSavedRawImage = NULL ;
  1204. }
  1205. if(isForSculptOnly())
  1206. {
  1207. //just update some variables, not to create a real GL texture.
  1208. createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE) ;
  1209. mNeedsCreateTexture = FALSE ;
  1210. destroyRawImage();
  1211. }
  1212. else if(!force_update && getDiscardLevel() > -1 && getDiscardLevel() <= mRawDiscardLevel)
  1213. {
  1214. mNeedsCreateTexture = FALSE ;
  1215. destroyRawImage();
  1216. }
  1217. else
  1218. {
  1219. #if 1
  1220. //
  1221. //if mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the required image res keep going up,
  1222. //so do not scale down the over qualified image.
  1223. //Note: scaling down image is expensensive. Do it only when very necessary.
  1224. //
  1225. if(mRequestedDiscardLevel <= mDesiredDiscardLevel && !mForceToSaveRawImage)
  1226. {
  1227. S32 w = mFullWidth >> mRawDiscardLevel;
  1228. S32 h = mFullHeight >> mRawDiscardLevel;
  1229. //if big image, do not load extra data
  1230. //scale it down to size >= LLViewerTexture::sMinLargeImageSize
  1231. if(w * h > LLViewerTexture::sMinLargeImageSize)
  1232. {
  1233. S32 d_level = llmin(mRequestedDiscardLevel, (S32)mDesiredDiscardLevel) - mRawDiscardLevel ;
  1234. if(d_level > 0)
  1235. {
  1236. S32 i = 0 ;
  1237. while((d_level > 0) && ((w >> i) * (h >> i) > LLViewerTexture::sMinLargeImageSize))
  1238. {
  1239. i++;
  1240. d_level--;
  1241. }
  1242. if(i > 0)
  1243. {
  1244. mRawDiscardLevel += i ;
  1245. if(mRawDiscardLevel >= getDiscardLevel() && getDiscardLevel() > 0)
  1246. {
  1247. mNeedsCreateTexture = FALSE ;
  1248. destroyRawImage();
  1249. return ;
  1250. }
  1251. mRawImage->scale(w >> i, h >> i) ;
  1252. }
  1253. }
  1254. }
  1255. }
  1256. #endif
  1257. mNeedsCreateTexture = TRUE;
  1258. gTextureList.mCreateTextureList.insert(this);
  1259. }
  1260. return ;
  1261. }
  1262. // ONLY called from LLViewerTextureList
  1263. BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
  1264. {
  1265. if (!mNeedsCreateTexture)
  1266. {
  1267. destroyRawImage();
  1268. return FALSE;
  1269. }
  1270. mNeedsCreateTexture = FALSE;
  1271. if (mRawImage.isNull())
  1272. {
  1273. llerrs << "LLViewerTexture trying to create texture with no Raw Image" << llendl;
  1274. }
  1275. // llinfos << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ",
  1276. // mRawDiscardLevel,
  1277. // mRawImage->getWidth(), mRawImage->getHeight(),mRawImage->getDataSize())
  1278. // << mID.getString() << llendl;
  1279. BOOL res = TRUE;
  1280. // store original size only for locally-sourced images
  1281. if (mUrl.compare(0, 7, "file://") == 0)
  1282. {
  1283. mOrigWidth = mRawImage->getWidth();
  1284. mOrigHeight = mRawImage->getHeight();
  1285. if (mBoostLevel == BOOST_PREVIEW)
  1286. {
  1287. mRawImage->biasedScaleToPowerOfTwo(1024);
  1288. }
  1289. else
  1290. { // leave black border, do not scale image content
  1291. mRawImage->expandToPowerOfTwo(MAX_IMAGE_SIZE, FALSE);
  1292. }
  1293. mFullWidth = mRawImage->getWidth();
  1294. mFullHeight = mRawImage->getHeight();
  1295. setTexelsPerImage();
  1296. }
  1297. else
  1298. {
  1299. mOrigWidth = mFullWidth;
  1300. mOrigHeight = mFullHeight;
  1301. }
  1302. bool size_okay = true;
  1303. U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel;
  1304. U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel;
  1305. if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE )
  1306. {
  1307. llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl;
  1308. size_okay = false;
  1309. }
  1310. if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
  1311. {
  1312. // A non power-of-two image was uploaded (through a non standard client)
  1313. llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl;
  1314. size_okay = false;
  1315. }
  1316. if( !size_okay )
  1317. {
  1318. // An inappropriately-sized image was uploaded (through a non standard client)
  1319. // We treat these images as missing assets which causes them to
  1320. // be renderd as 'missing image' and to stop requesting data
  1321. setIsMissingAsset();
  1322. destroyRawImage();
  1323. return FALSE;
  1324. }
  1325. if(!(res = insertToAtlas()))
  1326. {
  1327. res = mGLTexturep->createGLTexture(mRawDiscardLevel, mRawImage, usename, TRUE, mBoostLevel);
  1328. resetFaceAtlas() ;
  1329. }
  1330. setActive() ;
  1331. if (!needsToSaveRawImage())
  1332. {
  1333. mNeedsAux = FALSE;
  1334. destroyRawImage();
  1335. }
  1336. return res;
  1337. }
  1338. // Call with 0,0 to turn this feature off.
  1339. //virtual
  1340. void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
  1341. {
  1342. if(mKnownDrawWidth < width || mKnownDrawHeight < height)
  1343. {
  1344. mKnownDrawWidth = llmax(mKnownDrawWidth, width) ;
  1345. mKnownDrawHeight = llmax(mKnownDrawHeight, height) ;
  1346. mKnownDrawSizeChanged = TRUE ;
  1347. mFullyLoaded = FALSE ;
  1348. }
  1349. addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight));
  1350. }
  1351. //virtual
  1352. void LLViewerFetchedTexture::processTextureStats()
  1353. {
  1354. if(mFullyLoaded)
  1355. {
  1356. if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more
  1357. {
  1358. mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel) ;
  1359. mFullyLoaded = FALSE ;
  1360. }
  1361. }
  1362. else
  1363. {
  1364. updateVirtualSize() ;
  1365. static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes");
  1366. if (textures_fullres)
  1367. {
  1368. mDesiredDiscardLevel = 0;
  1369. }
  1370. else if(!mFullWidth || !mFullHeight)
  1371. {
  1372. mDesiredDiscardLevel = llmin(getMaxDiscardLevel(), (S32)mLoadedCallbackDesiredDiscardLevel) ;
  1373. }
  1374. else
  1375. {
  1376. if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight)
  1377. {
  1378. if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
  1379. {
  1380. mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
  1381. }
  1382. else
  1383. {
  1384. mDesiredDiscardLevel = 0;
  1385. }
  1386. }
  1387. else if(mKnownDrawSizeChanged)//known draw size is set
  1388. {
  1389. mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2,
  1390. log((F32)mFullHeight / mKnownDrawHeight) / log_2) ;
  1391. mDesiredDiscardLevel = llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()) ;
  1392. mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel) ;
  1393. }
  1394. mKnownDrawSizeChanged = FALSE ;
  1395. if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel))
  1396. {
  1397. mFullyLoaded = TRUE ;
  1398. }
  1399. }
  1400. }
  1401. if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) //force to refetch the texture.
  1402. {
  1403. mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel) ;
  1404. if(getDiscardLevel() < 0 || getDiscardLevel() > mDesiredDiscardLevel)
  1405. {
  1406. mFullyLoaded = FALSE ;
  1407. }
  1408. }
  1409. }
  1410. const F32 MAX_PRIORITY_PIXEL = 999.f ; //pixel area
  1411. const F32 PRIORITY_BOOST_LEVEL_FACTOR = 1000.f ; //boost level
  1412. const F32 PRIORITY_DELTA_DISCARD_LEVEL_FACTOR = 100000.f ; //delta discard
  1413. const S32 MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY = 4 ;
  1414. const F32 PRIORITY_ADDITIONAL_FACTOR = 1000000.f ; //additional
  1415. const S32 MAX_ADDITIONAL_LEVEL_FOR_PRIORITY = 8 ;
  1416. const F32 PRIORITY_BOOST_HIGH_FACTOR = 10000000.f ;//boost high
  1417. F32 LLViewerFetchedTexture::calcDecodePriority()
  1418. {
  1419. #ifndef LL_RELEASE_FOR_DOWNLOAD
  1420. if (mID == LLAppViewer::getTextureFetch()->mDebugID)
  1421. {
  1422. LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
  1423. }
  1424. #endif
  1425. if (mNeedsCreateTexture)
  1426. {
  1427. return mDecodePriority; // no change while waiting to create
  1428. }
  1429. if(mFullyLoaded && !mForceToSaveRawImage)//already loaded for static texture
  1430. {
  1431. return -1.0f ; //alreay fetched
  1432. }
  1433. S32 cur_discard = getCurrentDiscardLevelForFetching();
  1434. bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel));
  1435. F32 pixel_priority = (F32) sqrt(mMaxVirtualSize);
  1436. F32 priority = 0.f;
  1437. if (mIsMissingAsset)
  1438. {
  1439. priority = 0.0f;
  1440. }
  1441. else if(mDesiredDiscardLevel >= cur_discard && cur_discard > -1)
  1442. {
  1443. priority = -2.0f ;
  1444. }
  1445. else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel)
  1446. {
  1447. priority = -3.0f;
  1448. }
  1449. else if (mDesiredDiscardLevel > getMaxDiscardLevel())
  1450. {
  1451. // Don't decode anything we don't need
  1452. priority = -4.0f;
  1453. }
  1454. else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data)
  1455. {
  1456. priority = 1.f;
  1457. }
  1458. else if (pixel_priority < 0.001f && !have_all_data)
  1459. {
  1460. // Not on screen but we might want some data
  1461. if (mBoostLevel > BOOST_HIGH)
  1462. {
  1463. // Always want high boosted images
  1464. priority = 1.f;
  1465. }
  1466. else
  1467. {
  1468. priority = -5.f; //stop fetching
  1469. }
  1470. }
  1471. else if (cur_discard < 0)
  1472. {
  1473. //texture does not have any data, so we don't know the size of the image, treat it like 32 * 32.
  1474. // priority range = 100,000 - 500,000
  1475. static const F64 log_2 = log(2.0);
  1476. F32 desired = (F32)(log(32.0/pixel_priority) / log_2);
  1477. S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;
  1478. ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
  1479. priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
  1480. setAdditionalDecodePriority(1.0f) ;//boost the textures without any data so far.
  1481. }
  1482. else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
  1483. {
  1484. // larger mips are corrupted
  1485. priority = -6.0f;
  1486. }
  1487. else
  1488. {
  1489. // priority range = 100,000 - 500,000
  1490. S32 desired_discard = mDesiredDiscardLevel;
  1491. if (!isJustBound() && mCachedRawImageReady)
  1492. {
  1493. if(mBoostLevel < BOOST_HIGH)
  1494. {
  1495. // We haven't rendered this in a while, de-prioritize it
  1496. desired_discard += 2;
  1497. }
  1498. else
  1499. {
  1500. // We haven't rendered this in the last half second, and we have a cached raw image, leave the desired discard as-is
  1501. desired_discard = cur_discard;
  1502. }
  1503. }
  1504. S32 ddiscard = cur_discard - desired_discard;
  1505. ddiscard = llclamp(ddiscard, -1, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
  1506. priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
  1507. }
  1508. // Priority Formula:
  1509. // BOOST_HIGH + ADDITIONAL PRI + DELTA DISCARD + BOOST LEVEL + PIXELS
  1510. // [10,000,000] + [1,000,000-9,000,000] + [100,000-500,000] + [1-20,000] + [0-999]
  1511. if (priority > 0.0f)
  1512. {
  1513. bool large_enough = mCachedRawImageReady && ((S32)mTexelsPerImage > sMinLargeImageSize) ;
  1514. if(large_enough)
  1515. {
  1516. //Note:
  1517. //to give small, low-priority textures some chance to be fetched,
  1518. //cut the priority in half if the texture size is larger than 256 * 256 and has a 64*64 ready.
  1519. priority *= 0.5f ;
  1520. }
  1521. pixel_priority = llclamp(pixel_priority, 0.0f, MAX_PRIORITY_PIXEL);
  1522. priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel;
  1523. if ( mBoostLevel > BOOST_HIGH)
  1524. {
  1525. if(mBoostLevel > BOOST_SUPER_HIGH)
  1526. {
  1527. //for very important textures, always grant the highest priority.
  1528. priority += PRIORITY_BOOST_HIGH_FACTOR;
  1529. }
  1530. else if(mCachedRawImageReady)
  1531. {
  1532. //Note:
  1533. //to give small, low-priority textures some chance to be fetched,
  1534. //if high priority texture has a 64*64 ready, lower its fetching priority.
  1535. setAdditionalDecodePriority(0.5f) ;
  1536. }
  1537. else
  1538. {
  1539. priority += PRIORITY_BOOST_HIGH_FACTOR;
  1540. }
  1541. }
  1542. if(mAdditionalDecodePriority > 0.0f)
  1543. {
  1544. // priority range += 1,000,000.f-9,000,000.f
  1545. F32 additional = PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY);
  1546. if(large_enough)
  1547. {
  1548. //Note:
  1549. //to give small, low-priority textures some chance to be fetched,
  1550. //cut the additional priority to a quarter if the texture size is larger than 256 * 256 and has a 64*64 ready.
  1551. additional *= 0.25f ;
  1552. }
  1553. priority += additional;
  1554. }
  1555. }
  1556. return priority;
  1557. }
  1558. //static
  1559. F32 LLViewerFetchedTexture::maxDecodePriority()
  1560. {
  1561. static const F32 max_priority = PRIORITY_BOOST_HIGH_FACTOR + //boost_high
  1562. PRIORITY_ADDITIONAL_FACTOR * (MAX_ADDITIONAL_LEVEL_FOR_PRIORITY + 1) + //additional (view dependent factors)
  1563. PRIORITY_DELTA_DISCARD_LEVEL_FACTOR * (MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY + 1) + //delta discard
  1564. PRIORITY_BOOST_LEVEL_FACTOR * (BOOST_MAX_LEVEL - 1) + //boost level
  1565. MAX_PRIORITY_PIXEL + 1.0f ; //pixel area.
  1566. return max_priority ;
  1567. }
  1568. //============================================================================
  1569. void LLViewerFetchedTexture::setDecodePriority(F32 priority)
  1570. {
  1571. llassert(!mInImageList);
  1572. mDecodePriority = priority;
  1573. if(mDecodePriority < F_ALMOST_ZERO)
  1574. {
  1575. mStopFetchingTimer.reset() ;
  1576. }
  1577. }
  1578. void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
  1579. {
  1580. priority = llclamp(priority, 0.f, 1.f);
  1581. if(mAdditionalDecodePriority < priority)
  1582. {
  1583. mAdditionalDecodePriority = priority;
  1584. }
  1585. }
  1586. void LLViewerFetchedTexture::updateVirtualSize()
  1587. {
  1588. if(!mMaxVirtualSizeResetCounter)
  1589. {
  1590. addTextureStats(0.f, FALSE) ;//reset
  1591. }
  1592. for(U32 i = 0 ; i < mNumFaces ; i++)
  1593. {
  1594. LLFace* facep = mFaceList[i] ;
  1595. if(facep->getDrawable()->isRecentlyVisible())
  1596. {
  1597. addTextureStats(facep->getVirtualSize()) ;
  1598. setAdditionalDecodePriority(facep->getImportanceToCamera()) ;
  1599. }
  1600. }
  1601. if(mMaxVirtualSizeResetCounter > 0)
  1602. {
  1603. mMaxVirtualSizeResetCounter--;
  1604. }
  1605. reorganizeFaceList() ;
  1606. reorganizeVolumeList();
  1607. }
  1608. S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching()
  1609. {
  1610. S32 current_discard = getDiscardLevel() ;
  1611. if(mForceToSaveRawImage)
  1612. {
  1613. if(mSavedRawDiscardLevel < 0 || current_discard < 0)
  1614. {
  1615. current_discard = -1 ;
  1616. }
  1617. else
  1618. {
  1619. current_discard = llmax(current_discard, mSavedRawDiscardLevel) ;
  1620. }
  1621. }
  1622. return current_discard ;
  1623. }
  1624. bool LLViewerFetchedTexture::updateFetch()
  1625. {
  1626. static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled");
  1627. if(textures_decode_disabled)
  1628. {
  1629. return false ;
  1630. }
  1631. mFetchState = 0;
  1632. mFetchPriority = 0;
  1633. mFetchDeltaTime = 999999.f;
  1634. mRequestDeltaTime = 999999.f;
  1635. #ifndef LL_RELEASE_FOR_DOWNLOAD
  1636. if (mID == LLAppViewer::getTextureFetch()->mDebugID)
  1637. {
  1638. LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
  1639. }
  1640. #endif
  1641. if (mNeedsCreateTexture)
  1642. {
  1643. // We may be fetching still (e.g. waiting on write)
  1644. // but don't check until we've processed the raw data we have
  1645. return false;
  1646. }
  1647. if (mIsMissingAsset)
  1648. {
  1649. llassert_always(!mHasFetcher);
  1650. return false; // skip
  1651. }
  1652. if (!mLoadedCallbackList.empty() && mRawImage.notNull())
  1653. {
  1654. return false; // process any raw image data in callbacks before replacing
  1655. }
  1656. S32 current_discard = getCurrentDiscardLevelForFetching() ;
  1657. S32 desired_discard = getDesiredDiscardLevel();
  1658. F32 decode_priority = getDecodePriority();
  1659. decode_priority = llclamp(decode_priority, 0.0f, maxDecodePriority());
  1660. if (mIsFetching)
  1661. {
  1662. // Sets mRawDiscardLevel, mRawImage, mAuxRawImage
  1663. S32 fetch_discard = current_discard;
  1664. if (mRawImage.notNull()) sRawCount--;
  1665. if (mAuxRawImage.notNull()) sAuxCount--;
  1666. bool finished = LLAppViewer::getTextureFetch()->getRequestFinished(getID(), fetch_discard, mRawImage, mAuxRawImage);
  1667. if (mRawImage.notNull()) sRawCount++;
  1668. if (mAuxRawImage.notNull()) sAuxCount++;
  1669. if (finished)
  1670. {
  1671. mIsFetching = FALSE;
  1672. mLastPacketTimer.reset() ;
  1673. }
  1674. else
  1675. {
  1676. mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
  1677. mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
  1678. }
  1679. // We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
  1680. if (mRawImage.notNull())
  1681. {
  1682. LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
  1683. if (tester)
  1684. {
  1685. mIsFetched = TRUE ;
  1686. tester->updateTextureLoadingStats(this, mRawImage, LLAppViewer::getTextureFetch()->isFromLocalCache(mID)) ;
  1687. }
  1688. mRawDiscardLevel = fetch_discard;
  1689. if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&
  1690. (current_discard < 0 || mRawDiscardLevel < current_discard))
  1691. {
  1692. mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
  1693. mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
  1694. setTexelsPerImage();
  1695. if(mFullWidth > MAX_IMAGE_SIZE || mFullHeight > MAX_IMAGE_SIZE)
  1696. {
  1697. //discard all oversized textures.
  1698. destroyRawImage();
  1699. setIsMissingAsset();
  1700. mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
  1701. mIsFetching = FALSE ;
  1702. mLastPacketTimer.reset();
  1703. }
  1704. else
  1705. {
  1706. mIsRawImageValid = TRUE;
  1707. addToCreateTexture() ;
  1708. }
  1709. return TRUE ;
  1710. }
  1711. else
  1712. {
  1713. // Data is ready but we don't need it
  1714. // (received it already while fetcher was writing to disk)
  1715. destroyRawImage();
  1716. return false; // done
  1717. }
  1718. }
  1719. if (!mIsFetching)
  1720. {
  1721. if ((decode_priority > 0) && (mRawDiscardLevel < 0 || mRawDiscardLevel == INVALID_DISCARD_LEVEL))
  1722. {
  1723. // We finished but received no data
  1724. if (current_discard < 0)
  1725. {
  1726. setIsMissingAsset();
  1727. desired_discard = -1;
  1728. }
  1729. else
  1730. {
  1731. //llwarns << mID << ": Setting min discard to " << current_discard << llendl;
  1732. mMinDiscardLevel = current_discard;
  1733. desired_discard = current_discard;
  1734. }
  1735. destroyRawImage();
  1736. }
  1737. else if (mRawImage.notNull())
  1738. {
  1739. // We have data, but our fetch failed to return raw data
  1740. // *TODO: FIgure out why this is happening and fix it
  1741. destroyRawImage();
  1742. }
  1743. }
  1744. else
  1745. {
  1746. // // Useful debugging code for undesired deprioritization of textures.
  1747. // if (decode_priority <= 0.0f && desired_discard >= 0 && desired_discard < current_discard)
  1748. // {
  1749. // llinfos << "Calling updateRequestPriority() with decode_priority = 0.0f" << llendl;
  1750. // calcDecodePriority();
  1751. // }
  1752. static const F32 MAX_HOLD_TIME = 5.0f ; //seconds to wait before canceling fecthing if decode_priority is 0.f.
  1753. if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME)
  1754. {
  1755. mStopFetchingTimer.reset() ;
  1756. LLAppViewer::getTextureFetch()->updateRequestPriority(mID, decode_priority);
  1757. }
  1758. }
  1759. }
  1760. bool make_request = true;
  1761. if (decode_priority <= 0)
  1762. {
  1763. make_request = false;
  1764. }
  1765. else if (mNeedsCreateTexture || mIsMissingAsset)
  1766. {
  1767. make_request = false;
  1768. }
  1769. else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)
  1770. {
  1771. make_request = false;
  1772. }
  1773. //else if (!isJustBound() && mCachedRawImageReady)
  1774. //{
  1775. // make_request = false;
  1776. //}
  1777. if(make_request)
  1778. {
  1779. //load the texture progressively.
  1780. S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ;
  1781. if(current_discard < 0)
  1782. {
  1783. desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level);
  1784. }
  1785. else
  1786. {
  1787. desired_discard = llmax(desired_discard, current_discard - delta_level);
  1788. }
  1789. if (mIsFetching)
  1790. {
  1791. if (mRequestedDiscardLevel <= desired_discard)
  1792. {
  1793. make_request = false;
  1794. }
  1795. }
  1796. else
  1797. {
  1798. if (current_discard >= 0 && current_discard <= desired_discard)
  1799. {
  1800. make_request = false;
  1801. }
  1802. }
  1803. }
  1804. if (make_request)
  1805. {
  1806. S32 w=0, h=0, c=0;
  1807. if (getDiscardLevel() >= 0)
  1808. {
  1809. w = mGLTexturep->getWidth(0);
  1810. h = mGLTexturep->getHeight(0);
  1811. c = mComponents;
  1812. }
  1813. const U32 override_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel");
  1814. if (override_tex_discard_level != 0)
  1815. {
  1816. desired_discard = override_tex_discard_level;
  1817. }
  1818. // bypass texturefetch directly by pulling from LLTextureCache
  1819. bool fetch_request_created = false;
  1820. fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), decode_priority,
  1821. w, h, c, desired_discard, needsAux(), mCanUseHTTP);
  1822. if (fetch_request_created)
  1823. {
  1824. mHasFetcher = TRUE;
  1825. mIsFetching = TRUE;
  1826. mRequestedDiscardLevel = desired_discard;
  1827. mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
  1828. mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
  1829. }
  1830. // if createRequest() failed, we're finishing up a request for this UUID,
  1831. // wait for it to complete
  1832. }
  1833. else if (mHasFetcher && !mIsFetching)
  1834. {
  1835. // Only delete requests that haven't receeived any network data for a while
  1836. const F32 FETCH_IDLE_TIME = 5.f;
  1837. if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
  1838. {
  1839. // llinfos << "Deleting request: " << getID() << " Discard: " << current_discard << " <= min:" << mMinDiscardLevel << " or priority == 0: " << decode_priority << llendl;
  1840. LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
  1841. mHasFetcher = FALSE;
  1842. }
  1843. }
  1844. llassert_always(mRawImage.notNull() || (!mNeedsCreateTexture && !mIsRawImageValid));
  1845. return mIsFetching ? true : false;
  1846. }
  1847. void LLViewerFetchedTexture::setIsMissingAsset()
  1848. {
  1849. if (mUrl.empty())
  1850. {
  1851. llwarns << mID << ": Marking image as missing" << llendl;
  1852. }
  1853. else
  1854. {
  1855. llwarns << mUrl << ": Marking image as missing" << llendl;
  1856. }
  1857. if (mHasFetcher)
  1858. {
  1859. LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
  1860. mHasFetcher = FALSE;
  1861. mIsFetching = FALSE;
  1862. mLastPacketTimer.reset();
  1863. mFetchState = 0;
  1864. mFetchPriority = 0;
  1865. }
  1866. mIsMissingAsset = TRUE;
  1867. }
  1868. void LLViewerFetchedTexture::setLoadedCallback( loaded_callback_func loaded_callback,
  1869. S32 discard_level, BOOL keep_imageraw, BOOL needs_aux, void* userdata,
  1870. LLLoadedCallbackEntry::source_callback_list_t* src_callback_list, BOOL pause)
  1871. {
  1872. //
  1873. // Don't do ANYTHING here, just add it to the global callback list
  1874. //
  1875. if (mLoadedCallbackList.empty())
  1876. {
  1877. // Put in list to call this->doLoadedCallbacks() periodically
  1878. gTextureList.mCallbackList.insert(this);
  1879. mLoadedCallbackDesiredDiscardLevel = (S8)discard_level;
  1880. }
  1881. else
  1882. {
  1883. mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel, (S8)discard_level) ;
  1884. }
  1885. if(mPauseLoadedCallBacks && !pause)
  1886. {
  1887. unpauseLoadedCallbacks(src_callback_list) ;
  1888. }
  1889. LLLoadedCallbackEntry* entryp = new LLLoadedCallbackEntry(loaded_callback, discard_level, keep_imageraw, userdata, src_callback_list, this, pause);
  1890. mLoadedCallbackList.push_back(entryp);
  1891. mNeedsAux |= needs_aux;
  1892. if(keep_imageraw)
  1893. {
  1894. mSaveRawImage = TRUE ;
  1895. }
  1896. if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0)
  1897. {
  1898. // We need aux data, but we've already loaded the image, and it didn't have any
  1899. llwarns << "No aux data available for callback for image:" << getID() << llendl;
  1900. }
  1901. mLastCallBackActiveTime = sCurrentTime ;
  1902. }
  1903. void LLViewerFetchedTexture::clearCallbackEntryList()
  1904. {
  1905. if(mLoadedCallbackList.empty())
  1906. {
  1907. return ;
  1908. }
  1909. for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
  1910. iter != mLoadedCallbackList.end(); )
  1911. {
  1912. LLLoadedCallbackEntry *entryp = *iter;
  1913. // We never finished loading the image. Indicate failure.
  1914. // Note: this allows mLoadedCallbackUserData to be cleaned up.
  1915. entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
  1916. iter = mLoadedCallbackList.erase(iter) ;
  1917. delete entryp;
  1918. }
  1919. gTextureList.mCallbackList.erase(this);
  1920. mLoadedCallbackDesiredDiscardLevel = S8_MAX ;
  1921. if(needsToSaveRawImage())
  1922. {
  1923. destroySavedRawImage() ;
  1924. }
  1925. return ;
  1926. }
  1927. void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
  1928. {
  1929. if(mLoadedCallbackList.empty() || !callback_list)
  1930. {
  1931. return ;
  1932. }
  1933. S32 desired_discard = S8_MAX ;
  1934. S32 desired_raw_discard = INVALID_DISCARD_LEVEL ;
  1935. for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
  1936. iter != mLoadedCallbackList.end(); )
  1937. {
  1938. LLLoadedCallbackEntry *entryp = *iter;
  1939. if(entryp->mSourceCallbackList == callback_list)
  1940. {
  1941. // We never finished loading the image. Indicate failure.
  1942. // Note: this allows mLoadedCallbackUserData to be cleaned up.
  1943. entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
  1944. iter = mLoadedCallbackList.erase(iter) ;
  1945. delete entryp;
  1946. }
  1947. else
  1948. {
  1949. ++iter;
  1950. desired_discard = llmin(desired_discard, entryp->mDesiredDiscard) ;
  1951. if(entryp->mNeedsImageRaw)
  1952. {
  1953. desired_raw_discard = llmin(desired_raw_discard, entryp->mDesiredDiscard) ;
  1954. }
  1955. }
  1956. }
  1957. mLoadedCallbackDesiredDiscardLevel = desired_discard;
  1958. if (mLoadedCallbackList.empty())
  1959. {
  1960. // If we have no callbacks, take us off of the image callback list.
  1961. gTextureList.mCallbackList.erase(this);
  1962. if(needsToSaveRawImage())
  1963. {
  1964. destroySavedRawImage() ;
  1965. }
  1966. }
  1967. else if(needsToSaveRawImage() && mBoostLevel != LLViewerTexture::BOOST_PREVIEW)
  1968. {
  1969. if(desired_raw_discard != INVALID_DISCARD_LEVEL)
  1970. {
  1971. mDesiredSavedRawDiscardLevel = desired_raw_discard ;
  1972. }
  1973. else
  1974. {
  1975. destroySavedRawImage() ;
  1976. }
  1977. }
  1978. }
  1979. void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
  1980. {
  1981. if(!callback_list)
  1982. {
  1983. mPauseLoadedCallBacks = FALSE ;
  1984. return ;
  1985. }
  1986. BOOL need_raw = FALSE ;
  1987. for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
  1988. iter != mLoadedCallbackList.end(); )
  1989. {
  1990. LLLoadedCallbackEntry *entryp = *iter++;
  1991. if(entryp->mSourceCallbackList == callback_list)
  1992. {
  1993. entryp->mPaused = FALSE ;
  1994. if(entryp->mNeedsImageRaw)
  1995. {
  1996. need_raw = TRUE ;
  1997. }
  1998. }
  1999. }
  2000. mPauseLoadedCallBacks = FALSE ;
  2001. mLastCallBackActiveTime = sCurrentTime ;
  2002. if(need_raw)
  2003. {
  2004. mSaveRawImage = TRUE ;
  2005. }
  2006. }
  2007. void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
  2008. {
  2009. if(!callback_list)
  2010. {
  2011. return ;
  2012. }
  2013. bool paused = true ;
  2014. for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
  2015. iter != mLoadedCallbackList.end(); )
  2016. {
  2017. LLLoadedCallbackEntry *entryp = *iter++;
  2018. if(entryp->mSourceCallbackList == callback_list)
  2019. {
  2020. entryp->mPaused = TRUE ;
  2021. }
  2022. else if(!entryp->mPaused)
  2023. {
  2024. paused = false ;
  2025. }
  2026. }
  2027. if(paused)
  2028. {
  2029. mPauseLoadedCallBacks = TRUE ;//when set, loaded callback is paused.
  2030. resetTextureStats();
  2031. mSaveRawImage = FALSE ;
  2032. }
  2033. }
  2034. bool LLViewerFetchedTexture::doLoadedCallbacks()
  2035. {
  2036. static const F32 MAX_INACTIVE_TIME = 900.f ; //seconds
  2037. if (mNeedsCreateTexture)
  2038. {
  2039. return false;
  2040. }
  2041. if(mPauseLoadedCallBacks)
  2042. {
  2043. destroyRawImage();
  2044. return false; //paused
  2045. }
  2046. if(sCurrentTime - mLastCallBackActiveTime > MAX_INACTIVE_TIME && !mIsFetching)
  2047. {
  2048. clearCallbackEntryList() ; //remove all callbacks.
  2049. return false ;
  2050. }
  2051. bool res = false;
  2052. if (isMissingAsset())
  2053. {
  2054. for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
  2055. iter != mLoadedCallbackList.end(); )
  2056. {
  2057. LLLoadedCallbackEntry *entryp = *iter++;
  2058. // We never finished loading the image. Indicate failure.
  2059. // Note: this allows mLoadedCallbackUserData to be cleaned up.
  2060. entryp->mCallback(FALSE, this, NULL, NULL, 0, TRUE, entryp->mUserData);
  2061. delete entryp;
  2062. }
  2063. mLoadedCallbackList.clear();
  2064. // Remove ourself from the global list of textures with callbacks
  2065. gTextureList.mCallbackList.erase(this);
  2066. return false ;
  2067. }
  2068. S32 gl_discard = getDiscardLevel();
  2069. // If we don't have a legit GL image, set it to be lower than the worst discard level
  2070. if (gl_discard == -1)
  2071. {
  2072. gl_discard = MAX_DISCARD_LEVEL + 1;
  2073. }
  2074. //
  2075. // Determine the quality levels of textures that we can provide to callbacks
  2076. // and whether we need to do decompression/readback to get it
  2077. //
  2078. S32 current_raw_discard = MAX_DISCARD_LEVEL + 1; // We can always do a readback to get a raw discard
  2079. S32 best_raw_discard = gl_discard; // Current GL quality level
  2080. S32 current_aux_discard = MAX_DISCARD_LEVEL + 1;
  2081. S32 best_aux_discard = MAX_DISCARD_LEVEL + 1;
  2082. if (mIsRawImageValid)
  2083. {
  2084. // If we have an existing raw image, we have a baseline for the raw and auxiliary quality levels.
  2085. best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel);
  2086. best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel); // We always decode the aux when we decode the base raw
  2087. current_aux_discard = llmin(current_aux_discard, best_aux_discard);
  2088. }
  2089. else
  2090. {
  2091. // We have no data at all, we need to get it
  2092. // Do this by forcing the best aux discard to be 0.
  2093. best_aux_discard = 0;
  2094. }
  2095. //
  2096. // See if any of the callbacks would actually run using the data that we can provide,
  2097. // and also determine if we need to perform any readbacks or decodes.
  2098. //
  2099. bool run_gl_callbacks = false;
  2100. bool run_raw_callbacks = false;
  2101. bool need_readback = false;
  2102. for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
  2103. iter != mLoadedCallbackList.end(); )
  2104. {
  2105. LLLoadedCallbackEntry *entryp = *iter++;
  2106. if (entryp->mNeedsImageRaw)
  2107. {
  2108. if (mNeedsAux)
  2109. {
  2110. //
  2111. // Need raw and auxiliary channels
  2112. //
  2113. if (entryp->mLastUsedDiscard > current_aux_discard)
  2114. {
  2115. // We have useful data, run the callbacks
  2116. run_raw_callbacks = true;
  2117. }
  2118. }
  2119. else
  2120. {
  2121. if (entryp->mLastUsedDiscard > current_raw_dis