From 6622a5694b5ccd1da77e1564c6475eaf81095f5b Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 7 Jul 2026 04:59:59 -0400 Subject: Get some more wins for overall downrezzing and minimizing thrashing. Also make sure that probes don't stamp - that creates thrashing when distant probes render. We're at a low enough resolution on those things that higher mips are likely to go unnoticed, and we bake them frequently enough that we can pick up lower mips when we actually need them. --- indra/llrender/llimagegl.cpp | 56 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 11 deletions(-) (limited to 'indra/llrender/llimagegl.cpp') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 6bcc34938c..95575c009b 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -166,6 +166,8 @@ U64 LLImageGL::getTextureBytesAllocated() //statics U32 LLImageGL::sUniqueCount = 0; +std::atomic LLImageGL::sOOMErrorCount(0); +thread_local bool LLImageGL::sStampBindFrame = true; U32 LLImageGL::sBindCount = 0; S32 LLImageGL::sCount = 0; @@ -777,6 +779,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw) bool LLImageGL::setImage(const U8* data_in, bool data_hasmips /* = false */, S32 usename /* = 0 */) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + LLImageGLStampBypass no_stamp; // upload binds are not visibility const bool is_compressed = isCompressed(); @@ -1502,6 +1505,12 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt { free_cur_tex_image(); } + + // Drain stale GL errors so an OOM detected below belongs to this alloc. + // Otherwise a failed glTexImage2D is swallowed in release while + // alloc_tex_image still counts the bytes, inflating the used-VRAM figure. + while (glGetError() != GL_NO_ERROR) {} + const bool use_sub_image = should_stagger_image_set(compress); if (!use_sub_image) { @@ -1511,19 +1520,30 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt else { // break up calls to a manageable size for the GL command buffer - { - LL_PROFILE_ZONE_NAMED("glTexImage2D alloc"); - glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr); - } + LL_PROFILE_ZONE_NAMED("glTexImage2D alloc"); + glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, nullptr); + } - U8* src = (U8*)(pixels); - if (src) + if (glGetError() == GL_OUT_OF_MEMORY) + { + ++sOOMErrorCount; + LL_WARNS_ONCE("Texture") << "glTexImage2D failed with GL_OUT_OF_MEMORY (" + << width << "x" << height << " mip " << miplevel + << ") - not counting bytes" << LL_ENDL; + } + else + { + if (use_sub_image) { - LL_PROFILE_ZONE_NAMED("glTexImage2D copy"); - sub_image_lines(target, miplevel, 0, 0, width, height, pixformat, pixtype, src, width); + U8* src = (U8*)(pixels); + if (src) + { + LL_PROFILE_ZONE_NAMED("glTexImage2D copy"); + sub_image_lines(target, miplevel, 0, 0, width, height, pixformat, pixtype, src, width); + } } + alloc_tex_image(width, height, intformat, 1); } - alloc_tex_image(width, height, intformat, 1); } stop_glerror(); } @@ -1668,6 +1688,7 @@ bool LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, bool data_ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LL_PROFILE_GPU_ZONE("createGLTexture"); checkActiveThread(); + LLImageGLStampBypass no_stamp; // creation binds are not visibility bool main_thread = on_main_thread(); @@ -2090,12 +2111,21 @@ S32 LLImageGL::dimDerivedMaxDiscard(S32 width, S32 height) void LLImageGL::stampBound() const { - // Skip the store on same-frame re-binds - bindFast is per-draw and - // would dirty this cache line per bind per texture otherwise. + // Both stamps skip same-frame re-binds (bindFast runs per draw). They dedupe + // separately, so a non-camera pass touching the time stamp first doesn't stop + // a real camera bind from setting the frame stamp later the same frame. if (mLastBindTime != sLastFrameTime) { mLastBindTime = sLastFrameTime; } + if (sStampBindFrame) + { + const U32 frame = LLFrameTimer::getFrameCount(); + if (mLastBindFrame != frame) + { + mLastBindFrame = frame; + } + } } S64 LLImageGL::getBytes(S32 discard_level) const @@ -2520,6 +2550,10 @@ bool LLImageGL::scaleDown(S32 desired_discard) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + // Don't let eviction re-arm visibility: the glGenerateMipmap re-bind below + // would otherwise stamp mLastBindFrame and keep the texture fetch-eligible. + LLImageGLStampBypass no_stamp; + if (mTarget != GL_TEXTURE_2D || mFormatInternal == -1 // not initialized ) -- cgit v1.3 From f117d33535097c3bb8d48f1f954a7a8df0449c44 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Tue, 7 Jul 2026 07:34:09 -0400 Subject: Kill the system memory stuff - it's not relevant to the new texture streaming. --- indra/llrender/llimagegl.cpp | 8 +- indra/llrender/llimagegl.h | 1 - indra/newview/app_settings/settings.xml | 11 --- indra/newview/llviewerdisplay.cpp | 5 - indra/newview/llviewermessage.cpp | 7 -- indra/newview/llviewertexture.cpp | 159 -------------------------------- indra/newview/llviewertexture.h | 22 ----- indra/newview/llvocache.cpp | 6 -- 8 files changed, 3 insertions(+), 216 deletions(-) (limited to 'indra/llrender/llimagegl.cpp') diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 95575c009b..c8a23d873e 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -493,7 +493,7 @@ bool LLImageGL::create(LLPointer& dest, const LLImageRaw* imageraw, b //---------------------------------------------------------------------------- LLImageGL::LLImageGL(bool usemipmaps/* = true*/, bool allow_compression/* = true*/) -: mSaveData(0), mExternalTexture(false) +: mExternalTexture(false) { init(usemipmaps, allow_compression); setSize(0, 0, 0); @@ -502,7 +502,7 @@ LLImageGL::LLImageGL(bool usemipmaps/* = true*/, bool allow_compression/* = true } LLImageGL::LLImageGL(U32 width, U32 height, U8 components, bool usemipmaps/* = true*/, bool allow_compression/* = true*/) -: mSaveData(0), mExternalTexture(false) +: mExternalTexture(false) { llassert( components <= 4 ); init(usemipmaps, allow_compression); @@ -512,7 +512,7 @@ LLImageGL::LLImageGL(U32 width, U32 height, U8 components, bool usemipmaps/* = t } LLImageGL::LLImageGL(const LLImageRaw* imageraw, bool usemipmaps/* = true*/, bool allow_compression/* = true*/) -: mSaveData(0), mExternalTexture(false) +: mExternalTexture(false) { init(usemipmaps, allow_compression); setSize(0, 0, 0); @@ -621,8 +621,6 @@ void LLImageGL::cleanup() destroyGLTexture(); } freePickMask(); - - mSaveData = NULL; // deletes data } //---------------------------------------------------------------------------- diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 57ca79b3dd..ca75b543c0 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -256,7 +256,6 @@ private: void freePickMask(); bool isCompressed(); - LLPointer mSaveData; // used for destroyGL/restoreGL LL::WorkQueue::weak_t mMainQueue; U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel U16 mPickMaskWidth; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index bdcbf3b7f2..45a7dced5c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8002,17 +8002,6 @@ Value 1 - RenderMinFreeMainMemoryThreshold - - Comment - If available free physical memory is below this value textures get agresively scaled down - Persist - 0 - Type - U32 - Value - 512 - RenderLowMemMinDiscardIncrement Comment diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 4773a8a555..9f1b0d75f3 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -217,11 +217,6 @@ void display_update_camera() { final_far *= 0.5f; } - // When system memory is critically low or recovering, shrink draw distance. - else if (LLViewerTexture::getSystemMemoryBudgetFactor() > 1.f) - { - final_far = llmax(32.f, final_far / LLViewerTexture::getSystemMemoryBudgetFactor()); - } LLViewerCamera::getInstance()->setFar(final_far); LLVOAvatar::sRenderDistance = llclamp(final_far, 16.f, 256.f); gViewerWindow->setup3DRender(); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 612af029b9..09f17fec40 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3372,13 +3372,6 @@ void send_agent_update(bool force_send, bool send_reliable) static F32 last_draw_disatance_step = 1024; F32 memory_limited_draw_distance = gAgentCamera.mDrawDistance; - if (LLViewerTexture::getSystemMemoryBudgetFactor() > 1.f) - { - // We are critcally low on memory or recovering, - // limit requested draw distance - memory_limited_draw_distance = llmax(gAgentCamera.mDrawDistance / LLViewerTexture::getSystemMemoryBudgetFactor(), gAgentCamera.mDrawDistance / 2.f); - } - if (tp_state == LLAgent::TELEPORT_ARRIVING || LLStartUp::getStartupState() < STATE_MISC) { // Inform interest list, prioritize closer area. diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 47d022c854..7d07c95395 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -91,9 +91,6 @@ F32 LLViewerTexture::sPixelToTexelRatio = 1.f; U32 LLViewerTexture::sGCSuspendedFrame = 0; S64 LLViewerTexture::sPendingAllocBytes = 0; S64 LLViewerTexture::sPendingFreeBytes = 0; -U32 LLViewerTexture::sUprezRequestCount = 0; -U32 LLViewerTexture::sDownscaleEnqueueCount = 0; -U32 LLViewerTexture::sCooldownFlooredCount = 0; S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size constexpr S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64; @@ -105,19 +102,14 @@ U32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256. U32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA; F32 LLViewerTexture::sCurrentTime = 0.0f; -constexpr F32 MEMORY_CHECK_WAIT_TIME = 1.0f; constexpr F32 MIN_VRAM_BUDGET = 768.f; F32 LLViewerTexture::sFreeVRAMMegabytes = MIN_VRAM_BUDGET; F32 LLViewerTexture::sWindowPixelArea = 1.f; -F32 LLViewerTexture::sSysMemoryFactor = 1.f; LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF; const F64 log_2 = log(2.0); -// GC evict->refetch cycle samples for the 1Hz TextureStream log (main thread). -static U32 sGCRefetchCount = 0; - //---------------------------------------------------------------------------------------------- //namespace: LLViewerTextureAccess //---------------------------------------------------------------------------------------------- @@ -489,13 +481,6 @@ void LLViewerTexture::initClass() LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture(); } -S32Megabytes get_render_free_main_memory_treshold() -{ - static LLCachedControl min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512); - const U32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory); - return MIN_FREE_MAIN_MEMORY; -} - //static void LLViewerTexture::updateClass() { @@ -544,7 +529,6 @@ void LLViewerTexture::updateClass() // 'bias' calculation to kick in. F32 vram_target = llmax(llmin(vram_budget - 512.f, vram_budget * 0.8f), MIN_VRAM_BUDGET); sFreeVRAMMegabytes = vram_target - vram_used; - const S32Megabytes free_sys_mem = getFreeSystemMemory(); // VRAM pressure controller for the global pixel:texel ratio. Tightens above // the high watermark, relaxes below the low one, holds in the band (the band @@ -598,135 +582,7 @@ void LLViewerTexture::updateClass() { sGCSuspendedFrame = LLFrameTimer::getFrameCount(); } - - // 1 Hz pressure log. `used` units are the doubled-bytes metric - // (bytes/524288, see above); pending ledgers are converted to match so - // eff(ective) = what used will read once in-flight work settles. - static LLFrameTimer s_pressure_log_timer; - if (s_pressure_log_timer.getElapsedTimeF32() > 1.f) - { - s_pressure_log_timer.reset(); - constexpr F32 BYTES_TO_USED_UNITS = 1.f / 524288.f; - F32 pend_alloc = (F32)sPendingAllocBytes * BYTES_TO_USED_UNITS; - F32 pend_free = (F32)sPendingFreeBytes * BYTES_TO_USED_UNITS; - LL_INFOS("TextureStream") << "pressure" - << " ratio=" << sPixelToTexelRatio - << " used=" << vram_used - << " eff=" << vram_used + pend_alloc - pend_free - << " pend+=" << pend_alloc - << " pend-=" << pend_free - << " budget=" << vram_budget - << " high=" << high - << " low=" << low - << " dsq=" << (S32)gTextureList.mDownScaleQueue.size() - << " uprez/s=" << sUprezRequestCount - << " dscale/s=" << sDownscaleEnqueueCount - << " cdfloor/s=" << sCooldownFlooredCount - << " gcref/s=" << sGCRefetchCount - << " gloom=" << LLImageGL::sOOMErrorCount.load() - << LL_ENDL; - sUprezRequestCount = 0; - sDownscaleEnqueueCount = 0; - sCooldownFlooredCount = 0; - sGCRefetchCount = 0; - } - } - - // System-memory -> draw-distance factor. Separate from the VRAM ratio above: - // this is a last-resort response to running low on *system* RAM and only - // affects draw distance (via getSystemMemoryBudgetFactor, consumed by - // llviewerdisplay). Textures were mostly moved to VRAM, so this rarely fires. - bool is_sys_critically_low = isSystemMemoryCritical(); - static bool sys_was_low = false; - - // System memory factor - // sSysMemoryFactor affects draw distance - // - // We only decrement when more than 406MB is free, but increment - // when below 256MB free. This should provide a stable value - // in the 256-406MB range to avoid draw range fluctuations. - // - // Draw range reduction is a last resort, texture bias is supposed - // to free at least some memory before we get here. - // Note: textures were mostly moved to vram, we might want to - // detach texture bias from system memory. - if (is_sys_critically_low) - { - const S32Megabytes MIN_FREE_MAIN_MEMORY(get_render_free_main_memory_treshold() / 2); - // debt is a negative value since MIN_FREE_MAIN_MEMORY > free memory. - S32 sys_budget_debt = free_sys_mem - MIN_FREE_MAIN_MEMORY; - - // Leave some padding, otherwise we will crash out of memory before hitting factor 2. - const S32Megabytes PAD_BUFFER(32); - S32Megabytes budget_target = MIN_FREE_MAIN_MEMORY - PAD_BUFFER; - if (!sys_was_low) - { - // Result should range from 1 at 0 debt to 2 at -224 debt, 2.14 at -256MB - F32 new_factor = 1.f - (F32)sys_budget_debt / (F32)budget_target; - sSysMemoryFactor = llmax(sSysMemoryFactor, new_factor); - } - else - { - // Slowly ramp up factor to free memory (increasing factor decreases draw range) - constexpr F32 MAX_INCREMENT = 0.05f; - F32 increment = MAX_INCREMENT * llmax(-(F32)sys_budget_debt / (F32)budget_target, 0.f); - sSysMemoryFactor += increment * gFrameIntervalSeconds; - } - sSysMemoryFactor = llclamp(sSysMemoryFactor, 1.f, 2.f); - } - else - { - const S32Megabytes MIN_FREE_MAIN_MEMORY(get_render_free_main_memory_treshold() / 2); - // Only start ramping down when we have breathing room. - // This should be under the value of isSystemMemoryLow to not throw texture - // bias into 1.5+ territory each time we fluctuate around isSystemMemoryLow's - // treshold. - const S32Megabytes MEM_THRESHOLD = MIN_FREE_MAIN_MEMORY + S32Megabytes(150); - if (free_sys_mem > MEM_THRESHOLD && sSysMemoryFactor > 1.f) - { - // Ramp down factor over time. - constexpr F32 DECREMENT = 0.02f; - sSysMemoryFactor -= DECREMENT * gFrameIntervalSeconds; - sSysMemoryFactor = llclamp(sSysMemoryFactor, 1.f, 2.f); - } } - sys_was_low = is_sys_critically_low; -} - -//static -U32Megabytes LLViewerTexture::getFreeSystemMemory() -{ - static LLFrameTimer timer; - static U32Megabytes physical_res = U32Megabytes(U32_MAX); - - if (timer.getElapsedTimeF32() < MEMORY_CHECK_WAIT_TIME) //call this once per second. - { - return physical_res; - } - - timer.reset(); - - LLMemory::updateMemoryInfo(); - physical_res = LLMemory::getAvailableMemKB(); - return physical_res; -} - -//static -bool LLViewerTexture::isSystemMemoryLow() -{ - return getFreeSystemMemory() < get_render_free_main_memory_treshold(); -} - -//static -bool LLViewerTexture::isSystemMemoryCritical() -{ - return getFreeSystemMemory() < get_render_free_main_memory_treshold() / 2; -} - -// static -F32 LLViewerTexture::getSystemMemoryBudgetFactor() -{ - return sSysMemoryFactor; } //end of static functions @@ -2320,14 +2176,7 @@ bool LLViewerFetchedTexture::updateFetch() // resident minus what's resident now. Settled at postCreateTexture (or // on the cancel/failure paths). setPendingByteDelta(estimatedVRAMBytesAtDiscard(mRequestedDiscardLevel) - residentVRAMBytes()); - ++sUprezRequestCount; - if (mGCEvicted) - { - // GC evict->refetch cycle; counted as gcref/s, should be ~0 when settled. - mGCEvicted = false; - ++sGCRefetchCount; - } mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP); } @@ -3308,7 +3157,6 @@ S32 LLViewerLODTexture::computeDesiredDiscard(S32 dim_max_i, bool avatar_bake) c static LLCachedControl gc_step_mips(gSavedSettings, "TextureGCStepMips", 1); constexpr U32 GC_RESUME_GRACE_FRAMES = 10; const U32 now = LLFrameTimer::getFrameCount(); - mGCFloored = false; if (gli->mLastBindFrame > 0 // drawn at least once && now - sGCSuspendedFrame > GC_RESUME_GRACE_FRAMES) // not just back from background { @@ -3318,8 +3166,6 @@ S32 LLViewerLODTexture::computeDesiredDiscard(S32 dim_max_i, bool avatar_bake) c { const S32 step_mips = (S32)llmax((U32)gc_step_mips, 1u); desired = llclamp(desired + periods * step_mips, desired, dim_max_i); - mGCFloored = true; - ++sCooldownFlooredCount; } } } @@ -3406,10 +3252,6 @@ void LLViewerLODTexture::processTextureStats() S32 current_discard = getDiscardLevel(); if (!avatar_bake && current_discard >= 0 && current_discard < mDesiredDiscardLevel && !mForceToSaveRawImage) { - if (mGCFloored) - { - mGCEvicted = true; // eviction attributable to the visibility GC - } scaleDown(); } @@ -3455,7 +3297,6 @@ bool LLViewerLODTexture::scaleDown() gTextureList.mDownScaleQueue.push(this); // Pending-free ledger entry: bytes decided-freed, returned when the queue drains. setPendingByteDelta(estimatedVRAMBytesAtDiscard(mDesiredDiscardLevel) - residentVRAMBytes()); - ++sDownscaleEnqueueCount; } return true; diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index ce9a953de5..145661fefe 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -114,11 +114,6 @@ protected: public: static void initClass(); static void updateClass(); - static bool isSystemMemoryLow(); - static bool isSystemMemoryCritical(); - - // Ranges from 1 (no RAM deficit) to 2 (RAM deficit) - static F32 getSystemMemoryBudgetFactor(); LLViewerTexture(bool usemipmaps = true); LLViewerTexture(const LLUUID& id, bool usemipmaps) ; @@ -198,8 +193,6 @@ private: friend class LLBumpImageList; friend class LLUIImageList; - static U32Megabytes getFreeSystemMemory(); - protected: friend class LLViewerTextureList; LLUUID mID; @@ -259,12 +252,6 @@ public: static S64 sPendingAllocBytes; // in-flight toward allocation static S64 sPendingFreeBytes; // queued for release, not yet returned - // 1Hz churn counters (main thread; reset each pressure-log tick). High - // uprez+downscale with no memory pressure = per-texture oscillation. - static U32 sUprezRequestCount; // finer-mip fetch requests issued - static U32 sDownscaleEnqueueCount; // scaleDown enqueues - static U32 sCooldownFlooredCount; // desired raised by the cooldown floor - static S32 sMaxSculptRez ; static U32 sMinLargeImageSize ; static U32 sMaxSmallImageSize ; @@ -273,7 +260,6 @@ public: // estimated free memory for textures, by bias calculation static F32 sFreeVRAMMegabytes; - static F32 sSysMemoryFactor; // Viewport pixel area, refreshed once per frame. Hoisted to keep the // per-texture hot path out of gViewerWindow. static F32 sWindowPixelArea; @@ -453,14 +439,6 @@ public: bool mCreatePending = false; // if true, this is in gTextureList.mCreateTextureList mutable bool mDownScalePending = false; // if true, this is in gTextureList.mDownScaleQueue - // GC-cycle diagnostics (main thread): mGCFloored = the visibility GC - // raised desired on the last computeDesiredDiscard; mGCEvicted = this - // texture was actually evicted because of it. A subsequent uprez fetch - // request while mGCEvicted is a full evict->refetch cycle - the churn - // signature - and gets sampled into the 1Hz TextureStream log. - mutable bool mGCFloored = false; - bool mGCEvicted = false; - // --- committed-bytes ledger (main thread only) --- // Estimated VRAM bytes this texture would occupy resident at `discard` // (components ~4, x4/3 mip chain, /4 rough DXT when compression is on). diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 7618739b3c..f3efe3f3bb 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -488,12 +488,6 @@ void LLVOCacheEntry::updateDebugSettings() static const F32 MIN_RADIUS = 1.0f; F32 draw_radius = gAgentCamera.mDrawDistance; - if (LLViewerTexture::getSystemMemoryBudgetFactor() > 1.f) - { - // Factor is intended to go from 1.0 to 2.0 - // For safety cap reduction at 50%, we don't want to go below half of draw distance - draw_radius = llmax(draw_radius / LLViewerTexture::getSystemMemoryBudgetFactor(), draw_radius / 2.f); - } const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance] sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor); -- cgit v1.3