From 5b485bdc6046867e8b03906e8bdd0f02471f9fa8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Fri, 3 Apr 2026 02:11:15 +0300 Subject: #5612 Improve profiling coverage --- indra/newview/llviewermessage.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'indra/newview/llviewermessage.cpp') diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 5d8bd45218..812ba76551 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3554,6 +3554,7 @@ extern U32Bits gObjectData; void process_object_update(LLMessageSystem *mesgsys, void **user_data) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // Update the data counters if (mesgsys->getReceiveCompressedSize()) { @@ -3575,6 +3576,7 @@ void process_object_update(LLMessageSystem *mesgsys, void **user_data) void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // Update the data counters if (mesgsys->getReceiveCompressedSize()) { @@ -3596,6 +3598,7 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // Update the data counters if (mesgsys->getReceiveCompressedSize()) { @@ -3613,6 +3616,7 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data) void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_data) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; if (mesgsys->getReceiveCompressedSize()) { gObjectData += (U32Bytes)mesgsys->getReceiveCompressedSize(); @@ -3972,6 +3976,7 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data) void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; LLUUID animation_id; LLUUID uuid; S32 anim_sequence_id; @@ -4083,6 +4088,7 @@ void process_avatar_animation(LLMessageSystem *mesgsys, void **user_data) void process_object_animation(LLMessageSystem *mesgsys, void **user_data) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; LLUUID animation_id; LLUUID uuid; S32 anim_sequence_id; @@ -4148,6 +4154,7 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data) void process_avatar_appearance(LLMessageSystem *mesgsys, void **user_data) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; LLUUID uuid; mesgsys->getUUIDFast(_PREHASH_Sender, _PREHASH_ID, uuid); @@ -5679,6 +5686,7 @@ void process_script_experience_details(const LLSD& experience_details, LLSD args void process_script_question(LLMessageSystem *msg, void **user_data) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; // *TODO: Translate owner name -> [FIRST] [LAST] LLHost sender = msg->getSender(); -- cgit v1.3 From 1d456767fe47773d9dadcaa456b0af31dc6060e5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Thu, 11 Jun 2026 23:18:09 +0300 Subject: p#604 Fix draw range fluctuations --- indra/newview/lldebugview.cpp | 2 +- indra/newview/lltextureview.cpp | 2 +- indra/newview/llviewermessage.cpp | 5 +- indra/newview/llviewertexture.cpp | 115 +++++++++++++++++++++++++++----------- indra/newview/llviewertexture.h | 3 + indra/newview/llvocache.cpp | 2 +- 6 files changed, 91 insertions(+), 38 deletions(-) (limited to 'indra/newview/llviewermessage.cpp') diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp index 3941b82e75..246a9d28e4 100644 --- a/indra/newview/lldebugview.cpp +++ b/indra/newview/lldebugview.cpp @@ -101,7 +101,7 @@ void LLDebugView::init() addChild(gSceneMonitorView); gSceneMonitorView->setRect(rect); - r.set(150, rect.getHeight() - 60, 820, 110); + r.set(150, rect.getHeight() - 60, 835, 110); LLTextureView::Params tvp; tvp.name("gTextureView"); tvp.rect(r); diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index 4534db958f..470a133fa7 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -250,7 +250,7 @@ void LLTextureBar::draw() gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); // Draw the progress bar. - S32 bar_width = 100; + S32 bar_width = 110; S32 bar_left = 260; left = bar_left; right = left + bar_width; diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 812ba76551..612af029b9 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3372,9 +3372,10 @@ 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::isSystemMemoryCritical()) + if (LLViewerTexture::getSystemMemoryBudgetFactor() > 1.f) { - // If we are low on memory, reduce requested draw distance + // 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); } diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 82f4cc8341..739ca25707 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -114,6 +114,7 @@ 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; @@ -490,6 +491,13 @@ 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() { @@ -523,23 +531,24 @@ void LLViewerTexture::updateClass() // get an estimate of how much video memory we're using // NOTE: our metrics miss about half the vram we use, so this biases high but turns out to typically be within 5% of the real number - F32 used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc); + F32 vram_used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc); // For debugging purposes, it's useful to be able to set the VRAM budget manually. // But when manual control is not enabled, use the VRAM divisor. // While we're at it, assume we have 1024 to play with at minimum when the divisor is in use. Works more elegantly with the logic below this. // -Geenz 2025-03-21 - F32 budget = max_vram_budget == 0 ? llmax(1024, (F32)gGLManager.mVRAM / tex_vram_divisor) : (F32)max_vram_budget; + F32 vram_budget = max_vram_budget == 0 ? llmax(1024, (F32)gGLManager.mVRAM / tex_vram_divisor) : (F32)max_vram_budget; // Try to leave at least half a GB for everyone else and for bias, // but keep at least 768MB for ourselves // Viewer can 'overshoot' target when scene changes, if viewer goes over budget it // can negatively impact performance, so leave 20% of a breathing room for // 'bias' calculation to kick in. - F32 target = llmax(llmin(budget - 512.f, budget * 0.8f), MIN_VRAM_BUDGET); - sFreeVRAMMegabytes = target - used; + 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(); - F32 over_pct = (used - target) / target; + F32 over_pct = (vram_used - vram_target) / vram_target; // Predicted-VRAM pressure controller. Eviction is fast, refetch is slow, // so feedback on instantaneous `used` sawtooths; feeding `used + @@ -550,7 +559,7 @@ void LLViewerTexture::updateClass() static LLCachedControl prediction_gain(gSavedSettings, "TextureMemoryPressurePredictionGain", 10.f); static LLCachedControl smoothing_rate(gSavedSettings, "TextureMemoryPressureSmoothingRate", 4.f); - F32 backoff_target = target * llclamp((F32)backoff_start, 0.05f, 1.f); + F32 backoff_target = vram_target * llclamp((F32)backoff_start, 0.05f, 1.f); F32 cap = llmax((F32)max_mult, 1.0001f); F32 dt = (F32)gFrameIntervalSeconds; @@ -560,7 +569,7 @@ void LLViewerTexture::updateClass() // frame later, from `used` alone. bool need_predict = sMemoryPressureMultiplier > 1.001f || sLastDitchMinDiscard > 0.f - || used > backoff_target * 0.5f; + || vram_used > backoff_target * 0.5f; S64 pending_bytes_increase = 0; S64 pending_bytes_decrease = 0; @@ -597,7 +606,7 @@ void LLViewerTexture::updateClass() // 1024 * 512 = 524288: matches the unit reduction at line 513. constexpr F32 BYTES_TO_USED_UNITS = 1.f / 524288.f; - F32 predicted_used = used + F32 predicted_used = vram_used + (F32)pending_bytes_increase * BYTES_TO_USED_UNITS - (F32)pending_bytes_decrease * BYTES_TO_USED_UNITS; F32 predicted_over = predicted_used / llmax(backoff_target, 1.f); @@ -607,7 +616,7 @@ void LLViewerTexture::updateClass() // Recovers the historical 90% behavior - immediate aggressive // response instead of waiting for the lerp to chase the target. static LLCachedControl high_water(gSavedSettings, "TextureMemoryHighWaterMark", 0.8f); - bool above_high_water = used >= budget * llclamp((F32)high_water, 0.5f, 1.f); + bool above_high_water = vram_used >= vram_budget * llclamp((F32)high_water, 0.5f, 1.f); F32 target_mult = llclamp(powf(llmax(predicted_over, 1.f), llmax((F32)prediction_gain, 0.0001f)), 1.f, cap); if (above_high_water) @@ -649,14 +658,14 @@ void LLViewerTexture::updateClass() if (s_pressure_log_timer.getElapsedTimeF32() > 1.f) { s_pressure_log_timer.reset(); - F32 over = used / llmax(backoff_target, 1.f); + F32 over = vram_used / llmax(backoff_target, 1.f); LL_INFOS("TextureStream") << "pressure" << " mult=" << sMemoryPressureMultiplier << " target_mult=" << target_mult << " progress=" << progress - << " used=" << used + << " used=" << vram_used << " predicted=" << predicted_used - << " target=" << target + << " target=" << vram_target << " over=" << over << " pred_over=" << predicted_over << " in+=" << (S32)(pending_bytes_increase / 1024 / 1024) @@ -669,10 +678,66 @@ void LLViewerTexture::updateClass() } bool is_sys_low = isSystemMemoryLow(); + bool is_sys_critically_low = isSystemMemoryCritical(); bool is_low = is_sys_low || over_pct > 0.f; static bool was_low = false; + 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.05; + 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.02; + sSysMemoryFactor -= DECREMENT * gFrameIntervalSeconds; + sSysMemoryFactor = llclamp(sSysMemoryFactor, 1.f, 2.f); + } + } + sys_was_low = is_sys_critically_low; + + // VRAM memory bias if (is_low && !was_low) { if (is_sys_low) @@ -720,12 +785,11 @@ void LLViewerTexture::updateClass() // lower discard bias over time when at least 10% of budget is free constexpr F32 FREE_PERCENTAGE_TRESHOLD = -0.1f; - constexpr U32 FREE_SYS_MEM_TRESHOLD = 100; - static LLCachedControl min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512); - const S32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory() + FREE_SYS_MEM_TRESHOLD); + constexpr U32 FREE_SYS_MEM_THRESHOLD = 100; // 100MB more than isSystemMemoryLow to avoid fluctuations. + const S32Megabytes MIN_FREE_MAIN_MEMORY(get_render_free_main_memory_treshold() + S32Megabytes(FREE_SYS_MEM_THRESHOLD)); if (sDesiredDiscardBias > 1.f && over_pct < FREE_PERCENTAGE_TRESHOLD - && getFreeSystemMemory() > MIN_FREE_MAIN_MEMORY + && free_sys_mem > MIN_FREE_MAIN_MEMORY && !eviction_in_flight) { static LLCachedControl high_mem_discard_decrement(gSavedSettings, "RenderHighMemMinDiscardDecrement", .1f); @@ -835,13 +899,6 @@ U32Megabytes LLViewerTexture::getFreeSystemMemory() return physical_res; } -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 bool LLViewerTexture::isSystemMemoryLow() { @@ -854,18 +911,10 @@ bool LLViewerTexture::isSystemMemoryCritical() return getFreeSystemMemory() < get_render_free_main_memory_treshold() / 2; } +// static F32 LLViewerTexture::getSystemMemoryBudgetFactor() { - const S32Megabytes MIN_FREE_MAIN_MEMORY(get_render_free_main_memory_treshold() / 2); - S32 free_budget = (S32Megabytes)getFreeSystemMemory() - MIN_FREE_MAIN_MEMORY; - if (free_budget < 0) - { - // Leave some padding, otherwise we will crash out of memory before hitting factor 2. - const S32Megabytes PAD_BUFFER(32); - // Result should range from 1 at 0 free budget to 2 at -224 free budget, 2.14 at -256MB - return 1.f - free_budget / (MIN_FREE_MAIN_MEMORY - PAD_BUFFER); - } - return 1.f; + return sSysMemoryFactor; } //end of static functions diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 991bb638a1..8c5c48bafd 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -116,6 +116,8 @@ public: 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); @@ -268,6 +270,7 @@ 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; diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 5d456b1a19..7618739b3c 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -488,7 +488,7 @@ void LLVOCacheEntry::updateDebugSettings() static const F32 MIN_RADIUS = 1.0f; F32 draw_radius = gAgentCamera.mDrawDistance; - if (LLViewerTexture::isSystemMemoryCritical()) + 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 -- 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/newview/llviewermessage.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 From 1c8144b1708420b30c54472a5139d451034e89de Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev <117672381+akleshchev@users.noreply.github.com> Date: Mon, 6 Jul 2026 20:53:53 +0300 Subject: #4604 Restore system memory factor, but in LLMemory --- indra/llcommon/llmemory.cpp | 91 +++++++++++++++++++++++++++++++++++++- indra/llcommon/llmemory.h | 9 +++- indra/llcommon/llsys.cpp | 2 +- indra/llcommon/llsys.h | 8 ++-- indra/newview/llappviewerwin32.cpp | 15 ++++--- indra/newview/llviewerdisplay.cpp | 5 +++ indra/newview/llviewermessage.cpp | 8 ++++ indra/newview/llvocache.cpp | 8 ++++ 8 files changed, 133 insertions(+), 13 deletions(-) (limited to 'indra/newview/llviewermessage.cpp') diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index 31424bfed3..4e44b9a56a 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2026, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -73,6 +73,12 @@ U32Kilobytes LLMemory::sAllocatedMemInKB(0); U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0); +LLFrameTimer LLMemory::sMemoryCheckTimer; +F32 LLMemory::sSysMemoryFactor = 1.f; +U32 LLMemory::sFactorLastFrameCount = 0; + +static const S32Megabytes MEM_LOW_THRESHOLD = S32Megabytes(256); + static LLTrace::SampleStatHandle sAllocatedMem("allocated_mem", "active memory in use by application"); static LLTrace::SampleStatHandle sVirtualMem("virtual_mem", "virtual memory assigned to application"); @@ -105,12 +111,13 @@ void LLMemory::updateMemoryInfo() { LL_PROFILE_ZONE_SCOPED; + sMemoryCheckTimer.reset(); sMaxPhysicalMemInKB = gSysMemory.getPhysicalMemoryKB(); LLMemoryInfo::updateAvailableMemory(); #if LL_WINDOWS - // On windows getAvailableMemoryKB fills sAvailPhysicalMemInKB, + // On windows updateAvailableMemory fills sAvailPhysicalMemInKB, //sAllocatedMemInKB and sAllocatedPageSizeInKB sample(sVirtualMem, sAllocatedPageSizeInKB); @@ -194,6 +201,86 @@ void LLMemory::logMemoryInfo(bool update) LL_INFOS() << llformat("Current max usable memory: %.2f MB", sMaxPhysicalMemInKB / 1024.0) << LL_ENDL; } +void LLMemory::updateFreeSystemMemory() +{ + if (sMemoryCheckTimer.getElapsedTimeF32() >= 1.f) //once per second. + { + LLMemory::updateMemoryInfo(); // resets the timer + } +} + +F32 LLMemory::getSystemMemoryBudgetFactor() +{ + // Only update once per frame + U32 current_frame = LLFrameTimer::getFrameCount(); + if (sFactorLastFrameCount == current_frame) + { + return sSysMemoryFactor; + } + sFactorLastFrameCount = current_frame; + + updateFreeSystemMemory(); +#if LL_WINDOWS + S32Megabytes free_sys_mem = getAvailableCommitMemMB(); +#else + S32Megabytes free_sys_mem = getAvailableMemKB(); +#endif + bool is_sys_low = free_sys_mem < MEM_LOW_THRESHOLD; + static bool was_low = false; + + // 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_low) + { + // debt is a negative value since MIN_FREE_MAIN_MEMORY > free memory. + S32Megabytes sys_budget_debt = free_sys_mem - MEM_LOW_THRESHOLD; + + // Leave some padding, otherwise we will crash out of memory before hitting factor 2. + const S32Megabytes PAD_BUFFER(32); + S32Megabytes budget_target = MEM_LOW_THRESHOLD - PAD_BUFFER; + if (!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.value() / (F32)budget_target.value(); + 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.value() / (F32)budget_target.value(), 0.f); + sSysMemoryFactor += increment * LLFrameTimer::getFrameDeltaTimeF32(); + } + sSysMemoryFactor = llclamp(sSysMemoryFactor, 1.f, 2.f); + } + else + { + // 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 + // threshold. + const S32Megabytes MEM_THRESHOLD = MEM_LOW_THRESHOLD + S32Megabytes(150); + if (free_sys_mem > MEM_THRESHOLD && sSysMemoryFactor > 1.f) + { + // Ramp down factor over time. + constexpr F32 DECREMENT = 0.02f; + sSysMemoryFactor -= DECREMENT * LLFrameTimer::getFrameDeltaTimeF32(); + sSysMemoryFactor = llclamp(sSysMemoryFactor, 1.f, 2.f); + } + } + was_low = is_sys_low; + + return sSysMemoryFactor; +} + #if LL_WINDOWS //static U32Megabytes LLMemory::getAvailableCommitMemMB() diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h index 290f6e03d1..efcd7aadc4 100644 --- a/indra/llcommon/llmemory.h +++ b/indra/llcommon/llmemory.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2026, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,6 +27,7 @@ #define LLMEMORY_H #include "linden_common.h" +#include "llframetimer.h" #include "llunits.h" #include "stdtypes.h" #if !LL_WINDOWS @@ -428,6 +429,7 @@ public: static void initMaxHeapSizeGB(F32Gigabytes max_heap_size); static void updateMemoryInfo() ; static void logMemoryInfo(bool update = false); + static F32 getSystemMemoryBudgetFactor(); #if LL_WINDOWS // Commit charge is a Windows-only concept, combines page file and ram @@ -437,6 +439,7 @@ public: static U32Kilobytes getMaxMemKB() ; static U32Kilobytes getAllocatedMemKB() ; private: + static void updateFreeSystemMemory(); // LLMemoryInfo directly updates memory stats friend class LLMemoryInfo; @@ -447,6 +450,10 @@ private: static U32Kilobytes sAllocatedPageSizeInKB ; static U32Kilobytes sMaxHeapSizeInKB; + + static LLFrameTimer sMemoryCheckTimer; + static F32 sSysMemoryFactor; + static U32 sFactorLastFrameCount; }; // LLRefCount moved to llrefcount.h diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index 568a6b36dc..bc48fc0fd2 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2026, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 709fb29a82..0abbe047ad 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. + * Copyright (C) 2026, Linden Research, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -134,12 +134,12 @@ public: static U32Kilobytes getHardwareMemSize(); // Because some Mac linkers won't let us reference extern gSysMemory from a different lib. #endif - // Updates LLMemory's values (which ones is OS specific). + // Updates LLMemory's values. static void updateAvailableMemory(); // Retrieve a map of memory statistics. The keys of the map are platform- - // dependent. The values are in kilobytes to try to avoid integer overflow. - // On windows updates LLMemory values. + // dependent. + // On Windows updates LLMemory values. LLSD getStatsMap() const; // Re-fetch memory data (as reported by stream() and getStatsMap()) from the diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp index 5c2594e85c..8a9ddbcde6 100644 --- a/indra/newview/llappviewerwin32.cpp +++ b/indra/newview/llappviewerwin32.cpp @@ -82,6 +82,7 @@ #include "BugSplat.h" #include "boost/json.hpp" // Boost.Json #include "llagent.h" // for agent location +#include "llmemory.h" #include "llstartup.h" #include "llviewerregion.h" #include "llvoavatarself.h" // for agent name @@ -181,11 +182,15 @@ namespace sBugSplatSender->setAttribute(WCSTR(L"VRAM"), WCSTR(STRINGIZE(gGLManager.mVRAM))); sBugSplatSender->setAttribute(WCSTR(L"RAM"), WCSTR(STRINGIZE(gSysMemory.getPhysicalMemoryKB().value()))); - // Memory usage at crash time (can be 1s obsolete) - sBugSplatSender->setAttribute(WCSTR(L"MemAllocatedKB"), WCSTR(std::to_string(LLMemory::getAllocatedMemKB().value()))); - sBugSplatSender->setAttribute(WCSTR(L"MemAvailableKB"), WCSTR(std::to_string(LLMemory::getAvailableMemKB().value()))); - sBugSplatSender->setAttribute(WCSTR(L"MemMaxPhysicalKB"), WCSTR(std::to_string(LLMemory::getMaxMemKB().value()))); - sBugSplatSender->setAttribute(WCSTR(L"MemAvailCommitMB"), WCSTR(std::to_string(LLMemory::getAvailableCommitMemMB().value()))); + const U32 avail_kb = LLMemory::getAvailableMemKB().value(); + if (avail_kb != U32_MAX) // filter out initial values, if one is not set, all are not set + { + // Memory usage at crash time (can be 1s obsolete) + sBugSplatSender->setAttribute(WCSTR(L"MemAllocatedKB"), WCSTR(std::to_string(LLMemory::getAllocatedMemKB().value()))); + sBugSplatSender->setAttribute(WCSTR(L"MemAvailableKB"), WCSTR(std::to_string(LLMemory::getAvailableMemKB().value()))); + sBugSplatSender->setAttribute(WCSTR(L"MemMaxPhysicalKB"), WCSTR(std::to_string(LLMemory::getMaxMemKB().value()))); + sBugSplatSender->setAttribute(WCSTR(L"MemAvailCommitMB"), WCSTR(std::to_string(LLMemory::getAvailableCommitMemMB().value()))); + } if (gAgent.getRegion()) { diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 9f1b0d75f3..0d50ba6fe2 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -217,6 +217,11 @@ void display_update_camera() { final_far *= 0.5f; } + // When system memory is critically low or recovering, shrink draw distance. + else if (const F32 mem_factor = LLMemory::getSystemMemoryBudgetFactor(); mem_factor > 1.f) + { + final_far = llmax(32.f, final_far / mem_factor); + } 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 09f17fec40..8863dfb501 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -40,6 +40,7 @@ #include "llinventorydefines.h" #include "lllslconstants.h" #include "llmaterialtable.h" +#include "llmemory.h" #include "llregionhandle.h" #include "llsd.h" #include "llsdserialize.h" @@ -3371,6 +3372,13 @@ void send_agent_update(bool force_send, bool send_reliable) static F32 last_draw_disatance_step = 1024; F32 memory_limited_draw_distance = gAgentCamera.mDrawDistance; + const F32 mem_factor = LLMemory::getSystemMemoryBudgetFactor(); + if (mem_factor > 1.f) + { + // We are critically low on memory or recovering, + // limit requested draw distance + memory_limited_draw_distance = llmax(gAgentCamera.mDrawDistance / mem_factor, gAgentCamera.mDrawDistance / 2.f); + } if (tp_state == LLAgent::TELEPORT_ARRIVING || LLStartUp::getStartupState() < STATE_MISC) { diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index f3efe3f3bb..e513a3813f 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -32,6 +32,7 @@ #include "lldrawable.h" #include "llviewerregion.h" #include "llagentcamera.h" +#include "llmemory.h" #include "llsdserialize.h" #include "llworld.h" // For LLWorld::getInstance() //static variables @@ -488,6 +489,13 @@ void LLVOCacheEntry::updateDebugSettings() static const F32 MIN_RADIUS = 1.0f; F32 draw_radius = gAgentCamera.mDrawDistance; + const F32 mem_factor = LLMemory::getSystemMemoryBudgetFactor(); + if (mem_factor > 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 / mem_factor, 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