llviewertexture.cpp 104 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060
  1. /**
  2. * @file llviewertexture.cpp
  3. * @brief Object which handles a received image (and associated texture(s))
  4. *
  5. * $LicenseInfo:firstyear=2000&license=viewergpl$
  6. *
  7. * Copyright (c) 2000-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include <utility>
  34. #include "llviewertexture.h"
  35. #include "imageids.h"
  36. #include "llgl.h"
  37. #include "llfasttimer.h"
  38. #include "llhost.h"
  39. #include "llimage.h"
  40. #include "llimagegl.h"
  41. #include "llimagebmp.h"
  42. #include "llimagej2c.h"
  43. #include "llimagetga.h"
  44. #include "llmediaentry.h"
  45. #include "llnotifications.h"
  46. #include "llsys.h"
  47. #include "lltextureentry.h"
  48. #include "lltexturemanagerbridge.h"
  49. #include "llmessage.h"
  50. #include "llagent.h"
  51. #include "llappviewer.h"
  52. #include "lldrawpool.h"
  53. #include "llpipeline.h"
  54. #include "lltexturecache.h"
  55. #include "lltexturefetch.h"
  56. #include "llviewercamera.h"
  57. #include "llviewercontrol.h"
  58. #include "llviewermedia.h"
  59. #include "llviewertexturelist.h"
  60. #include "llvlcomposition.h" // For LLTerrain::isAsset()
  61. #include "llvovolume.h"
  62. // Static members
  63. LLPointer<LLViewerTexture> LLViewerTexture::sNullImagep = NULL;
  64. LLPointer<LLViewerTexture> LLViewerTexture::sCloudImagep = NULL;
  65. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
  66. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
  67. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
  68. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;
  69. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultIrradiancePBRp = NULL;
  70. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultSunImagep = NULL;
  71. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultMoonImagep = NULL;
  72. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultCloudsImagep = NULL;
  73. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultCloudNoiseImagep = NULL;
  74. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sBloomImagep = NULL;
  75. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sOpaqueWaterImagep = NULL;
  76. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWaterImagep = NULL;
  77. LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWaterNormapMapImagep = NULL;
  78. LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap;
  79. U32 LLViewerFetchedTexture::sMainThreadCreations = 0;
  80. U32 LLViewerFetchedTexture::sImageThreadCreations = 0;
  81. U32 LLViewerFetchedTexture::sImageThreadQueueSize = 0;
  82. bool LLViewerFetchedTexture::sImageThreadCreationsCapped = false;
  83. S32 LLViewerTexture::sImageCount = 0;
  84. S32 LLViewerTexture::sRawCount = 0;
  85. S32 LLViewerTexture::sAuxCount = 0;
  86. F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
  87. S32 LLViewerTexture::sBoundTexMemoryMB = 0;
  88. S32 LLViewerTexture::sLastBoundTexMemoryMB = 0;
  89. S32 LLViewerTexture::sTotalTexMemoryMB = 0;
  90. S32 LLViewerTexture::sLastTotalTexMemoryMB = 0;
  91. S32 LLViewerTexture::sMaxBoundTexMemMB = 0;
  92. S32 LLViewerTexture::sMaxTotalTexMemMB = 0;
  93. S32 LLViewerTexture::sLastFreeVRAMMB = -1;
  94. constexpr S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64;
  95. constexpr S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = MAX_SCULPT_REZ *
  96. MAX_SCULPT_REZ;
  97. constexpr S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128;
  98. S32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.
  99. S32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;
  100. F32 LLViewerTexture::sCurrentTime = 0.f;
  101. F32 LLViewerTexture::sNextDiscardBiasUpdateTime = 0.f;
  102. F32 LLViewerTexture::sLastDiscardDecreaseTime = 0.f;
  103. F32 LLViewerTexture::sLastLowMemCondTime = 0.f;
  104. bool LLViewerTexture::sALMTexPenalty = false;
  105. bool LLViewerTexture::sDontLoadVolumeTextures = false;
  106. // Max number of levels to reduce image quality by:
  107. constexpr F32 DESIRED_DISCARD_BIAS_MAX = (F32)MAX_DISCARD_LEVEL;
  108. //-----------------------------------------------------------------------------
  109. //namespace: LLViewerTextureAccess
  110. //-----------------------------------------------------------------------------
  111. LLLoadedCallbackEntry::LLLoadedCallbackEntry(loaded_callback_func cb,
  112. S32 discard_level,
  113. bool need_imageraw,
  114. void* userdata,
  115. uuid_list_t* cb_list,
  116. LLViewerFetchedTexture* target,
  117. bool pause)
  118. : mCallback(cb),
  119. mLastUsedDiscard(MAX_DISCARD_LEVEL + 1),
  120. mDesiredDiscard(discard_level),
  121. mNeedsImageRaw(need_imageraw),
  122. mUserData(userdata),
  123. mSourceCallbackList(cb_list),
  124. mPaused(pause)
  125. {
  126. if (mSourceCallbackList)
  127. {
  128. mSourceCallbackList->emplace(target->getID());
  129. }
  130. }
  131. void LLLoadedCallbackEntry::removeTexture(LLViewerFetchedTexture* texp)
  132. {
  133. if (mSourceCallbackList)
  134. {
  135. mSourceCallbackList->erase(texp->getID());
  136. }
  137. }
  138. //static
  139. void LLLoadedCallbackEntry::cleanUpCallbackList(uuid_list_t* cb_list)
  140. {
  141. // Clear texture callbacks.
  142. if (cb_list && !cb_list->empty())
  143. {
  144. for (uuid_list_t::iterator it = cb_list->begin(), end = cb_list->end();
  145. it != end; ++it)
  146. {
  147. LLViewerFetchedTexture* tex = gTextureList.findImage(*it);
  148. if (tex)
  149. {
  150. tex->deleteCallbackEntry(cb_list);
  151. }
  152. }
  153. cb_list->clear();
  154. }
  155. }
  156. LLViewerMediaTexture* LLViewerTextureManager::createMediaTexture(const LLUUID& media_id,
  157. bool usemipmaps,
  158. LLImageGL* gl_image)
  159. {
  160. return new LLViewerMediaTexture(media_id, usemipmaps, gl_image);
  161. }
  162. LLViewerTexture* LLViewerTextureManager::findTexture(const LLUUID& id)
  163. {
  164. LLViewerTexture* tex;
  165. //search fetched texture list
  166. tex = gTextureList.findImage(id);
  167. // search media texture list
  168. if (!tex)
  169. {
  170. tex = LLViewerTextureManager::findMediaTexture(id);
  171. }
  172. return tex;
  173. }
  174. LLViewerMediaTexture* LLViewerTextureManager::findMediaTexture(const LLUUID& media_id)
  175. {
  176. return LLViewerMediaTexture::findMediaTexture(media_id);
  177. }
  178. LLViewerMediaTexture* LLViewerTextureManager::getMediaTexture(const LLUUID& id,
  179. LLImageGL* gl_image)
  180. {
  181. LLViewerMediaTexture* texp = LLViewerMediaTexture::findMediaTexture(id);
  182. if (!texp)
  183. {
  184. texp = LLViewerTextureManager::createMediaTexture(id, false, gl_image);
  185. }
  186. texp->initVirtualSize();
  187. return texp;
  188. }
  189. LLViewerFetchedTexture* LLViewerTextureManager::staticCast(LLGLTexture* tex,
  190. bool report_error)
  191. {
  192. if (!tex)
  193. {
  194. return NULL;
  195. }
  196. S8 type = tex->getType();
  197. if (type == LLViewerTexture::FETCHED_TEXTURE ||
  198. type == LLViewerTexture::LOD_TEXTURE)
  199. {
  200. return (LLViewerFetchedTexture*)tex;
  201. }
  202. if (report_error)
  203. {
  204. llerrs << "Not a fetched texture type: " << type << llendl;
  205. }
  206. return NULL;
  207. }
  208. LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(bool usemipmaps,
  209. bool generate_gl_tex)
  210. {
  211. LLPointer<LLViewerTexture> tex = new LLViewerTexture(usemipmaps);
  212. if (generate_gl_tex)
  213. {
  214. tex->generateGLTexture();
  215. }
  216. return tex;
  217. }
  218. LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID& id,
  219. bool usemipmaps,
  220. bool generate_gl_tex)
  221. {
  222. LLPointer<LLViewerTexture> tex = new LLViewerTexture(id, usemipmaps);
  223. if (generate_gl_tex)
  224. {
  225. tex->generateGLTexture();
  226. }
  227. return tex;
  228. }
  229. LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* rawp,
  230. bool usemipmaps)
  231. {
  232. LLPointer<LLViewerTexture> tex = new LLViewerTexture(rawp, usemipmaps);
  233. return tex;
  234. }
  235. LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(U32 width,
  236. U32 height,
  237. U8 components,
  238. bool usemipmaps,
  239. bool generate_gl_tex)
  240. {
  241. LLPointer<LLViewerTexture> tex = new LLViewerTexture(width, height,
  242. components,
  243. usemipmaps);
  244. if (generate_gl_tex)
  245. {
  246. tex->generateGLTexture();
  247. }
  248. return tex;
  249. }
  250. LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageRaw* rawp,
  251. FTType type,
  252. bool usemipmaps)
  253. {
  254. LLViewerFetchedTexture* texp = new LLViewerFetchedTexture(rawp, type,
  255. usemipmaps);
  256. gTextureList.addImage(texp);
  257. return texp;
  258. }
  259. LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID& image_id,
  260. FTType f_type,
  261. bool usemipmaps,
  262. LLGLTexture::EBoostLevel boost_priority,
  263. S8 texture_type,
  264. S32 internal_format,
  265. U32 primary_format,
  266. LLHost request_from_host)
  267. {
  268. return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority,
  269. texture_type, internal_format, primary_format,
  270. request_from_host);
  271. }
  272. LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(const std::string& filename,
  273. bool usemipmaps,
  274. LLGLTexture::EBoostLevel boost_priority,
  275. S8 texture_type,
  276. S32 internal_format,
  277. U32 primary_format,
  278. const LLUUID& force_id)
  279. {
  280. return gTextureList.getImageFromFile(filename, usemipmaps,
  281. boost_priority, texture_type,
  282. internal_format, primary_format,
  283. force_id);
  284. }
  285. //static
  286. LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
  287. FTType f_type,
  288. bool usemipmaps,
  289. LLGLTexture::EBoostLevel boost_priority,
  290. S8 texture_type,
  291. S32 internal_format,
  292. U32 primary_format,
  293. const LLUUID& force_id)
  294. {
  295. return gTextureList.getImageFromUrl(url, f_type, usemipmaps,
  296. boost_priority, texture_type,
  297. internal_format, primary_format,
  298. force_id);
  299. }
  300. LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id,
  301. FTType f_type,
  302. LLHost host)
  303. {
  304. return gTextureList.getImageFromHost(image_id, f_type, host);
  305. }
  306. // Create a bridge to the viewer texture manager.
  307. class LLViewerTextureManagerBridge : public LLTextureManagerBridge
  308. {
  309. LLPointer<LLGLTexture> getLocalTexture(bool usemipmaps = true,
  310. bool generate = true) override
  311. {
  312. return LLViewerTextureManager::getLocalTexture(usemipmaps, generate);
  313. }
  314. LLPointer<LLGLTexture> getLocalTexture(U32 width, U32 height,
  315. U8 components, bool usemipmaps,
  316. bool generate = true) override
  317. {
  318. return LLViewerTextureManager::getLocalTexture(width, height,
  319. components, usemipmaps,
  320. generate);
  321. }
  322. LLGLTexture* getFetchedTexture(const LLUUID& image_id) override
  323. {
  324. return LLViewerTextureManager::getFetchedTexture(image_id);
  325. }
  326. };
  327. void LLViewerTextureManager::init()
  328. {
  329. LLPointer<LLImageRaw> nullp = new LLImageRaw(1, 1, 3);
  330. nullp->clear(0x77, 0x77, 0x77, 0xFF);
  331. LLViewerTexture::sNullImagep = getLocalTexture(nullp.get(), true);
  332. LLViewerTexture::sCloudImagep =
  333. getFetchedTextureFromFile("cloud-particle.j2c");
  334. #if 1
  335. LLViewerFetchedTexture::sDefaultImagep = getFetchedTexture(IMG_DEFAULT);
  336. LLViewerFetchedTexture::sDefaultImagep->setBoostLevel(LLGLTexture::BOOST_UI);
  337. constexpr S32 dim = 128;
  338. LLPointer<LLImageRaw> rawp = new LLImageRaw(dim, dim, 3);
  339. U8* datap = rawp->getData();
  340. if (!datap)
  341. {
  342. return;
  343. }
  344. memset(datap, 0x7f, dim * dim * 3);
  345. LLViewerFetchedTexture::sDefaultImagep->createGLTexture(0, rawp);
  346. // Cache the raw image
  347. LLViewerFetchedTexture::sDefaultImagep->setCachedRawImage(0, rawp);
  348. rawp = NULL;
  349. #else
  350. LLViewerFetchedTexture::sDefaultImagep =
  351. getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, true,
  352. LLGLTexture::BOOST_UI);
  353. #endif
  354. LLViewerFetchedTexture::sSmokeImagep =
  355. getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, true,
  356. LLGLTexture::BOOST_UI);
  357. LLViewerTexture::initClass();
  358. // Create a texture manager bridge.
  359. gTextureManagerBridgep = new LLViewerTextureManagerBridge;
  360. }
  361. void LLViewerTextureManager::cleanup()
  362. {
  363. delete gTextureManagerBridgep;
  364. LLImageGL::sDefaultGLImagep = NULL;
  365. LLViewerTexture::sNullImagep = NULL;
  366. LLViewerTexture::sCloudImagep = NULL;
  367. LLViewerFetchedTexture::sDefaultImagep = NULL;
  368. LLViewerFetchedTexture::sSmokeImagep = NULL;
  369. LLViewerFetchedTexture::sWhiteImagep = NULL;
  370. LLViewerFetchedTexture::sFlatNormalImagep = NULL;
  371. LLViewerFetchedTexture::sDefaultIrradiancePBRp = NULL;
  372. LLViewerFetchedTexture::sDefaultSunImagep = NULL;
  373. LLViewerFetchedTexture::sDefaultMoonImagep = NULL;
  374. LLViewerFetchedTexture::sDefaultCloudsImagep = NULL;
  375. LLViewerFetchedTexture::sDefaultCloudNoiseImagep = NULL;
  376. LLViewerFetchedTexture::sBloomImagep = NULL;
  377. LLViewerFetchedTexture::sOpaqueWaterImagep = NULL;
  378. LLViewerFetchedTexture::sWaterImagep = NULL;
  379. LLViewerFetchedTexture::sWaterNormapMapImagep = NULL;
  380. LLViewerMediaTexture::cleanUpClass();
  381. }
  382. //-----------------------------------------------------------------------------
  383. // LLViewerTexture
  384. //-----------------------------------------------------------------------------
  385. // static
  386. void LLViewerTexture::initClass()
  387. {
  388. LLImageGL::sDefaultGLImagep =
  389. LLViewerFetchedTexture::sDefaultImagep->getGLImage();
  390. }
  391. // Tuning params
  392. constexpr F32 DISCARD_BIAS_DELTA = 0.25f; // Was .05f in v1
  393. constexpr F32 DISCARD_DELTA_TIME = 0.5f;
  394. // I rewrote and thoroughly tuned this method to try and cope with most
  395. // situations. It also uses an algorithm to anticipate the next memory check
  396. // so to prevent the VRAM from getting full. Of course, it only properly works
  397. // when GL calls for VRAM usage are properly supported, which sadly only covers
  398. // NVIDIA cards and, under Linux/Mesa only, AMD cards... HB
  399. //static
  400. bool LLViewerTexture::isMemoryForTextureLow(F32& discard,
  401. bool& can_decrease_discard)
  402. {
  403. // No need to bother at all when we cannot read the VRAM via GL !
  404. static bool can_do = gGLManager.mHasATIMemInfo ||
  405. gGLManager.mHasNVXMemInfo;
  406. if (!can_do)
  407. {
  408. return false;
  409. }
  410. // Keep an option to disable this check entirely, in case the reports by
  411. // the driver would be wrong/broken (could be the case with some APUs).
  412. static LLCachedControl<bool> disabled(gSavedSettings, "DisableVRAMCheck");
  413. if (disabled)
  414. {
  415. return false;
  416. }
  417. // When GL threading is disabled, LLImageGLThread::updateFreeVRAM() is
  418. // synchronous and immediately updates the value returned by
  419. // LLImageGLThread::getFreeVRAMMegabytes(), which is *NOT* the case when
  420. // threading is enabled (we then get the value requested at the moment
  421. // last check was done). HB
  422. bool asynchronous = LLImageGLThread::sEnabled;
  423. if (!asynchronous)
  424. {
  425. // Update now, synchronously.
  426. LLImageGLThread::updateFreeVRAM();
  427. }
  428. S32 free_vram = LLImageGLThread::getFreeVRAMMegabytes();
  429. if (asynchronous)
  430. {
  431. // Update for next check, asynchronously.
  432. LLImageGLThread::updateFreeVRAM();
  433. }
  434. if (free_vram < 0) // Negative denotes a failure to get any info
  435. {
  436. return false;
  437. }
  438. // Compute how much more or less we are using VRAM since last check.
  439. S32 delta = 0;
  440. if (sLastFreeVRAMMB >= 0)
  441. {
  442. delta = free_vram - sLastFreeVRAMMB;
  443. }
  444. sLastFreeVRAMMB = free_vram;
  445. // Set the low limit for the VRAM free for textures to below 10% of its
  446. // initial size (at viewer startup, as reported by GL), a minimum further
  447. // clamped between 10 and 1000 MB.
  448. static S32 min_free_texture_memory =
  449. llclamp(10 * gGLManager.mTexVRAM / 100, 10, 1000);
  450. if (free_vram < min_free_texture_memory &&
  451. free_vram + delta < min_free_texture_memory)
  452. {
  453. // EEEK ! Emergency action is required !
  454. discard = DESIRED_DISCARD_BIAS_MAX;
  455. can_decrease_discard = false;
  456. return true;
  457. }
  458. // Let's see if we will have still enough memory at next check. We use 1.5
  459. // times the min memory for comparison, so that we can start increasing the
  460. // bias a little already when getting close to the limit.
  461. if (free_vram + delta > 3 * min_free_texture_memory / 2)
  462. {
  463. return false; // Yes, should be fine...
  464. }
  465. // Do not let the discard bias decrease in these tight memory conditions.
  466. can_decrease_discard = false;
  467. // If we predict that more than 1.25 times the min memory will be available
  468. // at next check, then we still leave the discard bias unchanged for now.
  469. if (free_vram + delta >= 4 * min_free_texture_memory / 3)
  470. {
  471. return false; // Then, we should be fine...
  472. }
  473. F32 bias_delta;
  474. // How large is the delta, compared with the minimum ?
  475. F32 factor = (F32)delta / (F32)min_free_texture_memory;
  476. if (factor >= 1.5f)
  477. {
  478. // React strongly to try and avoid freezes due to texture memory
  479. // spilling into the RAM by lack of VRAM...
  480. bias_delta = DISCARD_BIAS_DELTA * 2.f;
  481. }
  482. else if (factor >= 1.f)
  483. {
  484. bias_delta = DISCARD_BIAS_DELTA * 1.5f;
  485. }
  486. else if (factor >= 0.5f)
  487. {
  488. bias_delta = DISCARD_BIAS_DELTA;
  489. }
  490. else
  491. {
  492. bias_delta = DISCARD_BIAS_DELTA * 0.5f;
  493. }
  494. LL_DEBUGS("TextureMemory") << "Increasing discard bias: low free VRAM."
  495. << LL_ENDL;
  496. discard = llclamp(discard + bias_delta, 0.f, DESIRED_DISCARD_BIAS_MAX);
  497. return true;
  498. }
  499. //static
  500. void LLViewerTexture::updateClass()
  501. {
  502. sCurrentTime = gFrameTimeSeconds;
  503. LLViewerMediaTexture::updateClass();
  504. // Everything in MB
  505. sBoundTexMemoryMB = BYTES2MEGABYTES(LLImageGL::sBoundTexMemBytes);
  506. sTotalTexMemoryMB = BYTES2MEGABYTES(LLImageGL::sGlobalTexMemBytes);
  507. sMaxBoundTexMemMB = gTextureList.getMaxResidentTexMem();
  508. sMaxTotalTexMemMB = gTextureList.getMaxTotalTextureMem();
  509. if (gUseWireframe)
  510. {
  511. // Max out the discard level, because the wireframe mode kills object
  512. // culling and causes all objects and textures in FOV to load at once.
  513. sDesiredDiscardBias = DESIRED_DISCARD_BIAS_MAX;
  514. return;
  515. }
  516. S32 bound_delta = 0;
  517. S32 total_delta = 0;
  518. bool is_check_time = sCurrentTime >= sNextDiscardBiasUpdateTime;
  519. if (is_check_time)
  520. {
  521. sNextDiscardBiasUpdateTime = sCurrentTime + DISCARD_DELTA_TIME;
  522. if (sLastBoundTexMemoryMB > 0)
  523. {
  524. bound_delta = sBoundTexMemoryMB - sLastBoundTexMemoryMB;
  525. }
  526. sLastBoundTexMemoryMB = sBoundTexMemoryMB;
  527. if (sLastTotalTexMemoryMB > 0)
  528. {
  529. total_delta = sTotalTexMemoryMB - sLastTotalTexMemoryMB;
  530. }
  531. sLastTotalTexMemoryMB = sTotalTexMemoryMB;
  532. }
  533. const F32 initial_discard = sDesiredDiscardBias;
  534. bool can_decrease_discard = true;
  535. bool increased_discard = false;
  536. // First check wether the system memory is low or not and adjust discard
  537. if (LLMemory::hasFailedAllocation())
  538. {
  539. // There has been a failure to allocate memory: the latter is either
  540. // too low or too fragmented ! Let's take radical measures... HB
  541. sDesiredDiscardBias = 5.f;
  542. increased_discard = true;
  543. can_decrease_discard = false;
  544. static LLCachedControl<F32> draw_dist(gSavedSettings, "RenderFarClip");
  545. if (draw_dist > 64.f)
  546. {
  547. gSavedSettings.setF32("RenderFarClip", 64.f);
  548. }
  549. static S32 last_failure = 0;
  550. if ((S32)sCurrentTime - last_failure > 3)
  551. {
  552. gAgent.resetView();
  553. }
  554. // Clear the error condition.
  555. LLMemory::resetFailedAllocation();
  556. // Warn the user, but do not spam them either...
  557. if ((S32)sCurrentTime - last_failure > 20)
  558. {
  559. gNotifications.add("GotAllocationFailure");
  560. }
  561. last_failure = (S32)sCurrentTime;
  562. LL_DEBUGS("TextureMemory") << "Maxing discard bias due to memory allocation failure."
  563. << LL_ENDL;
  564. }
  565. // Check VRAM usage: this is also a hard limit...
  566. else if (is_check_time &&
  567. isMemoryForTextureLow(sDesiredDiscardBias, can_decrease_discard))
  568. {
  569. increased_discard = true;
  570. // Make the next check sooner, to get better chances to catch high
  571. // VRAM usage increase rates and avoid filling up the VRAM. HB
  572. sNextDiscardBiasUpdateTime -= DISCARD_DELTA_TIME * 0.5f;
  573. }
  574. // If we are using (or soon going to use) more texture memory than we
  575. // should, scale up the desired discard level, but do not when the last
  576. // memory usage was larger than the current one (meaning we are in the
  577. // process of returning to the limit already). HB
  578. if ((is_check_time && !increased_discard) &&
  579. ((bound_delta >= 0 &&
  580. sBoundTexMemoryMB + bound_delta >= sMaxBoundTexMemMB) ||
  581. (total_delta >= 0 &&
  582. sTotalTexMemoryMB + total_delta >= sMaxTotalTexMemMB)))
  583. {
  584. LL_DEBUGS("TextureMemory") << "Increasing discard bias: too much texture memory used."
  585. << LL_ENDL;
  586. can_decrease_discard = false;
  587. increased_discard = true;
  588. sDesiredDiscardBias += DISCARD_BIAS_DELTA;
  589. }
  590. // If we are using less texture memory than what we could *and* the memory
  591. // usage is not larger than at last check time, scale down the desired
  592. // discard level. HB
  593. if (is_check_time && can_decrease_discard && sDesiredDiscardBias > 0.f &&
  594. bound_delta <= 0 && total_delta <= 0)
  595. {
  596. static LLCachedControl<F32> bias_mult(gSavedSettings,
  597. "TexBiasDecreaseDelayFactor");
  598. static LLCachedControl<F32> lower_bound(gSavedSettings,
  599. "TexMemLowerBoundScale");
  600. F32 texmem_lower_bound_scale = llclamp((F32)lower_bound, 0.75f, 0.9f);
  601. if (sBoundTexMemoryMB < sMaxBoundTexMemMB * texmem_lower_bound_scale &&
  602. sTotalTexMemoryMB < sMaxTotalTexMemMB * texmem_lower_bound_scale)
  603. {
  604. F32 factor = llmin((F32)bias_mult, 2.f);
  605. // Do not decrease the discard too fast: when, for example, the
  606. // agent avatar turns around, the texture memory usage can drop
  607. // dramatically fast, just to increase brutally again a couple
  608. // seconds later... HB
  609. if (sCurrentTime - sLastDiscardDecreaseTime >=
  610. sDesiredDiscardBias * factor)
  611. {
  612. // When using lower discard biases, decrease them slower, to
  613. // obtain finer memory usage adjustements and avoid entering
  614. // a decrease-increase yo-yo due to an overshoot. HB
  615. if (sDesiredDiscardBias <= 2.5f)
  616. {
  617. sDesiredDiscardBias -= DISCARD_BIAS_DELTA * 0.5f;
  618. }
  619. else
  620. {
  621. sDesiredDiscardBias -= DISCARD_BIAS_DELTA;
  622. }
  623. sLastDiscardDecreaseTime = sCurrentTime;
  624. }
  625. }
  626. }
  627. sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 0.f,
  628. DESIRED_DISCARD_BIAS_MAX);
  629. if (sDesiredDiscardBias >= 3.f && sLastDiscardDecreaseTime > 0.f)
  630. {
  631. sLastLowMemCondTime = sCurrentTime;
  632. }
  633. // Decide whether or not we should increase the discard bias for ALM
  634. // textures based on the ratio of used bound texture memory (for toggling
  635. // it on) and on the desired discard bias (for toggling it off, providing
  636. // an adequate hysteresis). HB
  637. static LLCachedControl<F32> bratio(gSavedSettings,
  638. "BoundTexRatioToBiasALM");
  639. static LLCachedControl<F32> mdiscard(gSavedSettings,
  640. "MaxDiscardToUnbiasALM");
  641. if (F32(sBoundTexMemoryMB) >
  642. F32(sMaxBoundTexMemMB) * llmax(0.25f, bratio))
  643. {
  644. sALMTexPenalty = true;
  645. }
  646. else if (sALMTexPenalty &&
  647. sDesiredDiscardBias < llclamp((F32)mdiscard, 1.f, 4.f))
  648. {
  649. sALMTexPenalty = false;
  650. }
  651. // If we just changed the discard level, or it is already at the max, we
  652. // can also try and make room for textures by removing from memory the
  653. // ones not seen/used in a while. Note that freeing memory also when the
  654. // discard decreases helps avoiding a yo-yo effect, by making room for
  655. // the higher texture LODs that are going to be decoded. HB
  656. if (is_check_time &&
  657. (sDesiredDiscardBias == DESIRED_DISCARD_BIAS_MAX ||
  658. sDesiredDiscardBias != initial_discard))
  659. {
  660. gTextureList.flushOldImages();
  661. }
  662. }
  663. //static
  664. void LLViewerTexture::resetLowMemCondition(bool reset_bias)
  665. {
  666. // Reset with -LOW_MEM_COND_DURATION delta to avoid false positive on
  667. // login, i.e. when sCurrentTime < LOW_MEM_COND_DURATION. HB
  668. constexpr F32 LOW_MEM_COND_DURATION = 30.f;
  669. sLastLowMemCondTime = -LOW_MEM_COND_DURATION;
  670. sLastDiscardDecreaseTime = 0.f;
  671. if (reset_bias && sDesiredDiscardBias >= 3.f)
  672. {
  673. sDesiredDiscardBias = 2.5f;
  674. }
  675. }
  676. LLViewerTexture::LLViewerTexture(bool usemipmaps)
  677. : LLGLTexture(usemipmaps)
  678. {
  679. init(true);
  680. mID.generate();
  681. ++sImageCount;
  682. }
  683. LLViewerTexture::LLViewerTexture(const LLUUID& id, bool usemipmaps)
  684. : LLGLTexture(usemipmaps),
  685. mID(id)
  686. {
  687. init(true);
  688. ++sImageCount;
  689. }
  690. LLViewerTexture::LLViewerTexture(U32 width, U32 height, U8 comp, bool mipmaps)
  691. : LLGLTexture(width, height, comp, mipmaps)
  692. {
  693. init(true);
  694. mID.generate();
  695. ++sImageCount;
  696. }
  697. LLViewerTexture::LLViewerTexture(const LLImageRaw* rawp, bool usemipmaps)
  698. : LLGLTexture(rawp, usemipmaps)
  699. {
  700. init(true);
  701. mID.generate();
  702. ++sImageCount;
  703. }
  704. LLViewerTexture::~LLViewerTexture()
  705. {
  706. cleanup();
  707. --sImageCount;
  708. }
  709. //virtual
  710. void LLViewerTexture::init(bool firstinit)
  711. {
  712. mMaxVirtualSize = 0.f;
  713. mMaxVirtualSizeResetInterval = 1;
  714. mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;
  715. mAdditionalDecodePriority = 0.f;
  716. mParcelMedia = NULL;
  717. for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
  718. {
  719. mNumFaces[i] = 0;
  720. mFaceList[i].clear();
  721. }
  722. memset(&mNumVolumes, 0,
  723. sizeof(U32) * LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
  724. mVolumeList[LLRender::LIGHT_TEX].clear();
  725. mVolumeList[LLRender::SCULPT_TEX].clear();
  726. mLastReferencedTime = mLastFaceListUpdate = mLastVolumeListUpdate =
  727. gFrameTimeSeconds;
  728. }
  729. void LLViewerTexture::setNeedsAlphaAndPickMask(bool b)
  730. {
  731. if (mImageGLp)
  732. {
  733. mImageGLp->setNeedsAlphaAndPickMask(b);
  734. }
  735. }
  736. //virtual
  737. S8 LLViewerTexture::getType() const
  738. {
  739. return LLViewerTexture::LOCAL_TEXTURE;
  740. }
  741. void LLViewerTexture::cleanup()
  742. {
  743. #if LL_FIX_MAT_TRANSPARENCY
  744. notifyAboutMissingAsset();
  745. #endif
  746. mFaceList[LLRender::DIFFUSE_MAP].clear();
  747. mFaceList[LLRender::NORMAL_MAP].clear();
  748. mFaceList[LLRender::SPECULAR_MAP].clear();
  749. mVolumeList[LLRender::LIGHT_TEX].clear();
  750. mVolumeList[LLRender::SCULPT_TEX].clear();
  751. }
  752. #if LL_FIX_MAT_TRANSPARENCY
  753. void LLViewerTexture::notifyAboutCreatingTexture()
  754. {
  755. for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
  756. {
  757. for (U32 f = 0, count = mNumFaces[ch]; f < count; ++f)
  758. {
  759. mFaceList[ch][f]->notifyAboutCreatingTexture(this);
  760. }
  761. }
  762. }
  763. void LLViewerTexture::notifyAboutMissingAsset()
  764. {
  765. for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
  766. {
  767. for (U32 f = 0, count = mNumFaces[ch]; f < count; ++f)
  768. {
  769. mFaceList[ch][f]->notifyAboutMissingAsset(this);
  770. }
  771. }
  772. }
  773. #endif
  774. // virtual
  775. void LLViewerTexture::dump()
  776. {
  777. LLGLTexture::dump();
  778. llinfos << "LLViewerTexture mID: " << mID << llendl;
  779. }
  780. void LLViewerTexture::resetLastReferencedTime()
  781. {
  782. mLastReferencedTime = gFrameTimeSeconds;
  783. }
  784. F32 LLViewerTexture::getElapsedLastReferenceTime()
  785. {
  786. return gFrameTimeSeconds - mLastReferencedTime;
  787. }
  788. //virtual
  789. void LLViewerTexture::setBoostLevel(U32 level)
  790. {
  791. LLGLTexture::setBoostLevel(level);
  792. // Strongly encourage anything boosted to load at full res
  793. static LLCachedControl<bool> boost_full_res(gSavedSettings,
  794. "FullResBoostedTextures");
  795. if (mBoostLevel >= BOOST_HIGH && boost_full_res &&
  796. sDesiredDiscardBias < 3.f)
  797. {
  798. constexpr F32 max_size = 2048.f * 2048.f;
  799. mMaxVirtualSize = max_size;
  800. }
  801. }
  802. bool LLViewerTexture::bindDefaultImage(S32 stage)
  803. {
  804. if (stage < 0) return false;
  805. bool res = true;
  806. if (LLViewerFetchedTexture::sDefaultImagep.notNull() &&
  807. LLViewerFetchedTexture::sDefaultImagep.get() != this)
  808. {
  809. // Use default if we got it
  810. res = gGL.getTexUnit(stage)->bind(LLViewerFetchedTexture::sDefaultImagep);
  811. }
  812. if (!res && LLViewerTexture::sNullImagep.notNull() &&
  813. LLViewerTexture::sNullImagep != this)
  814. {
  815. res = gGL.getTexUnit(stage)->bind(LLViewerTexture::sNullImagep);
  816. }
  817. if (!res)
  818. {
  819. llwarns << "Failed at stage: " << stage << llendl;
  820. }
  821. // Check if there is cached raw image and switch to it if possible
  822. switchToCachedImage();
  823. return res;
  824. }
  825. void LLViewerTexture::addTextureStats(F32 virtual_size,
  826. bool needs_gltexture) const
  827. {
  828. if (needs_gltexture)
  829. {
  830. mNeedsGLTexture = true;
  831. }
  832. // Do not allow the scaling down of do-not-discard textures ! HB
  833. if (mDontDiscard)
  834. {
  835. constexpr F32 MAX_AREA = 1024.f * 1024.f;
  836. virtual_size = MAX_AREA;
  837. }
  838. if (!mMaxVirtualSizeResetCounter)
  839. {
  840. // Flag to reset the values because the old values are used.
  841. resetMaxVirtualSizeResetCounter();
  842. mAdditionalDecodePriority = 0.f;
  843. }
  844. if (mMaxVirtualSize < virtual_size)
  845. {
  846. mMaxVirtualSize = virtual_size;
  847. }
  848. }
  849. void LLViewerTexture::resetTextureStats()
  850. {
  851. mMaxVirtualSizeResetCounter = 0;
  852. // Do not allow the scaling down of do-not-discard textures ! HB
  853. if (!mDontDiscard)
  854. {
  855. mMaxVirtualSize = 0.f;
  856. }
  857. mAdditionalDecodePriority = 0.f;
  858. }
  859. void LLViewerTexture::addFace(U32 ch, LLFace* facep)
  860. {
  861. if (!facep || ch >= LLRender::NUM_TEXTURE_CHANNELS)
  862. {
  863. llassert(false);
  864. return;
  865. }
  866. if (mNumFaces[ch] >= mFaceList[ch].size())
  867. {
  868. mFaceList[ch].resize(2 * mNumFaces[ch] + 1);
  869. }
  870. mFaceList[ch][mNumFaces[ch]] = facep;
  871. facep->setIndexInTex(ch, mNumFaces[ch]);
  872. ++mNumFaces[ch];
  873. mLastFaceListUpdate = gFrameTimeSeconds;
  874. }
  875. //virtual
  876. void LLViewerTexture::removeFace(U32 ch, LLFace* facep)
  877. {
  878. if (!facep || ch >= LLRender::NUM_TEXTURE_CHANNELS)
  879. {
  880. llassert(false);
  881. return;
  882. }
  883. if (mNumFaces[ch] > 1)
  884. {
  885. U32 index = facep->getIndexInTex(ch);
  886. if (index < (U32)mFaceList[ch].size() && index < mNumFaces[ch])
  887. {
  888. mFaceList[ch][index] = mFaceList[ch][--mNumFaces[ch]];
  889. mFaceList[ch][index]->setIndexInTex(ch, index);
  890. }
  891. else
  892. {
  893. llwarns << "Index out of range !" << llendl;
  894. llassert(false);
  895. }
  896. }
  897. else
  898. {
  899. mFaceList[ch].clear();
  900. mNumFaces[ch] = 0;
  901. }
  902. mLastFaceListUpdate = gFrameTimeSeconds;
  903. }
  904. S32 LLViewerTexture::getTotalNumFaces() const
  905. {
  906. S32 ret = 0;
  907. for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
  908. {
  909. ret += mNumFaces[i];
  910. }
  911. return ret;
  912. }
  913. S32 LLViewerTexture::getNumFaces(U32 ch) const
  914. {
  915. llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
  916. return mNumFaces[ch];
  917. }
  918. void LLViewerTexture::reorganizeFaceList()
  919. {
  920. constexpr F32 MAX_WAIT_TIME = 20.f; // seconds
  921. constexpr U32 MAX_EXTRA_BUFFER_SIZE = 4;
  922. if (gFrameTimeSeconds - mLastFaceListUpdate < MAX_WAIT_TIME)
  923. {
  924. return;
  925. }
  926. for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
  927. {
  928. if (mNumFaces[i] + MAX_EXTRA_BUFFER_SIZE > mFaceList[i].size())
  929. {
  930. return;
  931. }
  932. mFaceList[i].erase(mFaceList[i].begin() + mNumFaces[i],
  933. mFaceList[i].end());
  934. }
  935. mLastFaceListUpdate = gFrameTimeSeconds;
  936. }
  937. void LLViewerTexture::addVolume(U32 ch, LLVOVolume* volumep)
  938. {
  939. if (mNumVolumes[ch] >= mVolumeList[ch].size())
  940. {
  941. mVolumeList[ch].resize(2 * mNumVolumes[ch] + 1);
  942. }
  943. mVolumeList[ch][mNumVolumes[ch]] = volumep;
  944. volumep->setIndexInTex(ch, mNumVolumes[ch]);
  945. ++mNumVolumes[ch];
  946. mLastVolumeListUpdate = gFrameTimeSeconds;
  947. }
  948. void LLViewerTexture::removeVolume(U32 ch, LLVOVolume* volumep)
  949. {
  950. if (mNumVolumes[ch] > 1)
  951. {
  952. S32 index = volumep->getIndexInTex(ch);
  953. llassert(index < (S32)mVolumeList[ch].size() &&
  954. index < (S32)mNumVolumes[ch]);
  955. mVolumeList[ch][index] = mVolumeList[ch][--mNumVolumes[ch]];
  956. mVolumeList[ch][index]->setIndexInTex(ch, index);
  957. }
  958. else
  959. {
  960. mVolumeList[ch].clear();
  961. mNumVolumes[ch] = 0;
  962. }
  963. mLastVolumeListUpdate = gFrameTimeSeconds;
  964. }
  965. void LLViewerTexture::reorganizeVolumeList()
  966. {
  967. constexpr F32 MAX_WAIT_TIME = 20.f; // seconds
  968. constexpr U32 MAX_EXTRA_BUFFER_SIZE = 4;
  969. if (gFrameTimeSeconds - mLastVolumeListUpdate < MAX_WAIT_TIME)
  970. {
  971. return;
  972. }
  973. for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i)
  974. {
  975. if (mNumVolumes[i] + MAX_EXTRA_BUFFER_SIZE > mVolumeList[i].size())
  976. {
  977. return;
  978. }
  979. }
  980. mLastVolumeListUpdate = gFrameTimeSeconds;
  981. for (U32 i = 0; i < LLRender::NUM_VOLUME_TEXTURE_CHANNELS; ++i)
  982. {
  983. mVolumeList[i].erase(mVolumeList[i].begin() + mNumVolumes[i],
  984. mVolumeList[i].end());
  985. }
  986. }
  987. //-----------------------------------------------------------------------------
  988. // LLViewerFetchedTexture
  989. //-----------------------------------------------------------------------------
  990. const std::string& fttype_to_string(const FTType& fttype)
  991. {
  992. static const std::string ftt_unknown("FTT_UNKNOWN");
  993. static const std::string ftt_default("FTT_DEFAULT");
  994. static const std::string ftt_server_bake("FTT_SERVER_BAKE");
  995. static const std::string ftt_host_bake("FTT_HOST_BAKE");
  996. static const std::string ftt_map_tile("FTT_MAP_TILE");
  997. static const std::string ftt_local_file("FTT_LOCAL_FILE");
  998. static const std::string ftt_error("FTT_ERROR");
  999. switch (fttype)
  1000. {
  1001. case FTT_UNKNOWN:
  1002. return ftt_unknown;
  1003. case FTT_DEFAULT:
  1004. return ftt_default;
  1005. case FTT_SERVER_BAKE:
  1006. return ftt_server_bake;
  1007. case FTT_HOST_BAKE:
  1008. return ftt_host_bake;
  1009. case FTT_MAP_TILE:
  1010. return ftt_map_tile;
  1011. case FTT_LOCAL_FILE:
  1012. return ftt_local_file;
  1013. }
  1014. return ftt_error;
  1015. }
  1016. LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id,
  1017. FTType f_type,
  1018. const LLHost& host,
  1019. bool usemipmaps)
  1020. : LLViewerTexture(id, usemipmaps),
  1021. mTargetHost(host)
  1022. {
  1023. init(true);
  1024. mFTType = f_type;
  1025. generateGLTexture();
  1026. mImageGLp->setNeedsAlphaAndPickMask(true);
  1027. if (!host.isInvalid())
  1028. {
  1029. // We must request the image from the provided host sim.
  1030. mCanUseHTTP = false;
  1031. }
  1032. }
  1033. LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* rawp,
  1034. FTType f_type, bool usemipmaps)
  1035. : LLViewerTexture(rawp, usemipmaps)
  1036. {
  1037. init(true);
  1038. mFTType = f_type;
  1039. // Make sure we are not going to enter the texture fetcher, since this is
  1040. // just a fake "fetched" texture based on a local raw image, and there is
  1041. // strictly nothing to be fetched from network, neither from a file ! HB
  1042. mRawImage = const_cast<LLImageRaw*>(rawp); // Let's cheat...
  1043. mFullWidth = mRawImage->getWidth();
  1044. mFullHeight = mRawImage->getHeight();
  1045. mSavedRawImage = mRawImage;
  1046. mIsRawImageValid = true;
  1047. mIsMissingAsset = mFullyLoaded = true;
  1048. mCanUseHTTP = false;
  1049. mDesiredSavedRawDiscardLevel = mDesiredDiscardLevel = 0;
  1050. mDesiredSavedRawDiscardLevel = mSavedRawDiscardLevel = 0;
  1051. }
  1052. LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url,
  1053. FTType f_type,
  1054. const LLUUID& id,
  1055. bool usemipmaps)
  1056. : LLViewerTexture(id, usemipmaps),
  1057. mUrl(url)
  1058. {
  1059. init(true);
  1060. mFTType = f_type;
  1061. generateGLTexture();
  1062. mImageGLp->setNeedsAlphaAndPickMask(true);
  1063. }
  1064. void LLViewerFetchedTexture::init(bool firstinit)
  1065. {
  1066. mOrigWidth = 0;
  1067. mOrigHeight = 0;
  1068. mNeedsAux = mHasAux = false;
  1069. mRequestedDiscardLevel = -1;
  1070. mRequestedDownloadPriority = 0.f;
  1071. mFullyLoaded = false;
  1072. mCanUseHTTP = true;
  1073. mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
  1074. mMinDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
  1075. mKnownDrawWidth = 0;
  1076. mKnownDrawHeight = 0;
  1077. mKnownDrawSizeChanged = false;
  1078. if (firstinit)
  1079. {
  1080. mDecodePriority = 0.f;
  1081. mInImageList = false;
  1082. }
  1083. // Only set mIsMissingAsset true when we know for certain that the database
  1084. // does not contain this image.
  1085. mIsMissingAsset = false;
  1086. // When force-deleting a request before it can complete, set this as true
  1087. // to avoid false missing asset cases.
  1088. mWasDeleted = false;
  1089. mLoadedCallbackDesiredDiscardLevel = S8_MAX;
  1090. mPauseLoadedCallBacks = true;
  1091. mNeedsCreateTexture = false;
  1092. mIsRawImageValid = false;
  1093. mRawDiscardLevel = INVALID_DISCARD_LEVEL;
  1094. mMinDiscardLevel = 0;
  1095. mHasFetcher = false;
  1096. mIsFetching = false;
  1097. mFetchState = 0;
  1098. mFetchPriority = 0;
  1099. mDownloadProgress = 0.f;
  1100. mFetchDeltaTime = 999999.f;
  1101. mRequestDeltaTime = 0.f;
  1102. mForSculpt = false;
  1103. mCachedRawImage = NULL;
  1104. mCachedRawDiscardLevel = -1;
  1105. mCachedRawImageReady = false;
  1106. mSavedRawImage = NULL;
  1107. mForceToSaveRawImage = false;
  1108. mSaveRawImage = false;
  1109. mSavedRawDiscardLevel = -1;
  1110. mDesiredSavedRawDiscardLevel = -1;
  1111. mLastReferencedSavedRawImageTime = 0.f;
  1112. mKeptSavedRawImageTime = 0.f;
  1113. mLastCallBackActiveTime = 0.f;
  1114. mForceCallbackFetch = false;
  1115. mFTType = FTT_UNKNOWN;
  1116. mLastPacketTime = mStopFetchingTime = gFrameTimeSeconds;
  1117. }
  1118. LLViewerFetchedTexture::~LLViewerFetchedTexture()
  1119. {
  1120. // NOTE: gTextureFetchp can be NULL when viewer is shutting down; this is
  1121. // due to LLWearableList is singleton and is destroyed after
  1122. // LLAppViewer::cleanup() was called (see ticket EXT-177).
  1123. if (mHasFetcher && gTextureFetchp)
  1124. {
  1125. gTextureFetchp->deleteRequest(getID());
  1126. }
  1127. cleanup();
  1128. }
  1129. //virtual
  1130. S8 LLViewerFetchedTexture::getType() const
  1131. {
  1132. return LLViewerTexture::FETCHED_TEXTURE;
  1133. }
  1134. void LLViewerFetchedTexture::cleanup()
  1135. {
  1136. for (callback_list_t::iterator iter = mLoadedCallbackList.begin();
  1137. iter != mLoadedCallbackList.end(); )
  1138. {
  1139. LLLoadedCallbackEntry* entryp = *iter++;
  1140. // We never finished loading the image, so indicate a failure.
  1141. // Note: this allows mLoadedCallbackUserData to be cleaned up.
  1142. entryp->mCallback(false, this, NULL, NULL, 0, true, entryp->mUserData);
  1143. entryp->removeTexture(this);
  1144. delete entryp;
  1145. }
  1146. mLoadedCallbackList.clear();
  1147. mNeedsAux = false;
  1148. // Clean up image data
  1149. destroyRawImage();
  1150. mCachedRawImage = NULL;
  1151. mCachedRawDiscardLevel = -1;
  1152. mCachedRawImageReady = false;
  1153. mSavedRawImage = NULL;
  1154. mSavedRawDiscardLevel = -1;
  1155. }
  1156. void LLViewerFetchedTexture::setForSculpt()
  1157. {
  1158. constexpr S32 MAX_INTERVAL = 8; // In frames
  1159. mForSculpt = true;
  1160. setBoostLevel(LLGLTexture::BOOST_SCULPTED);
  1161. #if !LL_IMPLICIT_SETNODELETE
  1162. setNoDelete();
  1163. #endif
  1164. if (isForSculptOnly() && hasGLTexture() && !getBoundRecently())
  1165. {
  1166. destroyGLTexture(); // Sculpt image does not need GL texture.
  1167. mTextureState = ACTIVE;
  1168. }
  1169. checkCachedRawSculptImage();
  1170. setMaxVirtualSizeResetInterval(MAX_INTERVAL);
  1171. }
  1172. void LLViewerFetchedTexture::setDeletionCandidate()
  1173. {
  1174. if (mTextureState == INACTIVE)
  1175. {
  1176. mTextureState = DELETION_CANDIDATE;
  1177. }
  1178. }
  1179. void LLViewerFetchedTexture::setInactive()
  1180. {
  1181. if (mTextureState == ACTIVE &&
  1182. (mImageGLp.isNull() || !mImageGLp->getBoundRecently()))
  1183. {
  1184. mTextureState = INACTIVE;
  1185. }
  1186. }
  1187. bool LLViewerFetchedTexture::isFullyLoaded() const
  1188. {
  1189. // Unfortunately, the boolean "mFullyLoaded" is never updated correctly so
  1190. // we use that logic to check if the texture is there and completely
  1191. // downloaded
  1192. return mFullWidth != 0 && mFullHeight != 0 && !mIsFetching && !mHasFetcher;
  1193. }
  1194. // virtual
  1195. void LLViewerFetchedTexture::dump()
  1196. {
  1197. LLViewerTexture::dump();
  1198. llinfos << "Dump : " << mID
  1199. << ", mIsMissingAsset = " << (S32)mIsMissingAsset
  1200. << ", mFullWidth = " << mFullWidth
  1201. << ", mFullHeight = " << mFullHeight
  1202. << ", mOrigWidth = " << mOrigWidth
  1203. << ", mOrigHeight = " << mOrigHeight
  1204. << llendl;
  1205. llinfos << " : "
  1206. << " mFullyLoaded = " << (S32)mFullyLoaded
  1207. << ", mFetchState = " << (S32)mFetchState
  1208. << ", mFetchPriority = " << (S32)mFetchPriority
  1209. << ", mDownloadProgress = " << (F32)mDownloadProgress
  1210. << llendl;
  1211. llinfos << " : "
  1212. << " mHasFetcher = " << (S32)mHasFetcher
  1213. << ", mIsFetching = " << (S32)mIsFetching
  1214. << ", mWasDeleted = " << (S32)mWasDeleted
  1215. << ", mBoostLevel = " << (S32)mBoostLevel
  1216. << llendl;
  1217. }
  1218. ///////////////////////////////////////////////////////////////////////////////
  1219. // ONLY called from LLViewerFetchedTextureList
  1220. bool LLViewerFetchedTexture::destroyTexture()
  1221. {
  1222. if (mNeedsCreateTexture)
  1223. {
  1224. // Return if in the process of generating a new texture.
  1225. return false;
  1226. }
  1227. destroyGLTexture();
  1228. mFullyLoaded = false;
  1229. return true;
  1230. }
  1231. void LLViewerFetchedTexture::addToCreateTexture()
  1232. {
  1233. bool force_update = false;
  1234. if (getComponents() != mRawImage->getComponents())
  1235. {
  1236. // We have changed the number of components, so we need to move any
  1237. // object using this pool to a different pool.
  1238. mComponents = mRawImage->getComponents();
  1239. mImageGLp->setComponents(mComponents);
  1240. force_update = true;
  1241. for (U32 j = 0; j < LLRender::NUM_TEXTURE_CHANNELS; ++j)
  1242. {
  1243. U32 count = mNumFaces[j];
  1244. U32 list_size = mFaceList[j].size();
  1245. if (count > list_size)
  1246. {
  1247. llwarns_once << "Face count greater than face list size for texture channel: "
  1248. << j << ". Clamping down." << llendl;
  1249. count = list_size;
  1250. }
  1251. for (U32 i = 0; i < count; ++i)
  1252. {
  1253. LLFace* facep = mFaceList[j][i];
  1254. if (facep)
  1255. {
  1256. facep->dirtyTexture();
  1257. }
  1258. }
  1259. }
  1260. // Discard the cached raw image and the saved raw image
  1261. mCachedRawImageReady = false;
  1262. mCachedRawDiscardLevel = -1;
  1263. mCachedRawImage = NULL;
  1264. mSavedRawDiscardLevel = -1;
  1265. mSavedRawImage = NULL;
  1266. }
  1267. if (isForSculptOnly())
  1268. {
  1269. // Just update some variables, not to create a real GL texture.
  1270. createGLTexture(mRawDiscardLevel, mRawImage, 0, false);
  1271. mNeedsCreateTexture = false;
  1272. destroyRawImage();
  1273. }
  1274. else if (!force_update && getDiscardLevel() > -1 &&
  1275. getDiscardLevel() <= mRawDiscardLevel)
  1276. {
  1277. mNeedsCreateTexture = false;
  1278. destroyRawImage();
  1279. }
  1280. else
  1281. {
  1282. // LLImageRaw:scale() allows for a lower memory usage but also causes
  1283. // memory fragmentation... This is a trade off ! HB
  1284. static LLCachedControl<bool> rescale(gSavedSettings,
  1285. "TextureRescaleFetched");
  1286. // If mRequestedDiscardLevel > mDesiredDiscardLevel, we assume the
  1287. // required image res keeps going up, so do not scale down the over
  1288. // qualified image. Note: scaling down image is expensensive. Do it
  1289. // only when very necessary.
  1290. if (rescale && !mForceToSaveRawImage &&
  1291. mRequestedDiscardLevel <= mDesiredDiscardLevel)
  1292. {
  1293. S32 w = mFullWidth >> mRawDiscardLevel;
  1294. S32 h = mFullHeight >> mRawDiscardLevel;
  1295. // If big image, do not load extra data, scale it down to size
  1296. // >= LLViewerTexture::sMinLargeImageSize
  1297. if (w * h > LLViewerTexture::sMinLargeImageSize)
  1298. {
  1299. S32 d_level = llmin(mRequestedDiscardLevel,
  1300. (S32)mDesiredDiscardLevel) - mRawDiscardLevel;
  1301. if (d_level > 0)
  1302. {
  1303. S32 i = 0;
  1304. while (d_level > 0 &&
  1305. (w >> i) * (h >> i) > LLViewerTexture::sMinLargeImageSize)
  1306. {
  1307. ++i;
  1308. --d_level;
  1309. }
  1310. if (i > 0)
  1311. {
  1312. mRawDiscardLevel += i;
  1313. if (mRawDiscardLevel >= getDiscardLevel() &&
  1314. getDiscardLevel() > 0)
  1315. {
  1316. mNeedsCreateTexture = false;
  1317. destroyRawImage();
  1318. return;
  1319. }
  1320. // Make a duplicate in case somebody else is using this
  1321. // raw image:
  1322. LLPointer<LLImageRaw> dup =
  1323. mRawImage->scaled(w >> i, h >> i);
  1324. if (dup.notNull())
  1325. {
  1326. mRawImage = std::move(dup);
  1327. }
  1328. }
  1329. }
  1330. }
  1331. }
  1332. scheduleCreateTexture();
  1333. }
  1334. }
  1335. // ONLY called from LLViewerTextureList
  1336. bool LLViewerFetchedTexture::preCreateTexture(S32 usename)
  1337. {
  1338. if (!mNeedsCreateTexture)
  1339. {
  1340. destroyRawImage();
  1341. return false;
  1342. }
  1343. mNeedsCreateTexture = false;
  1344. if (mRawImage.isNull())
  1345. {
  1346. llwarns << "Trying to create texture " << mID.asString()
  1347. << " without raw image: aborting !" << llendl;
  1348. destroyRawImage();
  1349. return false;
  1350. }
  1351. LL_DEBUGS("ViewerTexture") << "Creating image " << mID.asString()
  1352. << " - discard level = " << mRawDiscardLevel
  1353. << " - Size: " << mRawImage->getWidth() << "x"
  1354. << mRawImage->getHeight() << " pixels - "
  1355. << mRawImage->getDataSize() << " bytes."
  1356. << LL_ENDL;
  1357. bool res = true;
  1358. // Store original size only for locally-sourced images
  1359. if (mUrl.compare(0, 7, "file://") == 0)
  1360. {
  1361. mOrigWidth = mRawImage->getWidth();
  1362. mOrigHeight = mRawImage->getHeight();
  1363. const S32 max_size = gMaxImageSizeDefault * 2;
  1364. #if 0
  1365. if (mBoostLevel == BOOST_PREVIEW)
  1366. {
  1367. mRawImage->biasedScaleToPowerOfTwo(1024);
  1368. }
  1369. else
  1370. {
  1371. // Leave black border, do not scale image content
  1372. mRawImage->expandToPowerOfTwo(max_size, false);
  1373. }
  1374. #else
  1375. // Do not scale image content
  1376. mRawImage->expandToPowerOfTwo(max_size, false);
  1377. #endif
  1378. mFullWidth = mRawImage->getWidth();
  1379. mFullHeight = mRawImage->getHeight();
  1380. setTexelsPerImage();
  1381. }
  1382. else
  1383. {
  1384. mOrigWidth = mFullWidth;
  1385. mOrigHeight = mFullHeight;
  1386. }
  1387. bool size_okay = true;
  1388. S32 discard_level = mRawDiscardLevel;
  1389. if (discard_level < 0)
  1390. {
  1391. llwarns << "Trying to create texture " << mID.asString()
  1392. << " with a negative discard level. Zeroing it." << llendl;
  1393. discard_level = 0;
  1394. }
  1395. S32 raw_width = mRawImage->getWidth() << discard_level;
  1396. S32 raw_height = mRawImage->getHeight() << discard_level;
  1397. const S32 max_size = gMaxImageSizeDefault * 2;
  1398. if (raw_width > max_size || raw_height > max_size)
  1399. {
  1400. llinfos << "Width or height is greater than " << max_size
  1401. << ": (" << raw_width << "," << raw_height << ")" << llendl;
  1402. size_okay = false;
  1403. }
  1404. if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight()))
  1405. {
  1406. // A non power-of-two image was uploaded through a non standard client
  1407. llinfos << "Non power of two width or height: (" << mRawImage->getWidth()
  1408. << "," << mRawImage->getHeight() << ")" << llendl;
  1409. size_okay = false;
  1410. }
  1411. if (!size_okay)
  1412. {
  1413. // An inappropriately-sized image was uploaded through a non standard
  1414. // client. We treat these images as missing assets which causes them to
  1415. // be renderd as 'missing image' and to stop requesting data.
  1416. llwarns << "Image " << mID.asString()
  1417. << " does not have an acceptable size, setting as missing."
  1418. << llendl;
  1419. setIsMissingAsset();
  1420. destroyRawImage();
  1421. return false;
  1422. }
  1423. if (mImageGLp->hasExplicitFormat())
  1424. {
  1425. U32 format = mImageGLp->getPrimaryFormat();
  1426. S8 components = mRawImage->getComponents();
  1427. if (((format == GL_RGBA && components < 4) ||
  1428. (format == GL_RGB && components < 3)))
  1429. {
  1430. llwarns << "Cannot create texture " << mID
  1431. << ": invalid image format: " << std::hex << format
  1432. << std::dec << " - Number of components: " << components
  1433. << llendl;
  1434. // Was expecting specific format but raw texture has insufficient
  1435. // components for such format, using such texture would result in a
  1436. // crash or would display wrongly. Texture might be corrupted
  1437. // server side, so just set as missing and clear cached texture.
  1438. setIsMissingAsset();
  1439. destroyRawImage();
  1440. gTextureCachep->removeFromCache(mID);
  1441. return false;
  1442. }
  1443. }
  1444. return res;
  1445. }
  1446. bool LLViewerFetchedTexture::createTexture(S32 usename)
  1447. {
  1448. if (!mNeedsCreateTexture)
  1449. {
  1450. return false;
  1451. }
  1452. return mImageGLp->createGLTexture(mRawDiscardLevel, mRawImage, usename,
  1453. true);
  1454. }
  1455. void LLViewerFetchedTexture::postCreateTexture()
  1456. {
  1457. if (!mNeedsCreateTexture)
  1458. {
  1459. return;
  1460. }
  1461. #if LL_FIX_MAT_TRANSPARENCY
  1462. notifyAboutCreatingTexture();
  1463. #endif
  1464. setActive();
  1465. if (!needsToSaveRawImage())
  1466. {
  1467. mNeedsAux = false;
  1468. destroyRawImage();
  1469. }
  1470. mNeedsCreateTexture = false;
  1471. }
  1472. void LLViewerFetchedTexture::scheduleCreateTexture()
  1473. {
  1474. if (mNeedsCreateTexture)
  1475. {
  1476. return;
  1477. }
  1478. mNeedsCreateTexture = true;
  1479. if (!preCreateTexture())
  1480. {
  1481. return;
  1482. }
  1483. // Reassert this since it was set to false in preCreateTexture()... HB
  1484. mNeedsCreateTexture = true;
  1485. // This will be set appropiately below.
  1486. sImageThreadCreationsCapped = false;
  1487. // First, see if we can queue anything: this is not the case when the GL
  1488. // thread(s) is(are) not started (sEnabled is false);
  1489. bool can_queue = LLImageGLThread::sEnabled && gMainloopWorkp;
  1490. if (can_queue)
  1491. {
  1492. // ... finally, do not let the GL queue thread get trashed with too
  1493. // many requests and process in the main thread any request that would
  1494. // add beyond a reasonnable (and configurable) queue size. HB
  1495. static LLCachedControl<U32> queue_size(gSavedSettings,
  1496. "GLWorkerQueueSize");
  1497. sImageThreadQueueSize = gMainloopWorkp->size();
  1498. sImageThreadCreationsCapped = queue_size &&
  1499. sImageThreadQueueSize > (U32)queue_size;
  1500. if (!sImageThreadCreationsCapped)
  1501. {
  1502. ref();
  1503. if (gMainloopWorkp->postTo(gImageQueuep,
  1504. // Work to be done on worker thread
  1505. [this]()
  1506. {
  1507. // Actually create the texture on a
  1508. // background thread
  1509. createTexture();
  1510. },
  1511. // Callback to be run on main thread
  1512. [this]()
  1513. {
  1514. // Finalize on main thread
  1515. postCreateTexture();
  1516. unref();
  1517. }))
  1518. {
  1519. // Success !
  1520. ++sImageThreadCreations;
  1521. return;
  1522. }
  1523. // Failed (gImageQueuep closed): fallback to main thread.
  1524. unref();
  1525. }
  1526. }
  1527. // In case we cannot thread the GL image creation, insert ourselves in
  1528. // mCreateTextureList for a creation in the main thread.
  1529. gTextureList.mCreateTextureList.insert(this);
  1530. ++sMainThreadCreations;
  1531. }
  1532. // Call with 0,0 to turn this feature off.
  1533. //virtual
  1534. void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
  1535. {
  1536. if (mKnownDrawWidth < width || mKnownDrawHeight < height)
  1537. {
  1538. mKnownDrawWidth = llmax(mKnownDrawWidth, width);
  1539. mKnownDrawHeight = llmax(mKnownDrawHeight, height);
  1540. mKnownDrawSizeChanged = true;
  1541. mFullyLoaded = false;
  1542. }
  1543. addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight));
  1544. }
  1545. //virtual
  1546. void LLViewerFetchedTexture::processTextureStats()
  1547. {
  1548. if (mFullyLoaded)
  1549. {
  1550. if (mDesiredDiscardLevel > mMinDesiredDiscardLevel)
  1551. {
  1552. // Need to load more
  1553. mDesiredDiscardLevel = mMinDesiredDiscardLevel;
  1554. mFullyLoaded = false;
  1555. }
  1556. }
  1557. else
  1558. {
  1559. updateVirtualSize();
  1560. static LLCachedControl<bool> textures_fullres(gSavedSettings,
  1561. "TextureLoadFullRes");
  1562. if (textures_fullres)
  1563. {
  1564. mDesiredDiscardLevel = 0;
  1565. }
  1566. else if (!LLPipeline::sRenderDeferred && mBoostLevel == BOOST_ALM)
  1567. {
  1568. mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
  1569. }
  1570. else if (!mFullWidth || !mFullHeight)
  1571. {
  1572. mDesiredDiscardLevel = llmin(getMaxDiscardLevel(),
  1573. (S32)mLoadedCallbackDesiredDiscardLevel);
  1574. }
  1575. else
  1576. {
  1577. if (!mKnownDrawWidth || !mKnownDrawHeight ||
  1578. mFullWidth <= mKnownDrawWidth ||
  1579. mFullHeight <= mKnownDrawHeight)
  1580. {
  1581. mDesiredDiscardLevel = getMinDiscardLevel();
  1582. }
  1583. else if (mKnownDrawSizeChanged) // Known draw size is set
  1584. {
  1585. F32 ratio = llmin((F32)mFullWidth / (F32)mKnownDrawWidth,
  1586. (F32)mFullHeight / (F32)mKnownDrawHeight);
  1587. mDesiredDiscardLevel = (S8)logf(ratio / F_LN2);
  1588. mDesiredDiscardLevel = llclamp(mDesiredDiscardLevel, (S8)0,
  1589. (S8)getMaxDiscardLevel());
  1590. mDesiredDiscardLevel = llmin(mDesiredDiscardLevel,
  1591. mMinDesiredDiscardLevel);
  1592. }
  1593. mKnownDrawSizeChanged = false;
  1594. // If this texture is used for ALM (i.e. as a normal or specular
  1595. // map, or as a light texture), and we are low on available bound
  1596. // GL textures memory, scale it down. HB
  1597. if (mBoostLevel == BOOST_ALM && sALMTexPenalty &&
  1598. mDesiredDiscardLevel < MAX_DISCARD_LEVEL)
  1599. {
  1600. ++mDesiredDiscardLevel;
  1601. }
  1602. if (getDiscardLevel() >= 0 &&
  1603. getDiscardLevel() <= mDesiredDiscardLevel)
  1604. {
  1605. mFullyLoaded = true;
  1606. }
  1607. }
  1608. }
  1609. if (mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0)
  1610. {
  1611. // Force to refetch the texture.
  1612. mDesiredDiscardLevel = llmin(mDesiredDiscardLevel,
  1613. (S8)mDesiredSavedRawDiscardLevel);
  1614. if (getDiscardLevel() < 0 || getDiscardLevel() > mDesiredDiscardLevel)
  1615. {
  1616. mFullyLoaded = false;
  1617. }
  1618. }
  1619. }
  1620. constexpr F32 MAX_PRIORITY_PIXEL = 999.f; // Pixel area
  1621. constexpr F32 PRIORITY_BOOST_LEVEL_FACTOR = 1000.f; // Boost level
  1622. constexpr F32 PRIORITY_DELTA_DISCARD_LEVEL_FACTOR = 100000.f; // Delta discard
  1623. constexpr S32 MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY = 4;
  1624. constexpr F32 PRIORITY_ADDITIONAL_FACTOR = 1000000.f; // Additional
  1625. constexpr S32 MAX_ADDITIONAL_LEVEL_FOR_PRIORITY = 8;
  1626. constexpr F32 PRIORITY_BOOST_HIGH_FACTOR = 10000000.f; // Boost high
  1627. constexpr F32 MAX_DECODE_PRIORITY = PRIORITY_BOOST_HIGH_FACTOR +
  1628. PRIORITY_ADDITIONAL_FACTOR *
  1629. (MAX_ADDITIONAL_LEVEL_FOR_PRIORITY + 1) +
  1630. PRIORITY_DELTA_DISCARD_LEVEL_FACTOR *
  1631. (MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY + 1) +
  1632. PRIORITY_BOOST_LEVEL_FACTOR *
  1633. (LLGLTexture::BOOST_MAX_LEVEL - 1) +
  1634. MAX_PRIORITY_PIXEL + 1.f;
  1635. F32 LLViewerFetchedTexture::calcDecodePriority()
  1636. {
  1637. if (mNeedsCreateTexture)
  1638. {
  1639. return mDecodePriority; // No change while waiting to create
  1640. }
  1641. if (mFullyLoaded && !mForceToSaveRawImage)
  1642. {
  1643. return -1.f; // Already loaded for static texture
  1644. }
  1645. S32 cur_discard = getCurrentDiscardLevelForFetching();
  1646. bool have_all_data = cur_discard >= 0 &&
  1647. cur_discard <= mDesiredDiscardLevel;
  1648. F32 pixel_priority = sqrtf(mMaxVirtualSize);
  1649. F32 priority = 0.f;
  1650. if (mIsMissingAsset || mWasDeleted)
  1651. {
  1652. priority = 0.f;
  1653. }
  1654. else if (mDesiredDiscardLevel >= cur_discard && cur_discard > -1)
  1655. {
  1656. priority = -2.f;
  1657. }
  1658. else if (mCachedRawDiscardLevel > -1 &&
  1659. mDesiredDiscardLevel >= mCachedRawDiscardLevel)
  1660. {
  1661. priority = -3.f;
  1662. }
  1663. else if (mDesiredDiscardLevel > getMaxDiscardLevel())
  1664. {
  1665. // Do not decode anything we do not need
  1666. priority = -4.f;
  1667. }
  1668. else if (!have_all_data && mBoostLevel == BOOST_UI)
  1669. {
  1670. priority = 1.f;
  1671. }
  1672. else if (pixel_priority < 0.001f && !have_all_data)
  1673. {
  1674. // Not on screen but we might want some data
  1675. if (mBoostLevel > BOOST_HIGH)
  1676. {
  1677. // Always want high boosted images
  1678. priority = 1.f;
  1679. }
  1680. else
  1681. {
  1682. priority = -5.f; // Stop fetching
  1683. }
  1684. }
  1685. else if (cur_discard < 0)
  1686. {
  1687. // Texture does not have any data, so we do not know the size of the
  1688. // image, treat it like 32 * 32. Priority range = 100,000 - 500,000
  1689. F32 desired = (F32)(logf(32.f / pixel_priority) / F_LN2);
  1690. S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;
  1691. ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
  1692. priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
  1693. // Boost the textures without any data so far
  1694. setAdditionalDecodePriority(0.1f);
  1695. }
  1696. else if (mMinDiscardLevel > 0 && cur_discard <= mMinDiscardLevel)
  1697. {
  1698. // Larger mips are corrupted
  1699. priority = -6.f;
  1700. }
  1701. else
  1702. {
  1703. // Priority range = 100,000 - 500,000
  1704. S32 desired_discard = mDesiredDiscardLevel;
  1705. if (!isJustBound() && mCachedRawImageReady)
  1706. {
  1707. if (mBoostLevel < BOOST_HIGH)
  1708. {
  1709. // We do not have rendered this in a while, de-prioritize it
  1710. desired_discard += 2;
  1711. }
  1712. else
  1713. {
  1714. // We do not have rendered this in the last half second, and we
  1715. // have a cached raw image, leave the desired discard as-is
  1716. desired_discard = cur_discard;
  1717. }
  1718. }
  1719. S32 ddiscard = cur_discard - desired_discard;
  1720. ddiscard = llclamp(ddiscard, -1, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
  1721. priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
  1722. }
  1723. // Priority Formula:
  1724. // BOOST_HIGH + ADDITIONAL PRI + DELTA DISCARD + BOOST LEVEL + PIXELS
  1725. // [10,000,000] + [1,000,000-9,000,000] + [100,000-500,000] + [1-20,000] + [0-999]
  1726. if (priority > 0.f)
  1727. {
  1728. bool large_enough = mCachedRawImageReady &&
  1729. mTexelsPerImage > sMinLargeImageSize;
  1730. if (large_enough)
  1731. {
  1732. // Note: to give small, low-priority textures some chance to be
  1733. // fetched, cut the priority in half if the texture size is larger
  1734. // than 256 * 256 and has a 64 * 64 ready.
  1735. priority *= 0.5f;
  1736. }
  1737. pixel_priority = llclamp(pixel_priority, 0.f, MAX_PRIORITY_PIXEL);
  1738. priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel;
  1739. if (mBoostLevel > BOOST_HIGH)
  1740. {
  1741. if (mBoostLevel > BOOST_SUPER_HIGH)
  1742. {
  1743. // For very important textures, always grant the highest
  1744. // priority.
  1745. priority += PRIORITY_BOOST_HIGH_FACTOR;
  1746. }
  1747. else if (mCachedRawImageReady)
  1748. {
  1749. // Note: to give small, low-priority textures some chance to be
  1750. // fetched, if high priority texture has a 64*64 ready, lower
  1751. // its fetching priority.
  1752. setAdditionalDecodePriority(0.5f);
  1753. }
  1754. else
  1755. {
  1756. priority += PRIORITY_BOOST_HIGH_FACTOR;
  1757. }
  1758. }
  1759. if (mAdditionalDecodePriority > 0.f)
  1760. {
  1761. // Priority range += 1,000,000.f-9,000,000.f
  1762. F32 additional = PRIORITY_ADDITIONAL_FACTOR *
  1763. (1.f + mAdditionalDecodePriority *
  1764. MAX_ADDITIONAL_LEVEL_FOR_PRIORITY);
  1765. if (large_enough)
  1766. {
  1767. // Note: to give small, low-priority textures some chance to be
  1768. // fetched, cut the additional priority to a quarter if the
  1769. // texture size is larger than 256 * 256 and has a 64*64 ready.
  1770. additional *= 0.25f;
  1771. }
  1772. priority += additional;
  1773. }
  1774. }
  1775. return priority;
  1776. }
  1777. //static
  1778. F32 LLViewerFetchedTexture::maxDecodePriority()
  1779. {
  1780. return MAX_DECODE_PRIORITY;
  1781. }
  1782. void LLViewerFetchedTexture::setDecodePriority(F32 priority)
  1783. {
  1784. mDecodePriority = priority;
  1785. if (mDecodePriority < F_ALMOST_ZERO)
  1786. {
  1787. mStopFetchingTime = gFrameTimeSeconds;
  1788. }
  1789. }
  1790. void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
  1791. {
  1792. priority = llclamp(priority, 0.f, 1.f);
  1793. if (mAdditionalDecodePriority < priority)
  1794. {
  1795. mAdditionalDecodePriority = priority;
  1796. }
  1797. }
  1798. void LLViewerFetchedTexture::updateVirtualSize()
  1799. {
  1800. if (!mMaxVirtualSizeResetCounter)
  1801. {
  1802. addTextureStats(0.f, false); // Reset
  1803. }
  1804. for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
  1805. {
  1806. U32 list_size = mFaceList[ch].size();
  1807. for (U32 i = 0, count = llmin(mNumFaces[ch], list_size); i < count;
  1808. ++i)
  1809. {
  1810. LLFace* facep = mFaceList[ch][i];
  1811. if (!facep)
  1812. {
  1813. continue;
  1814. }
  1815. LLDrawable* drawable = facep->getDrawable();
  1816. if (drawable && drawable->isRecentlyVisible())
  1817. {
  1818. addTextureStats(facep->getVirtualSize());
  1819. setAdditionalDecodePriority(facep->getImportanceToCamera());
  1820. }
  1821. }
  1822. }
  1823. if (mMaxVirtualSizeResetCounter > 0)
  1824. {
  1825. --mMaxVirtualSizeResetCounter;
  1826. }
  1827. reorganizeFaceList();
  1828. reorganizeVolumeList();
  1829. }
  1830. S32 LLViewerFetchedTexture::getCurrentDiscardLevelForFetching()
  1831. {
  1832. S32 current_discard = getDiscardLevel();
  1833. if (mForceToSaveRawImage)
  1834. {
  1835. if (mSavedRawDiscardLevel < 0 || current_discard < 0)
  1836. {
  1837. current_discard = -1;
  1838. }
  1839. else
  1840. {
  1841. current_discard = llmax(current_discard, mSavedRawDiscardLevel);
  1842. }
  1843. }
  1844. return current_discard;
  1845. }
  1846. //virtual
  1847. void LLViewerFetchedTexture::setBoostLevel(U32 level)
  1848. {
  1849. LLViewerTexture::setBoostLevel(level);
  1850. // Strongly encourage anything boosted to load at full res
  1851. static LLCachedControl<bool> boost_full_res(gSavedSettings,
  1852. "FullResBoostedTextures");
  1853. if (level >= BOOST_HIGH && boost_full_res &&
  1854. LLViewerTexture::sDesiredDiscardBias < 3.f)
  1855. {
  1856. mDesiredDiscardLevel = 0;
  1857. }
  1858. }
  1859. bool LLViewerFetchedTexture::updateFetch()
  1860. {
  1861. if (gUseWireframe && mBoostLevel != BOOST_SCULPTED &&
  1862. mBoostLevel <= BOOST_SUPER_HIGH)
  1863. {
  1864. // Do not fetch the surface textures in wireframe mode.
  1865. // Note: anything above BOOST_SUPER_HIGH level needs to keep being
  1866. // fetched (this also includes avatar textures used to perform viewer-
  1867. // side baking in OpenSim); in the same vein, BOOST_SCULPTED textures
  1868. // are not displayed but used for sculpted object geometry and must
  1869. // therefore keep being fetched. HB
  1870. return false;
  1871. }
  1872. mFetchState = 0;
  1873. mFetchPriority = 0;
  1874. mFetchDeltaTime = mRequestDeltaTime = 999999.f;
  1875. if (mNeedsCreateTexture)
  1876. {
  1877. // We may be fetching still (e.g. waiting on write) but do not check
  1878. // until we have processed the raw data we have.
  1879. return false;
  1880. }
  1881. if (mIsMissingAsset)
  1882. {
  1883. llassert_always(!mHasFetcher);
  1884. return false; // Skip
  1885. }
  1886. if (!mLoadedCallbackList.empty() && mRawImage.notNull())
  1887. {
  1888. // Process any raw image data in callbacks before replacing
  1889. return false;
  1890. }
  1891. S32 current_discard = getCurrentDiscardLevelForFetching();
  1892. S32 desired_discard = getDesiredDiscardLevel();
  1893. F32 decode_priority = llclamp(getDecodePriority(), 0.f,
  1894. MAX_DECODE_PRIORITY);
  1895. if (mIsFetching)
  1896. {
  1897. // Sets mRawDiscardLevel, mRawImage, mAuxRawImage
  1898. S32 fetch_discard = current_discard;
  1899. if (mRawImage.notNull())
  1900. {
  1901. --sRawCount;
  1902. }
  1903. if (mAuxRawImage.notNull())
  1904. {
  1905. --sAuxCount;
  1906. }
  1907. bool finished = gTextureFetchp->getRequestFinished(getID(),
  1908. fetch_discard,
  1909. mRawImage,
  1910. mAuxRawImage,
  1911. mLastHttpGetStatus);
  1912. if (mRawImage.notNull())
  1913. {
  1914. ++sRawCount;
  1915. }
  1916. if (mAuxRawImage.notNull())
  1917. {
  1918. mHasAux = true;
  1919. ++sAuxCount;
  1920. }
  1921. if (finished)
  1922. {
  1923. mIsFetching = false;
  1924. mLastPacketTime = gFrameTimeSeconds;
  1925. }
  1926. else
  1927. {
  1928. mFetchState =
  1929. gTextureFetchp->getFetchState(mID, mDownloadProgress,
  1930. mRequestedDownloadPriority,
  1931. mFetchPriority, mFetchDeltaTime,
  1932. mRequestDeltaTime, mCanUseHTTP);
  1933. }
  1934. // We may have data ready regardless of whether or not we are finished
  1935. // (e.g. waiting on write)
  1936. if (mRawImage.notNull())
  1937. {
  1938. mRawDiscardLevel = fetch_discard;
  1939. if (mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0 &&
  1940. (current_discard < 0 || mRawDiscardLevel < current_discard))
  1941. {
  1942. mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
  1943. mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
  1944. setTexelsPerImage();
  1945. const S32 max_size = gMaxImageSizeDefault * 2;
  1946. if (mFullWidth > max_size || mFullHeight > max_size)
  1947. {
  1948. // Discard all oversized textures.
  1949. destroyRawImage();
  1950. setIsMissingAsset();
  1951. mRawDiscardLevel = INVALID_DISCARD_LEVEL;
  1952. mIsFetching = false;
  1953. mLastPacketTime = gFrameTimeSeconds;
  1954. }
  1955. else
  1956. {
  1957. mIsRawImageValid = true;
  1958. addToCreateTexture();
  1959. }
  1960. return true;
  1961. }
  1962. else
  1963. {
  1964. // Data is ready but we do not need it (received it already
  1965. // while the fetcher was writing to disk)
  1966. destroyRawImage();
  1967. return false; // done
  1968. }
  1969. }
  1970. // Seconds to wait before cancelling fetching if decode_priority is 0
  1971. constexpr F32 MAX_HOLD_TIME = 5.f;
  1972. if (!mIsFetching)
  1973. {
  1974. if (decode_priority > 0 &&
  1975. (mRawDiscardLevel < 0 ||
  1976. mRawDiscardLevel == INVALID_DISCARD_LEVEL))
  1977. {
  1978. // We finished but received no data
  1979. S32 actual_level = getDiscardLevel();
  1980. if (actual_level < 0)
  1981. {
  1982. if (!mWasDeleted && getFTType() != FTT_MAP_TILE &&
  1983. // Do not complain for an Id which is actually a PBR
  1984. // terrain material one... HB
  1985. !LLTerrain::isAsset(mID))
  1986. {
  1987. llwarns << "No data received for image " << mID
  1988. << ", setting as missing. decode_priority = "
  1989. << decode_priority << " - mRawDiscardLevel = "
  1990. << mRawDiscardLevel << " - current_discard = "
  1991. << current_discard << llendl;
  1992. }
  1993. setIsMissingAsset();
  1994. desired_discard = -1;
  1995. }
  1996. else
  1997. {
  1998. LL_DEBUGS("ViewerTexture") << "Texture: " << mID
  1999. << " - Setting min discard to "
  2000. << current_discard << LL_ENDL;
  2001. if (current_discard >= 0)
  2002. {
  2003. mMinDiscardLevel = current_discard;
  2004. desired_discard = current_discard;
  2005. }
  2006. else
  2007. {
  2008. mMinDiscardLevel = actual_level;
  2009. desired_discard = actual_level;
  2010. }
  2011. }
  2012. destroyRawImage();
  2013. }
  2014. else if (mRawImage.notNull())
  2015. {
  2016. // We have data, but our fetch failed to return raw data.
  2017. // *TODO: Figure out why this is happening and fix it.
  2018. LL_DEBUGS("ViewerTexture") << "Texture: " << mID
  2019. << " - We have data but fetch failed to return raw data."
  2020. << LL_ENDL;
  2021. destroyRawImage();
  2022. }
  2023. }
  2024. else if (decode_priority > 0.f ||
  2025. gFrameTimeSeconds - mStopFetchingTime > MAX_HOLD_TIME)
  2026. {
  2027. mStopFetchingTime = gFrameTimeSeconds;
  2028. gTextureFetchp->updateRequestPriority(mID, decode_priority);
  2029. }
  2030. }
  2031. bool make_request = true;
  2032. if (decode_priority <= 0)
  2033. {
  2034. make_request = false;
  2035. }
  2036. else if (mDesiredDiscardLevel > getMaxDiscardLevel())
  2037. {
  2038. make_request = false;
  2039. }
  2040. else if (mNeedsCreateTexture || mIsMissingAsset)
  2041. {
  2042. make_request = false;
  2043. }
  2044. else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)
  2045. {
  2046. make_request = false;
  2047. }
  2048. else if (mCachedRawImage.notNull() && mCachedRawImageReady &&
  2049. (current_discard < 0 || current_discard > mCachedRawDiscardLevel))
  2050. {
  2051. make_request = false;
  2052. switchToCachedImage(); // Use the cached raw data first
  2053. }
  2054. #if 0
  2055. else if (!isJustBound() && mCachedRawImageReady)
  2056. {
  2057. make_request = false;
  2058. }
  2059. #endif
  2060. if (make_request)
  2061. {
  2062. if (mIsFetching)
  2063. {
  2064. if (mRequestedDiscardLevel <= desired_discard)
  2065. {
  2066. make_request = false;
  2067. }
  2068. }
  2069. else if (current_discard >= 0 && current_discard <= desired_discard)
  2070. {
  2071. make_request = false;
  2072. }
  2073. }
  2074. if (make_request)
  2075. {
  2076. mWasDeleted = false;
  2077. S32 w = 0, h = 0, c = 0;
  2078. if (getDiscardLevel() >= 0)
  2079. {
  2080. w = mImageGLp->getWidth(0);
  2081. h = mImageGLp->getHeight(0);
  2082. c = mComponents;
  2083. }
  2084. #if 0 // Not implemented in the Cool VL Viewer
  2085. static LLCachedControl<U32> override_discard(gSavedSettings,
  2086. "TextureDiscardLevel");
  2087. if (override_discard != 0)
  2088. {
  2089. desired_discard = override_discard;
  2090. }
  2091. #endif
  2092. // Bypass texturefetch directly by pulling from LLTextureCache
  2093. bool fetch_request_created =
  2094. gTextureFetchp->createRequest(mFTType, mUrl, getID(),
  2095. getTargetHost(), decode_priority,
  2096. w, h, c, desired_discard, needsAux(),
  2097. mCanUseHTTP);
  2098. if (fetch_request_created)
  2099. {
  2100. mHasFetcher = mIsFetching = true;
  2101. mRequestedDiscardLevel = desired_discard;
  2102. mFetchState =
  2103. gTextureFetchp->getFetchState(mID, mDownloadProgress,
  2104. mRequestedDownloadPriority,
  2105. mFetchPriority, mFetchDeltaTime,
  2106. mRequestDeltaTime, mCanUseHTTP);
  2107. }
  2108. // If createRequest() failed, either we are finishing up a request for
  2109. // this UUID and should wait for it to complete, or we have failed a
  2110. // request for this UUID and there is no need to create another.
  2111. }
  2112. else if (mHasFetcher && !mIsFetching)
  2113. {
  2114. // Only delete requests that do not have received any network data for
  2115. // a while
  2116. constexpr F32 FETCH_IDLE_TIME = 5.f;
  2117. if (gFrameTimeSeconds - mLastPacketTime > FETCH_IDLE_TIME)
  2118. {
  2119. LL_DEBUGS("ViewerTexture") << "Exceeded idle time. Deleting request for texture "
  2120. << mID << LL_ENDL;
  2121. gTextureFetchp->deleteRequest(mID);
  2122. mHasFetcher = false;
  2123. }
  2124. }
  2125. if (mRawImage.isNull() && (mNeedsCreateTexture || mIsRawImageValid))
  2126. {
  2127. llwarns << "Incoherent fetcher state for texture " << mID
  2128. << ": mRawImage is NULL while mNeedsCreateTexture is "
  2129. << mNeedsCreateTexture << " and mIsRawImageValid is "
  2130. << mIsRawImageValid << llendl;
  2131. llassert(false);
  2132. }
  2133. return mIsFetching;
  2134. }
  2135. void LLViewerFetchedTexture::clearFetchedResults()
  2136. {
  2137. if (mNeedsCreateTexture || mIsFetching)
  2138. {
  2139. return;
  2140. }
  2141. cleanup();
  2142. destroyGLTexture();
  2143. if (getDiscardLevel() >= 0) // Sculpty texture; force to invalidate
  2144. {
  2145. mImageGLp->forceToInvalidateGLTexture();
  2146. }
  2147. }
  2148. void LLViewerFetchedTexture::requestWasDeleted()
  2149. {
  2150. mWasDeleted = true;
  2151. resetTextureStats();
  2152. }
  2153. void LLViewerFetchedTexture::setIsMissingAsset(bool is_missing)
  2154. {
  2155. if (is_missing && mWasDeleted)
  2156. {
  2157. mWasDeleted = false;
  2158. LL_DEBUGS("ViewerTexture") << "Fetch request for texture " << mID
  2159. << " was deleted in flight. Not marking as missing asset."
  2160. << LL_ENDL;
  2161. return;
  2162. }
  2163. if (is_missing == mIsMissingAsset)
  2164. {
  2165. // No change
  2166. return;
  2167. }
  2168. if (is_missing)
  2169. {
  2170. #if LL_FIX_MAT_TRANSPARENCY
  2171. notifyAboutMissingAsset();
  2172. #endif
  2173. if (!LLTerrain::isAsset(mID)) // PBR terrain... HB
  2174. {
  2175. if (mUrl.empty())
  2176. {
  2177. llwarns << mID << ": Marking image as missing" << llendl;
  2178. }
  2179. // It is normal to have no map tile on an empty region, but bad if
  2180. // we are failing on a server bake texture.
  2181. else if (getFTType() != FTT_MAP_TILE)
  2182. {
  2183. llwarns << mUrl << ": Marking image as missing" << llendl;
  2184. }
  2185. }
  2186. if (mHasFetcher)
  2187. {
  2188. gTextureFetchp->deleteRequest(mID);
  2189. mHasFetcher = false;
  2190. mIsFetching = false;
  2191. mLastPacketTime = gFrameTimeSeconds;
  2192. mFetchState = 0;
  2193. mFetchPriority = 0;
  2194. }
  2195. }
  2196. else
  2197. {
  2198. llinfos << mID << ": un-flagging missing asset." << llendl;
  2199. }
  2200. mIsMissingAsset = is_missing;
  2201. }
  2202. void LLViewerFetchedTexture::setLoadedCallback(loaded_callback_func loaded_callback,
  2203. S32 discard_level,
  2204. bool keep_imageraw,
  2205. bool needs_aux,
  2206. void* userdata,
  2207. uuid_list_t* src_cb_list,
  2208. bool pause)
  2209. {
  2210. // Do not do ANYTHING here, just add it to the global callback list
  2211. if (mLoadedCallbackList.empty())
  2212. {
  2213. // Put in list to call this->doLoadedCallbacks() periodically
  2214. gTextureList.mCallbackList.insert(this);
  2215. mLoadedCallbackDesiredDiscardLevel = (S8)discard_level;
  2216. }
  2217. else
  2218. {
  2219. mLoadedCallbackDesiredDiscardLevel = llmin(mLoadedCallbackDesiredDiscardLevel,
  2220. (S8)discard_level);
  2221. }
  2222. if (mPauseLoadedCallBacks)
  2223. {
  2224. if (!pause)
  2225. {
  2226. unpauseLoadedCallbacks(src_cb_list);
  2227. }
  2228. }
  2229. else if (pause)
  2230. {
  2231. pauseLoadedCallbacks(src_cb_list);
  2232. }
  2233. LLLoadedCallbackEntry* entryp =
  2234. new LLLoadedCallbackEntry(loaded_callback, discard_level,
  2235. keep_imageraw, userdata,
  2236. src_cb_list, this, pause);
  2237. mLoadedCallbackList.push_back(entryp);
  2238. if (needs_aux)
  2239. {
  2240. mNeedsAux = true;
  2241. }
  2242. if (keep_imageraw)
  2243. {
  2244. mSaveRawImage = true;
  2245. }
  2246. if (mNeedsAux && mAuxRawImage.isNull() && getDiscardLevel() >= 0)
  2247. {
  2248. if (mHasAux)
  2249. {
  2250. // Trigger a refetch
  2251. forceToRefetchTexture();
  2252. }
  2253. else
  2254. {
  2255. // We need aux data but we have already loaded the image and it did
  2256. // not have any. This is a common case with cached baked textures,
  2257. // so make if an info message instead of a warning...
  2258. llinfos_once << "No aux data available for callback for image: "
  2259. << mID << llendl;
  2260. }
  2261. }
  2262. mLastCallBackActiveTime = sCurrentTime;
  2263. }
  2264. void LLViewerFetchedTexture::clearCallbackEntryList()
  2265. {
  2266. if (mLoadedCallbackList.empty())
  2267. {
  2268. return;
  2269. }
  2270. for (callback_list_t::iterator iter = mLoadedCallbackList.begin();
  2271. iter != mLoadedCallbackList.end(); )
  2272. {
  2273. LLLoadedCallbackEntry* entryp = *iter;
  2274. // We never finished loading the image. Indicate failure.
  2275. // Note: this allows mLoadedCallbackUserData to be cleaned up.
  2276. entryp->mCallback(false, this, NULL, NULL, 0, true, entryp->mUserData);
  2277. iter = mLoadedCallbackList.erase(iter);
  2278. delete entryp;
  2279. }
  2280. gTextureList.mCallbackList.erase(this);
  2281. mLoadedCallbackDesiredDiscardLevel = S8_MAX;
  2282. if (needsToSaveRawImage())
  2283. {
  2284. destroySavedRawImage();
  2285. }
  2286. }
  2287. void LLViewerFetchedTexture::deleteCallbackEntry(const uuid_list_t* cb_list)
  2288. {
  2289. if (mLoadedCallbackList.empty() || !cb_list)
  2290. {
  2291. return;
  2292. }
  2293. S32 desired_discard = S8_MAX;
  2294. S32 desired_raw_discard = INVALID_DISCARD_LEVEL;
  2295. for (callback_list_t::iterator iter = mLoadedCallbackList.begin();
  2296. iter != mLoadedCallbackList.end(); )
  2297. {
  2298. LLLoadedCallbackEntry *entryp = *iter;
  2299. if (entryp->mSourceCallbackList == cb_list)
  2300. {
  2301. // We never finished loading the image. Indicate failure.
  2302. // Note: this allows mLoadedCallbackUserData to be cleaned up.
  2303. entryp->mCallback(false, this, NULL, NULL, 0, true,
  2304. entryp->mUserData);
  2305. iter = mLoadedCallbackList.erase(iter);
  2306. delete entryp;
  2307. }
  2308. else
  2309. {
  2310. ++iter;
  2311. desired_discard = llmin(desired_discard, entryp->mDesiredDiscard);
  2312. if (entryp->mNeedsImageRaw)
  2313. {
  2314. desired_raw_discard = llmin(desired_raw_discard,
  2315. entryp->mDesiredDiscard);
  2316. }
  2317. }
  2318. }
  2319. mLoadedCallbackDesiredDiscardLevel = desired_discard;
  2320. if (mLoadedCallbackList.empty())
  2321. {
  2322. // If we have no callbacks, take us off of the image callback list.
  2323. gTextureList.mCallbackList.erase(this);
  2324. if (needsToSaveRawImage())
  2325. {
  2326. destroySavedRawImage();
  2327. }
  2328. }
  2329. else if (needsToSaveRawImage() &&
  2330. mBoostLevel != BOOST_PREVIEW)
  2331. {
  2332. if (desired_raw_discard != INVALID_DISCARD_LEVEL)
  2333. {
  2334. mDesiredSavedRawDiscardLevel = desired_raw_discard;
  2335. }
  2336. else
  2337. {
  2338. destroySavedRawImage();
  2339. }
  2340. }
  2341. }
  2342. void LLViewerFetchedTexture::unpauseLoadedCallbacks(const uuid_list_t* cb_list)
  2343. {
  2344. if (!cb_list)
  2345. {
  2346. mPauseLoadedCallBacks = false;
  2347. return;
  2348. }
  2349. bool need_raw = false;
  2350. for (callback_list_t::iterator iter = mLoadedCallbackList.begin(),
  2351. end = mLoadedCallbackList.end();
  2352. iter != end; ++iter)
  2353. {
  2354. LLLoadedCallbackEntry* entryp = *iter;
  2355. if (entryp->mSourceCallbackList == cb_list)
  2356. {
  2357. entryp->mPaused = false;
  2358. if (entryp->mNeedsImageRaw)
  2359. {
  2360. need_raw = true;
  2361. }
  2362. }
  2363. }
  2364. mPauseLoadedCallBacks = false;
  2365. mLastCallBackActiveTime = sCurrentTime;
  2366. mForceCallbackFetch = true;
  2367. if (need_raw)
  2368. {
  2369. mSaveRawImage = true;
  2370. }
  2371. }
  2372. void LLViewerFetchedTexture::pauseLoadedCallbacks(const uuid_list_t* cb_list)
  2373. {
  2374. if (!cb_list)
  2375. {
  2376. return;
  2377. }
  2378. bool paused = true;
  2379. for (callback_list_t::iterator iter = mLoadedCallbackList.begin(),
  2380. end = mLoadedCallbackList.end();
  2381. iter != end; )
  2382. {
  2383. LLLoadedCallbackEntry* entryp = *iter++;
  2384. if (entryp->mSourceCallbackList == cb_list)
  2385. {
  2386. entryp->mPaused = true;
  2387. }
  2388. else if (!entryp->mPaused)
  2389. {
  2390. paused = false;
  2391. }
  2392. }
  2393. if (paused)
  2394. {
  2395. mPauseLoadedCallBacks = true; // When set, loaded callback is paused.
  2396. resetTextureStats();
  2397. mSaveRawImage = false;
  2398. }
  2399. }
  2400. bool LLViewerFetchedTexture::doLoadedCallbacks()
  2401. {
  2402. constexpr F32 MAX_INACTIVE_TIME = 180.f; // In seconds
  2403. constexpr F32 MAX_IDLE_WAIT_TIME = 5.f; // In seconds
  2404. if (mNeedsCreateTexture)
  2405. {
  2406. return false;
  2407. }
  2408. if (mPauseLoadedCallBacks)
  2409. {
  2410. destroyRawImage();
  2411. return false; // Paused
  2412. }
  2413. if (!mIsFetching &&
  2414. sCurrentTime - mLastCallBackActiveTime > MAX_INACTIVE_TIME)
  2415. {
  2416. clearCallbackEntryList(); // Remove all callbacks.
  2417. return false;
  2418. }
  2419. bool res = false;
  2420. if (isMissingAsset())
  2421. {
  2422. for (callback_list_t::iterator iter = mLoadedCallbackList.begin();
  2423. iter != mLoadedCallbackList.end(); )
  2424. {
  2425. LLLoadedCallbackEntry* entryp = *iter++;
  2426. // We never finished loading the image. Indicate failure.
  2427. // Note: this allows mLoadedCallbackUserData to be cleaned up.
  2428. entryp->mCallback(false, this, NULL, NULL, 0, true,
  2429. entryp->mUserData);
  2430. delete entryp;
  2431. }
  2432. mLoadedCallbackList.clear();
  2433. // Remove ourself from the global list of textures with callbacks
  2434. gTextureList.mCallbackList.erase(this);
  2435. return false;
  2436. }
  2437. S32 gl_discard = getDiscardLevel();
  2438. // If we do not have a legit GL image, set it to be lower than the worst
  2439. // discard level
  2440. if (gl_discard == -1)
  2441. {
  2442. gl_discard = MAX_DISCARD_LEVEL + 1;
  2443. }
  2444. //
  2445. // Determine the quality levels of textures that we can provide to
  2446. // callbacks and whether we need to do decompression/readback to get it.
  2447. //
  2448. // We can always do a readback to get a raw discard:
  2449. S32 current_raw_discard = MAX_DISCARD_LEVEL + 1;
  2450. // Current GL quality level:
  2451. S32 best_raw_discard = gl_discard;
  2452. S32 current_aux_discard = MAX_DISCARD_LEVEL + 1;
  2453. S32 best_aux_discard = MAX_DISCARD_LEVEL + 1;
  2454. if (mIsRawImageValid)
  2455. {
  2456. // If we have an existing raw image, we have a baseline for the raw and
  2457. // auxiliary quality levels.
  2458. best_raw_discard = llmin(best_raw_discard, mRawDiscardLevel);
  2459. // We always decode the aux when we decode the base raw
  2460. best_aux_discard = llmin(best_aux_discard, mRawDiscardLevel);
  2461. current_aux_discard = llmin(current_aux_discard, best_aux_discard);
  2462. }
  2463. else
  2464. {
  2465. // We have no data at all, we need to get it. Do this by forcing the
  2466. // best aux discard to be 0.
  2467. best_aux_discard = 0;
  2468. }
  2469. // See if any of the callbacks would actually run using the data that we
  2470. // can provide, and also determine if we need to perform any readbacks or
  2471. // decodes.
  2472. bool run_gl_callbacks = false;
  2473. bool run_raw_callbacks = false;
  2474. bool need_readback = false;
  2475. for (callback_list_t::iterator iter = mLoadedCallbackList.begin();
  2476. iter != mLoadedCallbackList.end(); )
  2477. {
  2478. LLLoadedCallbackEntry* entryp = *iter++;
  2479. if (entryp->mNeedsImageRaw)
  2480. {
  2481. if (mNeedsAux)
  2482. {
  2483. // Need raw and auxiliary channels
  2484. if (entryp->mLastUsedDiscard > current_aux_discard)
  2485. {
  2486. // We have useful data, run the callbacks
  2487. run_raw_callbacks = true;
  2488. }
  2489. }
  2490. else if (entryp->mLastUsedDiscard > current_raw_discard)
  2491. {
  2492. // We have useful data, just run the callbacks
  2493. run_raw_callbacks = true;
  2494. }
  2495. else if (entryp->mLastUsedDiscard > best_raw_discard)
  2496. {
  2497. // We can readback data, and then run the callbacks
  2498. need_readback = true;
  2499. run_raw_callbacks = true;
  2500. }
  2501. }
  2502. // Needs just GL
  2503. else if (entryp->mLastUsedDiscard > gl_discard)
  2504. {
  2505. // We have enough data, run this callback requiring GL data
  2506. run_gl_callbacks = true;
  2507. }
  2508. }
  2509. // Do a readback if required, OR start off a texture decode
  2510. if (need_readback && getMaxDiscardLevel() > gl_discard)
  2511. {
  2512. // Do a readback to get the GL data into the raw image. We have GL
  2513. // data.
  2514. destroyRawImage();
  2515. reloadRawImage(mLoadedCallbackDesiredDiscardLevel);
  2516. if (mRawImage.isNull())
  2517. {
  2518. llwarns << "mRawImage is null. Removing callbacks."
  2519. << llendl;
  2520. clearCallbackEntryList();
  2521. mNeedsCreateTexture = mIsRawImageValid = false;
  2522. return false;
  2523. }
  2524. if (mNeedsAux && mAuxRawImage.isNull())
  2525. {
  2526. llwarns << "mAuxRawImage is null. Removing callbacks."
  2527. << llendl;
  2528. clearCallbackEntryList();
  2529. return false;
  2530. }
  2531. }
  2532. // Run raw/auxiliary data callbacks
  2533. if (run_raw_callbacks && mIsRawImageValid &&
  2534. mRawDiscardLevel <= getMaxDiscardLevel())
  2535. {
  2536. // Do callbacks which require raw image data; call each party
  2537. // interested in the raw data.
  2538. for (callback_list_t::iterator iter = mLoadedCallbackList.begin();
  2539. iter != mLoadedCallbackList.end(); )
  2540. {
  2541. callback_list_t::iterator curiter = iter++;
  2542. LLLoadedCallbackEntry* entryp = *curiter;
  2543. if (entryp->mNeedsImageRaw &&
  2544. entryp->mLastUsedDiscard > mRawDiscardLevel)
  2545. {
  2546. // If we have loaded all the data there is to load or we have
  2547. // loaded enough to satisfy the interested party, then this is
  2548. // the last time that we are going to call them.
  2549. mLastCallBackActiveTime = sCurrentTime;
  2550. if (mNeedsAux && mAuxRawImage.isNull())
  2551. {
  2552. // This is a very common and normal case for baked
  2553. // textures, so let's make it a llinfos instead of a
  2554. // llwarns... HB
  2555. llinfos << "Raw Image with no Aux Data for callback"
  2556. << llendl;
  2557. }
  2558. bool is_final = mRawDiscardLevel <= entryp->mDesiredDiscard;
  2559. entryp->mLastUsedDiscard = mRawDiscardLevel;
  2560. entryp->mCallback(true, this, mRawImage, mAuxRawImage,
  2561. mRawDiscardLevel, is_final,
  2562. entryp->mUserData);
  2563. if (is_final)
  2564. {
  2565. iter = mLoadedCallbackList.erase(curiter);
  2566. delete entryp;
  2567. }
  2568. res = true;
  2569. }
  2570. }
  2571. }
  2572. // Run GL callbacks
  2573. if (run_gl_callbacks && gl_discard <= getMaxDiscardLevel())
  2574. {
  2575. // Call the callbacks interested in GL data.
  2576. for (callback_list_t::iterator iter = mLoadedCallbackList.begin();
  2577. iter != mLoadedCallbackList.end(); )
  2578. {
  2579. callback_list_t::iterator curiter = iter++;
  2580. LLLoadedCallbackEntry* entryp = *curiter;
  2581. if (!entryp->mNeedsImageRaw &&
  2582. entryp->mLastUsedDiscard > gl_discard)
  2583. {
  2584. mLastCallBackActiveTime = sCurrentTime;
  2585. bool is_final = gl_discard <= entryp->mDesiredDiscard;
  2586. entryp->mLastUsedDiscard = gl_discard;
  2587. entryp->mCallback(true, this, NULL, NULL, gl_discard, is_final,
  2588. entryp->mUserData);
  2589. if (is_final)
  2590. {
  2591. iter = mLoadedCallbackList.erase(curiter);
  2592. delete entryp;
  2593. }
  2594. res = true;
  2595. }
  2596. }
  2597. }
  2598. // Done with any raw image data at this point (will be re-created if we
  2599. // still have callbacks)
  2600. destroyRawImage();
  2601. // If we have no callback, take us off of the image callback list.
  2602. if (mLoadedCallbackList.empty())
  2603. {
  2604. gTextureList.mCallbackList.erase(this);
  2605. }
  2606. else if (!res && !mIsFetching && mForceCallbackFetch &&
  2607. sCurrentTime - mLastCallBackActiveTime > MAX_IDLE_WAIT_TIME)
  2608. {
  2609. // Waited for long enough but no fetching request issued, force one.
  2610. forceToRefetchTexture(mLoadedCallbackDesiredDiscardLevel, 5.f);
  2611. mForceCallbackFetch = false;
  2612. }
  2613. return res;
  2614. }
  2615. //virtual
  2616. void LLViewerFetchedTexture::forceImmediateUpdate()
  2617. {
  2618. // Only immediately update a deleted texture which is now being re-used.
  2619. if (!isDeleted())
  2620. {
  2621. return;
  2622. }
  2623. // If already called forceImmediateUpdate()
  2624. if (mInImageList && mDecodePriority == MAX_DECODE_PRIORITY)
  2625. {
  2626. return;
  2627. }
  2628. gTextureList.forceImmediateUpdate(this);
  2629. }
  2630. LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level)
  2631. {
  2632. llassert_always(mImageGLp.notNull() && discard_level >= 0 &&
  2633. mComponents > 0);
  2634. if (mRawImage.notNull())
  2635. {
  2636. // mRawImage is in use by somebody else, do not delete it.
  2637. return NULL;
  2638. }
  2639. if (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level)
  2640. {
  2641. if (mSavedRawDiscardLevel != discard_level)
  2642. {
  2643. mRawImage = new LLImageRaw(getWidth(discard_level),
  2644. getHeight(discard_level),
  2645. getComponents());
  2646. if (mRawImage)
  2647. {
  2648. mRawImage->copy(getSavedRawImage());
  2649. mRawDiscardLevel = discard_level;
  2650. }
  2651. else
  2652. {
  2653. llwarns << "Cannot create a new raw image (out of memory ?)"
  2654. << llendl;
  2655. mRawImage = getSavedRawImage();
  2656. mRawDiscardLevel = mSavedRawDiscardLevel;
  2657. }
  2658. }
  2659. else
  2660. {
  2661. mRawImage = getSavedRawImage();
  2662. mRawDiscardLevel = discard_level;
  2663. }
  2664. }
  2665. else if (mCachedRawDiscardLevel >= discard_level)
  2666. {
  2667. mRawImage = mCachedRawImage;
  2668. mRawDiscardLevel = mCachedRawDiscardLevel;
  2669. }
  2670. else // Cached raw image is good enough, copy it.
  2671. {
  2672. mRawImage = new LLImageRaw(getWidth(discard_level),
  2673. getHeight(discard_level),
  2674. getComponents());
  2675. if (mRawImage)
  2676. {
  2677. mRawImage->copy(mCachedRawImage);
  2678. mRawDiscardLevel = discard_level;
  2679. }
  2680. else
  2681. {
  2682. llwarns << "Cannot create a new raw image (out of memory ?)"
  2683. << llendl;
  2684. mRawImage = mCachedRawImage;
  2685. mRawDiscardLevel = mCachedRawDiscardLevel;
  2686. }
  2687. }
  2688. mIsRawImageValid = true;
  2689. ++sRawCount;
  2690. return mRawImage;
  2691. }
  2692. void LLViewerFetchedTexture::destroyRawImage()
  2693. {
  2694. if (mAuxRawImage.notNull())
  2695. {
  2696. --sAuxCount;
  2697. mAuxRawImage = NULL;
  2698. }
  2699. if (mRawImage.notNull())
  2700. {
  2701. --sRawCount;
  2702. if (mIsRawImageValid)
  2703. {
  2704. if (needsToSaveRawImage())
  2705. {
  2706. saveRawImage();
  2707. }
  2708. setCachedRawImage();
  2709. }
  2710. }
  2711. mRawImage = NULL;
  2712. mIsRawImageValid = false;
  2713. mRawDiscardLevel = INVALID_DISCARD_LEVEL;
  2714. }
  2715. // Use the mCachedRawImage to (re)generate the GL texture.
  2716. //virtual
  2717. void LLViewerFetchedTexture::switchToCachedImage()
  2718. {
  2719. // Note: we test for !mNeedsCreateTexture so that if a creation is pending
  2720. // we do not step on it.
  2721. if (!mNeedsCreateTexture && mCachedRawImage.notNull())
  2722. {
  2723. mRawImage = mCachedRawImage;
  2724. if (getComponents() != mRawImage->getComponents())
  2725. {
  2726. // We have changed the number of components, so we need to move any
  2727. // object using this pool to a different pool.
  2728. mComponents = mRawImage->getComponents();
  2729. mImageGLp->setComponents(mComponents);
  2730. gTextureList.dirtyImage(this);
  2731. }
  2732. mIsRawImageValid = true;
  2733. mRawDiscardLevel = mCachedRawDiscardLevel;
  2734. scheduleCreateTexture();
  2735. }
  2736. }
  2737. // Cache the imageraw forcefully.
  2738. //virtual
  2739. void LLViewerFetchedTexture::setCachedRawImage(S32 discard, LLImageRaw* rawp)
  2740. {
  2741. if (rawp != mRawImage.get())
  2742. {
  2743. mCachedRawImage = rawp;
  2744. mCachedRawDiscardLevel = discard;
  2745. mCachedRawImageReady = true;
  2746. }
  2747. }
  2748. void LLViewerFetchedTexture::setCachedRawImage()
  2749. {
  2750. if (mRawImage == mCachedRawImage || !mIsRawImageValid ||
  2751. mCachedRawImageReady)
  2752. {
  2753. return;
  2754. }
  2755. if (mCachedRawDiscardLevel < 0 ||
  2756. mCachedRawDiscardLevel > mRawDiscardLevel)
  2757. {
  2758. S32 i = 0;
  2759. S32 w = mRawImage->getWidth();
  2760. S32 h = mRawImage->getHeight();
  2761. S32 max_size = MAX_CACHED_RAW_IMAGE_AREA;
  2762. if (mBoostLevel == BOOST_TERRAIN)
  2763. {
  2764. max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA;
  2765. }
  2766. if (mForSculpt)
  2767. {
  2768. max_size = MAX_CACHED_RAW_SCULPT_IMAGE_AREA;
  2769. mCachedRawImageReady = !mRawDiscardLevel;
  2770. }
  2771. else
  2772. {
  2773. mCachedRawImageReady = !mRawDiscardLevel || w * h >= max_size;
  2774. }
  2775. while ((w >> i) * (h >> i) > max_size)
  2776. {
  2777. ++i;
  2778. }
  2779. if (i)
  2780. {
  2781. if (!(w >> i) || !(h >> i))
  2782. {
  2783. --i;
  2784. }
  2785. if (mRawImage->getComponents() == 5)
  2786. {
  2787. llwarns << "Trying to scale an image (" << mID
  2788. << ") with 5 components !" << llendl;
  2789. mIsRawImageValid = false;
  2790. return;
  2791. }
  2792. // Make a duplicate in case somebody else is using this raw image:
  2793. LLPointer<LLImageRaw> dup = mRawImage->scaled(w >> i, h >> i);
  2794. if (dup.notNull())
  2795. {
  2796. mRawImage = std::move(dup);
  2797. }
  2798. }
  2799. mCachedRawImage = mRawImage;
  2800. mRawDiscardLevel += i;
  2801. mCachedRawDiscardLevel = mRawDiscardLevel;
  2802. }
  2803. }
  2804. void LLViewerFetchedTexture::checkCachedRawSculptImage()
  2805. {
  2806. if (mCachedRawImageReady && mCachedRawDiscardLevel > 0)
  2807. {
  2808. if (getDiscardLevel() != 0)
  2809. {
  2810. mCachedRawImageReady = false;
  2811. }
  2812. else if (isForSculptOnly())
  2813. {
  2814. resetTextureStats(); // Do not update this image any more.
  2815. }
  2816. }
  2817. }
  2818. void LLViewerFetchedTexture::saveRawImage()
  2819. {
  2820. if (mRawImage.isNull() || mRawImage == mSavedRawImage ||
  2821. (mSavedRawDiscardLevel >= 0 &&
  2822. mSavedRawDiscardLevel <= mRawDiscardLevel))
  2823. {
  2824. return;
  2825. }
  2826. // This should not happen, but it did on Snowglobe 1.5. Better safe than
  2827. // sorry...
  2828. if (!mRawImage->getData())
  2829. {
  2830. llwarns << "mRawImage->getData() returns NULL" << llendl;
  2831. return;
  2832. }
  2833. mSavedRawDiscardLevel = mRawDiscardLevel;
  2834. mSavedRawImage = new LLImageRaw(mRawImage->getData(),
  2835. mRawImage->getWidth(),
  2836. mRawImage->getHeight(),
  2837. mRawImage->getComponents());
  2838. if (mForceToSaveRawImage &&
  2839. mSavedRawDiscardLevel <= mDesiredSavedRawDiscardLevel)
  2840. {
  2841. mForceToSaveRawImage = false;
  2842. }
  2843. mLastReferencedSavedRawImageTime = sCurrentTime;
  2844. }
  2845. void LLViewerFetchedTexture::forceToSaveRawImage(S32 desired_discard, F32 kept_time)
  2846. {
  2847. mKeptSavedRawImageTime = kept_time;
  2848. mLastReferencedSavedRawImageTime = sCurrentTime;
  2849. if (mSavedRawDiscardLevel > -1 && mSavedRawDiscardLevel <= desired_discard)
  2850. {
  2851. return; // Raw image is ready.
  2852. }
  2853. if (!mForceToSaveRawImage || mDesiredSavedRawDiscardLevel < 0 ||
  2854. mDesiredSavedRawDiscardLevel > desired_discard)
  2855. {
  2856. mForceToSaveRawImage = true;
  2857. mDesiredSavedRawDiscardLevel = desired_discard;
  2858. // Copy from the cached raw image if exists.
  2859. if (mCachedRawImage.notNull() && mRawImage.isNull())
  2860. {
  2861. mRawImage = mCachedRawImage;
  2862. mRawDiscardLevel = mCachedRawDiscardLevel;
  2863. saveRawImage();
  2864. mRawImage = NULL;
  2865. mRawDiscardLevel = INVALID_DISCARD_LEVEL;
  2866. }
  2867. }
  2868. }
  2869. void LLViewerFetchedTexture::destroySavedRawImage()
  2870. {
  2871. if (mLastReferencedSavedRawImageTime < mKeptSavedRawImageTime)
  2872. {
  2873. return; // Keep the saved raw image.
  2874. }
  2875. mForceToSaveRawImage = mSaveRawImage = false;
  2876. clearCallbackEntryList();
  2877. mSavedRawImage = NULL;
  2878. mForceToSaveRawImage = mSaveRawImage = false;
  2879. mSavedRawDiscardLevel = mDesiredSavedRawDiscardLevel = -1;
  2880. mLastReferencedSavedRawImageTime = mKeptSavedRawImageTime = 0.f;
  2881. }
  2882. LLImageRaw* LLViewerFetchedTexture::getSavedRawImage()
  2883. {
  2884. mLastReferencedSavedRawImageTime = sCurrentTime;
  2885. return mSavedRawImage;
  2886. }
  2887. F32 LLViewerFetchedTexture::getElapsedLastReferencedSavedRawImageTime() const
  2888. {
  2889. return sCurrentTime - mLastReferencedSavedRawImageTime;
  2890. }
  2891. // Forces to refetch the texture to the discard level
  2892. void LLViewerFetchedTexture::forceToRefetchTexture(S32 desired_discard,
  2893. F32 kept_time)
  2894. {
  2895. if (mForceToSaveRawImage)
  2896. {
  2897. desired_discard = llmin(desired_discard, mDesiredSavedRawDiscardLevel);
  2898. kept_time = llmax(kept_time, mKeptSavedRawImageTime);
  2899. }
  2900. // Trigger a new fetch
  2901. mForceToSaveRawImage = true;
  2902. mDesiredSavedRawDiscardLevel = desired_discard;
  2903. mKeptSavedRawImageTime = kept_time;
  2904. mLastReferencedSavedRawImageTime = sCurrentTime;
  2905. mSavedRawImage = NULL;
  2906. mSavedRawDiscardLevel = -1;
  2907. }
  2908. // This method is a hack to allow reloading manually staled, blurry (i.e.
  2909. // corrupted in cache), or "missing" textures. HB
  2910. void LLViewerFetchedTexture::forceRefetch()
  2911. {
  2912. if (mFTType == FTT_LOCAL_FILE)
  2913. {
  2914. // Cannot "fetch" a file, just reload it. HB
  2915. // *TODO: allow reloading textures on file.
  2916. return;
  2917. }
  2918. // Remove the cache entry
  2919. gTextureCachep->removeFromCache(getID());
  2920. S32 current_discard = getDiscardLevel();
  2921. S32 w = 0, h = 0, c = 0;
  2922. if (current_discard >= 0)
  2923. {
  2924. w = getWidth(0);
  2925. h = getHeight(0);
  2926. c = getComponents();
  2927. }
  2928. if (mHasFetcher)
  2929. {
  2930. gTextureFetchp->deleteRequest(getID());
  2931. }
  2932. cleanup();
  2933. mIsMissingAsset = mWasDeleted = false;
  2934. mDesiredSavedRawDiscardLevel = 0;
  2935. if (mImageGLp)
  2936. {
  2937. mImageGLp->forceToInvalidateGLTexture();
  2938. }
  2939. bool success = gTextureFetchp->createRequest(mFTType, mUrl, getID(),
  2940. getTargetHost(),
  2941. MAX_DECODE_PRIORITY, w, h, c,
  2942. mDesiredSavedRawDiscardLevel,
  2943. needsAux(), mCanUseHTTP);
  2944. if (!success)
  2945. {
  2946. return;
  2947. }
  2948. mHasFetcher = mIsFetching = true;
  2949. gTextureList.forceImmediateUpdate(this);
  2950. mRequestedDiscardLevel = mDesiredSavedRawDiscardLevel;
  2951. mFetchState = gTextureFetchp->getFetchState(mID, mDownloadProgress,
  2952. mRequestedDownloadPriority,
  2953. mFetchPriority,
  2954. mFetchDeltaTime,
  2955. mRequestDeltaTime,
  2956. mCanUseHTTP);
  2957. }
  2958. //-----------------------------------------------------------------------------
  2959. // LLViewerLODTexture
  2960. //-----------------------------------------------------------------------------
  2961. LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, FTType f_type,
  2962. const LLHost& host, bool usemipmaps)
  2963. : LLViewerFetchedTexture(id, f_type, host, usemipmaps)
  2964. {
  2965. init(true);
  2966. }
  2967. LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type,
  2968. const LLUUID& id, bool usemipmaps)
  2969. : LLViewerFetchedTexture(url, f_type, id, usemipmaps)
  2970. {
  2971. init(true);
  2972. }
  2973. void LLViewerLODTexture::init(bool firstinit)
  2974. {
  2975. mTexelsPerImage = 64 * 64;
  2976. mDiscardVirtualSize = 0.f;
  2977. mCalculatedDiscardLevel = -1.f;
  2978. }
  2979. //virtual
  2980. S8 LLViewerLODTexture::getType() const
  2981. {
  2982. return LLViewerTexture::LOD_TEXTURE;
  2983. }
  2984. // This is guaranteed to get called periodically for every texture
  2985. //virtual
  2986. void LLViewerLODTexture::processTextureStats()
  2987. {
  2988. updateVirtualSize();
  2989. // Restrict texture resolution to download based on user settings: level 0
  2990. // is 512x512, level 1 is 1024x1024, level 2 is 2048x2048.
  2991. static LLCachedControl<U32> level(gSavedSettings, "TextureMaxResLevel");
  2992. U32 max_size = 1024; // Default.
  2993. if ((level > 1 || mIsMegaTexture) && gMaxImageSizeDefault > 1024)
  2994. {
  2995. max_size = 2048;
  2996. }
  2997. else if (level == 0)
  2998. {
  2999. max_size = 512;
  3000. }
  3001. mMaxVirtualSize = llmin(mMaxVirtualSize, max_size * max_size);
  3002. static LLCachedControl<bool> textures_fullres(gSavedSettings,
  3003. "TextureLoadFullRes");
  3004. static LLCachedControl<U32> min_vsize_discard(gSavedSettings,
  3005. "TextureMinVirtualSizeDiscard");
  3006. F32 min_virtual_size = llmax((F32)min_vsize_discard, 10.f);
  3007. if (textures_fullres)
  3008. {
  3009. mDesiredDiscardLevel = 0;
  3010. }
  3011. // Generate the request priority and render priority
  3012. else if (mDontDiscard || !mUseMipMaps)
  3013. {
  3014. mDesiredDiscardLevel = getMinDiscardLevel();
  3015. }
  3016. else if (mBoostLevel == BOOST_ALM && !LLPipeline::sRenderDeferred)
  3017. {
  3018. mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
  3019. }
  3020. else if (mBoostLevel < BOOST_HIGH && mMaxVirtualSize <= min_virtual_size)
  3021. {
  3022. // If the image has not been significantly visible in a while, we do
  3023. // not want it
  3024. mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,
  3025. MAX_DISCARD_LEVEL + 1);
  3026. }
  3027. else if (!mFullWidth || !mFullHeight)
  3028. {
  3029. mDesiredDiscardLevel = getMaxDiscardLevel();
  3030. }
  3031. else
  3032. {
  3033. static const F32 inv_log_4 = 1.f / logf(4.f);
  3034. F32 discard_level = 0.f;
  3035. // If we know the output width and height, we can force the discard
  3036. // level to the correct value, and thus not decode more texture
  3037. // data than we need to.
  3038. if (mKnownDrawWidth && mKnownDrawHeight)
  3039. {
  3040. F32 draw_texels = llclamp(mKnownDrawWidth * mKnownDrawHeight,
  3041. MIN_IMAGE_AREA, max_size * max_size);
  3042. // Use log_4 because we are in square-pixel space, so an image with
  3043. // twice the width and twice the height will have mTexelsPerImage =
  3044. // 4 * draw_size
  3045. discard_level = logf(F32(mTexelsPerImage) / draw_texels) *
  3046. inv_log_4;
  3047. }
  3048. else
  3049. {
  3050. #if 1
  3051. if (isLargeImage() && !isJustBound() &&
  3052. mAdditionalDecodePriority < 0.3f)
  3053. {
  3054. // If it is a big image and not being used recently, nor close
  3055. // to the view point, do not load hi-res data.
  3056. mMaxVirtualSize =
  3057. llmin(mMaxVirtualSize,
  3058. (F32)LLViewerTexture::sMinLargeImageSize);
  3059. }
  3060. #endif
  3061. #if 0
  3062. if (mCalculatedDiscardLevel >= 0.f &&
  3063. fabsf(mMaxVirtualSize - mDiscardVirtualSize) <
  3064. mMaxVirtualSize * 0.2f)
  3065. {
  3066. // < 20% change in virtual size = no change in desired discard
  3067. discard_level = mCalculatedDiscardLevel;
  3068. }
  3069. else
  3070. #endif
  3071. {
  3072. // Calculate the required scale factor of the image using pixels
  3073. // per texel
  3074. discard_level = logf(mTexelsPerImage / mMaxVirtualSize) *
  3075. inv_log_4;
  3076. mDiscardVirtualSize = mMaxVirtualSize;
  3077. mCalculatedDiscardLevel = discard_level;
  3078. }
  3079. }
  3080. if (mBoostLevel < BOOST_HIGH)
  3081. {
  3082. constexpr F32 BIAS_SCALE = 1.1f;
  3083. discard_level += sDesiredDiscardBias;
  3084. discard_level *= BIAS_SCALE;
  3085. }
  3086. discard_level = floorf(discard_level);
  3087. F32 min_discard = getMinDiscardLevel();
  3088. discard_level = llclamp(discard_level, min_discard,
  3089. (F32)MAX_DISCARD_LEVEL);
  3090. // Cannot go higher than the max discard level
  3091. mDesiredDiscardLevel = llmin(getMaxDiscardLevel() + 1,
  3092. (S32)discard_level);
  3093. // Clamp to min desired discard
  3094. mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,
  3095. mDesiredDiscardLevel);
  3096. // At this point we have calculated the quality level that we want, if
  3097. // possible. Now we check to see if we have it and take the proper
  3098. // action if we do not.
  3099. S32 current_discard = getDiscardLevel();
  3100. if (sDesiredDiscardBias > 0.f && current_discard >= 0 &&
  3101. mBoostLevel < BOOST_HIGH)
  3102. {
  3103. static LLCachedControl<F32> lower_bound(gSavedSettings,
  3104. "TexMemLowerBoundScale");
  3105. F32 texmem_middle_bound_scale =
  3106. 1.f - (1.f - llclamp((F32)lower_bound, 0.75f, 0.9f)) * 0.75f;
  3107. if (!mForceToSaveRawImage &&
  3108. sDesiredDiscardBias >= DESIRED_DISCARD_BIAS_MAX)
  3109. {
  3110. // We need to release texture memory urgently
  3111. scaleDown();
  3112. }
  3113. else if (sBoundTexMemoryMB >
  3114. sMaxBoundTexMemMB * texmem_middle_bound_scale
  3115. && (!getBoundRecently() ||
  3116. mDesiredDiscardLevel >= mCachedRawDiscardLevel))
  3117. {
  3118. // Limit the amount of GL memory bound each frame
  3119. scaleDown();
  3120. }
  3121. else if (sTotalTexMemoryMB >
  3122. sMaxTotalTexMemMB * texmem_middle_bound_scale
  3123. && (!getBoundRecently() ||
  3124. mDesiredDiscardLevel >= mCachedRawDiscardLevel))
  3125. {
  3126. // Only allow GL to have 2x the video card memory
  3127. scaleDown();
  3128. }
  3129. }
  3130. }
  3131. if (mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0)
  3132. {
  3133. mDesiredDiscardLevel = llmin(mDesiredDiscardLevel,
  3134. (S8)mDesiredSavedRawDiscardLevel);
  3135. }
  3136. }
  3137. bool LLViewerLODTexture::scaleDown()
  3138. {
  3139. if (hasGLTexture() && mCachedRawDiscardLevel > getDiscardLevel())
  3140. {
  3141. switchToCachedImage();
  3142. return true;
  3143. }
  3144. return false;
  3145. }
  3146. //-----------------------------------------------------------------------------
  3147. // LLViewerMediaTexture
  3148. //-----------------------------------------------------------------------------
  3149. //static
  3150. void LLViewerMediaTexture::updateClass()
  3151. {
  3152. static LLCachedControl<U32> lazy_flush_timeout(gSavedSettings,
  3153. "TextureLazyFlushTimeout");
  3154. F32 max_inactive_time = llmax((F32)(lazy_flush_timeout / 2), 5.f);
  3155. #if 0
  3156. // Force to play media.
  3157. gSavedSettings.setBool("EnableStreamingMedia", true);
  3158. #endif
  3159. for (media_map_t::iterator iter = sMediaMap.begin(), end = sMediaMap.end();
  3160. iter != end; )
  3161. {
  3162. media_map_t::iterator cur = iter++;
  3163. LLViewerMediaTexture* mediap = cur->second.get();
  3164. if (mediap && mediap->getNumRefs() == 1) // one reference by sMediaMap
  3165. {
  3166. // Delay some time to delete the media textures to stop endlessly
  3167. // creating and immediately removing media texture.
  3168. if (mediap->getElapsedLastReferenceTime() > max_inactive_time)
  3169. {
  3170. sMediaMap.erase(cur);
  3171. }
  3172. }
  3173. }
  3174. }
  3175. //static
  3176. void LLViewerMediaTexture::removeMediaImplFromTexture(const LLUUID& media_id)
  3177. {
  3178. LLViewerMediaTexture* media_tex = findMediaTexture(media_id);
  3179. if (media_tex)
  3180. {
  3181. media_tex->invalidateMediaImpl();
  3182. }
  3183. }
  3184. //static
  3185. void LLViewerMediaTexture::cleanUpClass()
  3186. {
  3187. sMediaMap.clear();
  3188. }
  3189. //static
  3190. LLViewerMediaTexture* LLViewerMediaTexture::findMediaTexture(const LLUUID& media_id)
  3191. {
  3192. media_map_t::iterator iter = sMediaMap.find(media_id);
  3193. if (iter == sMediaMap.end())
  3194. {
  3195. return NULL;
  3196. }
  3197. LLViewerMediaTexture* media_tex = iter->second.get();
  3198. if (media_tex)
  3199. {
  3200. media_tex->setMediaImpl();
  3201. media_tex->resetLastReferencedTime();
  3202. }
  3203. return media_tex;
  3204. }
  3205. LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, bool usemipmaps,
  3206. LLImageGL* gl_image)
  3207. : LLViewerTexture(id, usemipmaps),
  3208. mMediaImplp(NULL),
  3209. mUpdateVirtualSizeTime(0)
  3210. {
  3211. sMediaMap[id] = this;
  3212. mImageGLp = gl_image;
  3213. if (mImageGLp.isNull())
  3214. {
  3215. generateGLTexture();
  3216. }
  3217. mImageGLp->setAllowCompression(false);
  3218. mImageGLp->setNeedsAlphaAndPickMask(false);
  3219. mIsPlaying = false;
  3220. setMediaImpl();
  3221. setBoostLevel(BOOST_MEDIA);
  3222. LLViewerTexture* tex = gTextureList.findImage(mID);
  3223. if (tex)
  3224. {
  3225. // This media is a parcel media for tex.
  3226. tex->setParcelMedia(this);
  3227. }
  3228. }
  3229. //virtual
  3230. LLViewerMediaTexture::~LLViewerMediaTexture()
  3231. {
  3232. LLViewerTexture* tex = gTextureList.findImage(mID);
  3233. if (tex)
  3234. {
  3235. // This media is a parcel media for tex.
  3236. tex->setParcelMedia(NULL);
  3237. }
  3238. }
  3239. void LLViewerMediaTexture::reinit(bool usemipmaps)
  3240. {
  3241. mUseMipMaps = usemipmaps;
  3242. resetLastReferencedTime();
  3243. if (mImageGLp.notNull())
  3244. {
  3245. mImageGLp->setUseMipMaps(usemipmaps);
  3246. mImageGLp->setNeedsAlphaAndPickMask(false);
  3247. }
  3248. }
  3249. void LLViewerMediaTexture::setUseMipMaps(bool mipmap)
  3250. {
  3251. mUseMipMaps = mipmap;
  3252. if (mImageGLp.notNull())
  3253. {
  3254. mImageGLp->setUseMipMaps(mipmap);
  3255. }
  3256. }
  3257. //virtual
  3258. S8 LLViewerMediaTexture::getType() const
  3259. {
  3260. return LLViewerTexture::MEDIA_TEXTURE;
  3261. }
  3262. void LLViewerMediaTexture::invalidateMediaImpl()
  3263. {
  3264. mMediaImplp = NULL;
  3265. }
  3266. void LLViewerMediaTexture::setMediaImpl()
  3267. {
  3268. if (!mMediaImplp)
  3269. {
  3270. mMediaImplp = LLViewerMedia::getMediaImplFromTextureID(mID);
  3271. }
  3272. }
  3273. // Return true if all faces to reference to this media texture are found
  3274. // Note: mMediaFaceList is valid only for the current instant because it does
  3275. // not check the face validity after the current frame.
  3276. bool LLViewerMediaTexture::findFaces()
  3277. {
  3278. mMediaFaceList.clear();
  3279. bool ret = true;
  3280. LLViewerTexture* tex = gTextureList.findImage(mID);
  3281. if (tex)
  3282. {
  3283. // This media is a parcel media for tex.
  3284. for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
  3285. {
  3286. const ll_face_list_t* face_list = tex->getFaceList(ch);
  3287. U32 end = tex->getNumFaces(ch);
  3288. for (U32 i = 0; i < end; ++i)
  3289. {
  3290. LLFace* facep = (*face_list)[i];
  3291. if (facep->isMediaAllowed())
  3292. {
  3293. mMediaFaceList.push_back((*face_list)[i]);
  3294. }
  3295. }
  3296. }
  3297. }
  3298. if (!mMediaImplp)
  3299. {
  3300. return true;
  3301. }
  3302. // For media on a face.
  3303. const std::list<LLVOVolume*>* obj_list = mMediaImplp->getObjectList();
  3304. for (std::list<LLVOVolume*>::const_iterator iter = obj_list->begin(),
  3305. end = obj_list->end();
  3306. iter != end; ++iter)
  3307. {
  3308. LLVOVolume* obj = *iter;
  3309. if (obj->mDrawable.isNull())
  3310. {
  3311. ret = false;
  3312. continue;
  3313. }
  3314. S32 face_id = -1;
  3315. S32 num_faces = obj->mDrawable->getNumFaces();
  3316. while ((face_id = obj->getFaceIndexWithMediaImpl(mMediaImplp,
  3317. face_id)) > -1 &&
  3318. face_id < num_faces)
  3319. {
  3320. LLFace* facep = obj->mDrawable->getFace(face_id);
  3321. if (facep)
  3322. {
  3323. mMediaFaceList.push_back(facep);
  3324. }
  3325. else
  3326. {
  3327. ret = false;
  3328. }
  3329. }
  3330. }
  3331. return ret;
  3332. }
  3333. void LLViewerMediaTexture::initVirtualSize()
  3334. {
  3335. if (mIsPlaying)
  3336. {
  3337. return;
  3338. }
  3339. findFaces();
  3340. for (std::list<LLFace*>::iterator iter = mMediaFaceList.begin(),
  3341. end = mMediaFaceList.end();
  3342. iter != end; ++iter)
  3343. {
  3344. addTextureStats((*iter)->getVirtualSize());
  3345. }
  3346. }
  3347. void LLViewerMediaTexture::addMediaToFace(LLFace* facep)
  3348. {
  3349. if (facep)
  3350. {
  3351. facep->setHasMedia(true);
  3352. }
  3353. if (!mIsPlaying)
  3354. {
  3355. // No need to remove the face because the media is not playing.
  3356. return;
  3357. }
  3358. switchTexture(LLRender::DIFFUSE_MAP, facep);
  3359. }
  3360. void LLViewerMediaTexture::removeMediaFromFace(LLFace* facep)
  3361. {
  3362. if (!facep)
  3363. {
  3364. return;
  3365. }
  3366. facep->setHasMedia(false);
  3367. if (!mIsPlaying)
  3368. {
  3369. // No need to remove the face because the media is not playing.
  3370. return;
  3371. }
  3372. mIsPlaying = false; // Set to remove the media from the face.
  3373. switchTexture(LLRender::DIFFUSE_MAP, facep);
  3374. mIsPlaying = true; // Set the flag back.
  3375. if (getTotalNumFaces() < 1) // No face referencing to this media
  3376. {
  3377. stopPlaying();
  3378. }
  3379. }
  3380. //virtual
  3381. void LLViewerMediaTexture::addFace(U32 ch, LLFace* facep)
  3382. {
  3383. LLViewerTexture::addFace(ch, facep);
  3384. const LLTextureEntry* te = facep->getTextureEntry();
  3385. if (te && te->getID().notNull())
  3386. {
  3387. LLViewerTexture* tex = gTextureList.findImage(te->getID());
  3388. if (tex)
  3389. {
  3390. // Increase the reference number by one for tex to avoid deleting
  3391. // it.
  3392. mTextureList.push_back(tex);
  3393. return;
  3394. }
  3395. }
  3396. // Check if it is a parcel media
  3397. if (facep->getTexture() && facep->getTexture() != this &&
  3398. facep->getTexture()->getID() == mID)
  3399. {
  3400. mTextureList.push_back(facep->getTexture()); // A parcel media.
  3401. }
  3402. // Note: there was a llerrs here, that crashed when the texture was not
  3403. // found in gTextureList, but this is a normal occurrence now (i.e. the
  3404. // texture could have just been pushed in the creation queue and thus not
  3405. // yet present in gTextureList). HB
  3406. }
  3407. //virtual
  3408. void LLViewerMediaTexture::removeFace(U32 ch, LLFace* facep)
  3409. {
  3410. LLViewerTexture::removeFace(ch, facep);
  3411. const LLTextureEntry* te = facep->getTextureEntry();
  3412. if (te && te->getID().notNull())
  3413. {
  3414. LLViewerTexture* tex = gTextureList.findImage(te->getID());
  3415. if (tex)
  3416. {
  3417. for (std::list<LLPointer<LLViewerTexture> >::iterator
  3418. iter = mTextureList.begin();
  3419. iter != mTextureList.end(); ++iter)
  3420. {
  3421. if (*iter == tex)
  3422. {
  3423. // decrease the reference number for tex by one.
  3424. mTextureList.erase(iter);
  3425. return;
  3426. }
  3427. }
  3428. // We have some trouble here: the texture of the face is changed.
  3429. // We need to find the former texture, and remove it from the list
  3430. // to avoid memory leaking.
  3431. std::vector<const LLTextureEntry*> te_list;
  3432. for (U32 ch = 0; ch < 3; ++ch)
  3433. {
  3434. U32 count = mNumFaces[ch];
  3435. U32 list_size = mFaceList[ch].size();
  3436. if (count > list_size)
  3437. {
  3438. llwarns_once << "Face count greater than face list size for texture channel: "
  3439. << ch << ". Clamping down." << llendl;
  3440. count = list_size;
  3441. }
  3442. for (U32 j = 0; j < count; ++j)
  3443. {
  3444. // All textures are in use.
  3445. te_list.push_back(mFaceList[ch][j]->getTextureEntry());
  3446. }
  3447. }
  3448. if (te_list.empty())
  3449. {
  3450. mTextureList.clear();
  3451. return;
  3452. }
  3453. S32 end = te_list.size();
  3454. for (std::list< LLPointer<LLViewerTexture> >::iterator
  3455. iter = mTextureList.begin();
  3456. iter != mTextureList.end(); ++iter)
  3457. {
  3458. S32 i = 0;
  3459. for (i = 0; i < end; ++i)
  3460. {
  3461. if (te_list[i] && te_list[i]->getID() == (*iter)->getID())
  3462. {
  3463. // the texture is in use.
  3464. te_list[i] = NULL;
  3465. break;
  3466. }
  3467. }
  3468. if (i == end) // No hit for this texture, remove it.
  3469. {
  3470. // Decrease the reference number for tex by one.
  3471. mTextureList.erase(iter);
  3472. return;
  3473. }
  3474. }
  3475. }
  3476. }
  3477. // Check if it is a parcel media
  3478. for (std::list< LLPointer<LLViewerTexture> >::iterator
  3479. iter = mTextureList.begin();
  3480. iter != mTextureList.end(); ++iter)
  3481. {
  3482. if ((*iter)->getID() == mID)
  3483. {
  3484. // Decrease the reference number for tex by one.
  3485. mTextureList.erase(iter);
  3486. return;
  3487. }
  3488. }
  3489. if (te && te->getID().notNull()) // Should have a texture
  3490. {
  3491. llwarns_sparse << "mTextureList texture reference number is corrupted !"
  3492. << llendl;
  3493. llassert(false);
  3494. }
  3495. }
  3496. void LLViewerMediaTexture::stopPlaying()
  3497. {
  3498. #if 0 // Do not stop the media impl playing here: this breaks non-inworld
  3499. // media (login screen, search, and media browser).
  3500. if (mMediaImplp)
  3501. {
  3502. mMediaImplp->stop();
  3503. }
  3504. #endif
  3505. mIsPlaying = false;
  3506. }
  3507. void LLViewerMediaTexture::switchTexture(U32 ch, LLFace* facep)
  3508. {
  3509. if (!facep) return;
  3510. // Check if another media is playing on this face and if this is a parcel
  3511. // media, let the prim media win.
  3512. LLViewerTexture* tex = facep->getTexture();
  3513. if (tex && tex != this &&
  3514. tex->getType() == LLViewerTexture::MEDIA_TEXTURE &&
  3515. tex->getID() == mID)
  3516. {
  3517. return;
  3518. }
  3519. if (mIsPlaying)
  3520. {
  3521. // Old textures switch to the media texture
  3522. facep->switchTexture(ch, this);
  3523. return;
  3524. }
  3525. // Switch to old textures.
  3526. const LLTextureEntry* tep = facep->getTextureEntry();
  3527. if (tep)
  3528. {
  3529. LLViewerTexture* texp = NULL;
  3530. if (tep->getID().notNull())
  3531. {
  3532. texp = gTextureList.findImage(tep->getID());
  3533. }
  3534. if (!texp && tep->getID() != mID) // Try parcel media.
  3535. {
  3536. texp = gTextureList.findImage(mID);
  3537. }
  3538. if (!texp)
  3539. {
  3540. texp = LLViewerFetchedTexture::sDefaultImagep;
  3541. }
  3542. facep->switchTexture(ch, texp);
  3543. }
  3544. }
  3545. void LLViewerMediaTexture::setPlaying(bool playing)
  3546. {
  3547. if (!mMediaImplp)
  3548. {
  3549. return;
  3550. }
  3551. if (!playing && !mIsPlaying)
  3552. {
  3553. return; // Media is already off
  3554. }
  3555. if (playing == mIsPlaying && !mMediaImplp->isUpdated())
  3556. {
  3557. return; // Nothing has changed since last time.
  3558. }
  3559. mIsPlaying = playing;
  3560. if (mIsPlaying) // We are about to play this media
  3561. {
  3562. if (findFaces())
  3563. {
  3564. // About to update all faces.
  3565. mMediaImplp->setUpdated(false);
  3566. }
  3567. if (mMediaFaceList.empty()) // No face pointing to this media
  3568. {
  3569. stopPlaying();
  3570. return;
  3571. }
  3572. for (std::list<LLFace*>::iterator iter = mMediaFaceList.begin();
  3573. iter!= mMediaFaceList.end(); ++iter)
  3574. {
  3575. switchTexture(LLRender::DIFFUSE_MAP, *iter);
  3576. }
  3577. }
  3578. else // Stop playing this media
  3579. {
  3580. U32 ch = LLRender::DIFFUSE_MAP;
  3581. U32 count = mNumFaces[ch];
  3582. U32 list_size = mFaceList[ch].size();
  3583. if (count > list_size)
  3584. {
  3585. llwarns_once << "Face count greater than face list size for texture channel: "
  3586. << ch << ". Clamping down." << llendl;
  3587. count = list_size;
  3588. }
  3589. for (U32 i = count; i; --i)
  3590. {
  3591. // Current face could be removed in this function.
  3592. switchTexture(ch, mFaceList[ch][i - 1]);
  3593. }
  3594. }
  3595. }
  3596. //virtual
  3597. F32 LLViewerMediaTexture::getMaxVirtualSize()
  3598. {
  3599. if (LLFrameTimer::getFrameCount() == mUpdateVirtualSizeTime)
  3600. {
  3601. return mMaxVirtualSize;
  3602. }
  3603. mUpdateVirtualSizeTime = LLFrameTimer::getFrameCount();
  3604. if (!mMaxVirtualSizeResetCounter)
  3605. {
  3606. addTextureStats(0.f, false); // Reset
  3607. }
  3608. if (mIsPlaying) // Media is playing
  3609. {
  3610. for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
  3611. {
  3612. U32 count = mNumFaces[ch];
  3613. U32 list_size = mFaceList[ch].size();
  3614. if (count > list_size)
  3615. {
  3616. llwarns_once << "Face count greater than face list size for texture channel: "
  3617. << ch << ". Clamping down." << llendl;
  3618. count = list_size;
  3619. }
  3620. for (U32 i = 0 ; i < count ; ++i)
  3621. {
  3622. LLFace* facep = mFaceList[ch][i];
  3623. if (facep && facep->getDrawable()->isRecentlyVisible())
  3624. {
  3625. addTextureStats(facep->getVirtualSize());
  3626. }
  3627. }
  3628. }
  3629. }
  3630. else // Media is not in playing
  3631. {
  3632. findFaces();
  3633. if (!mMediaFaceList.empty())
  3634. {
  3635. for (std::list<LLFace*>::iterator iter = mMediaFaceList.begin(),
  3636. end = mMediaFaceList.end();
  3637. iter!= end; ++iter)
  3638. {
  3639. LLFace* facep = *iter;
  3640. if (facep && facep->getDrawable() &&
  3641. facep->getDrawable()->isRecentlyVisible())
  3642. {
  3643. addTextureStats(facep->getVirtualSize());
  3644. }
  3645. }
  3646. }
  3647. }
  3648. if (mMaxVirtualSizeResetCounter > 0)
  3649. {
  3650. --mMaxVirtualSizeResetCounter;
  3651. }
  3652. reorganizeFaceList();
  3653. reorganizeVolumeList();
  3654. return mMaxVirtualSize;
  3655. }