Skip to content

Commit 7adaa7b

Browse files
committed
#4604 Reduce draw distance when low on RAM
1 parent b246834 commit 7adaa7b

File tree

4 files changed

+59
-16
lines changed

4 files changed

+59
-16
lines changed

indra/newview/llviewermessage.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3364,6 +3364,15 @@ void send_agent_update(bool force_send, bool send_reliable)
33643364
msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis());
33653365

33663366
static F32 last_draw_disatance_step = 1024;
3367+
F32 memory_limited_draw_distance = gAgentCamera.mDrawDistance;
3368+
3369+
if (LLViewerTexture::sDesiredDiscardBias > 2.f && LLViewerTexture::isSystemMemoryLow())
3370+
{
3371+
// If we are low on memory, reduce requested draw distace
3372+
memory_limited_draw_distance =
3373+
llmax(gAgentCamera.mDrawDistance / (LLViewerTexture::sDesiredDiscardBias - 1.f), memory_limited_draw_distance / 2.f);
3374+
}
3375+
33673376
if (tp_state == LLAgent::TELEPORT_ARRIVING || LLStartUp::getStartupState() < STATE_MISC)
33683377
{
33693378
// Inform interest list, prioritize closer area.
@@ -3372,25 +3381,25 @@ void send_agent_update(bool force_send, bool send_reliable)
33723381
// closer ones.
33733382
// Todo: revise and remove once server gets distance sorting.
33743383
last_draw_disatance_step = llmax((F32)(gAgentCamera.mDrawDistance / 2.f), 50.f);
3384+
last_draw_disatance_step = llmin(last_draw_disatance_step, memory_limited_draw_distance);
33753385
msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step);
33763386
}
3377-
else if (last_draw_disatance_step < gAgentCamera.mDrawDistance)
3387+
else if (last_draw_disatance_step < memory_limited_draw_distance)
33783388
{
33793389
static LLFrameTimer last_step_time;
33803390
if (last_step_time.getElapsedTimeF32() > 1.f)
33813391
{
33823392
// gradually increase draw distance
3383-
// Idealy this should be not per second, but based on how loaded
3384-
// mesh thread is, but hopefully this is temporary.
33853393
last_step_time.reset();
3386-
F32 step = gAgentCamera.mDrawDistance * 0.1f;
3387-
last_draw_disatance_step = llmin(last_draw_disatance_step + step, gAgentCamera.mDrawDistance);
3394+
F32 step = memory_limited_draw_distance * 0.1f;
3395+
last_draw_disatance_step = llmin(last_draw_disatance_step + step, memory_limited_draw_distance);
33883396
}
33893397
msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step);
33903398
}
33913399
else
33923400
{
3393-
msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance);
3401+
last_draw_disatance_step = memory_limited_draw_distance;
3402+
msg->addF32Fast(_PREHASH_Far, memory_limited_draw_distance);
33943403
}
33953404

33963405
msg->addU32Fast(_PREHASH_ControlFlags, control_flags);

indra/newview/llviewertexture.cpp

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -527,8 +527,16 @@ void LLViewerTexture::updateClass()
527527

528528
if (is_low && !was_low)
529529
{
530-
// slam to 1.5 bias the moment we hit low memory (discards off screen textures immediately)
531-
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f);
530+
if (is_sys_low)
531+
{
532+
// Not having system memory is more serious, so discard harder
533+
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f * getSystemMemoryBudgetFactor());
534+
}
535+
else
536+
{
537+
// Slam to 1.5 bias the moment we hit low memory (discards off screen textures immediately)
538+
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f);
539+
}
532540

533541
if (is_sys_low || over_pct > 2.f)
534542
{ // if we're low on system memory, emergency purge off screen textures to avoid a death spiral
@@ -627,24 +635,42 @@ void LLViewerTexture::updateClass()
627635
}
628636

629637
//static
630-
bool LLViewerTexture::isSystemMemoryLow()
638+
U32Megabytes LLViewerTexture::getFreeSystemMemory()
631639
{
632640
static LLFrameTimer timer;
633641
static U32Megabytes physical_res = U32Megabytes(U32_MAX);
634642

635-
static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512);
636-
const U32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory);
637-
638643
if (timer.getElapsedTimeF32() < MEMORY_CHECK_WAIT_TIME) //call this once per second.
639644
{
640-
return physical_res < MIN_FREE_MAIN_MEMORY;
645+
return physical_res;
641646
}
642647

643648
timer.reset();
644649

645650
LLMemory::updateMemoryInfo();
646651
physical_res = LLMemory::getAvailableMemKB();
647-
return physical_res < MIN_FREE_MAIN_MEMORY;
652+
return physical_res;
653+
}
654+
655+
//static
656+
bool LLViewerTexture::isSystemMemoryLow()
657+
{
658+
static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512);
659+
const U32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory);
660+
return getFreeSystemMemory() < MIN_FREE_MAIN_MEMORY;
661+
}
662+
663+
F32 LLViewerTexture::getSystemMemoryBudgetFactor()
664+
{
665+
static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512);
666+
const S32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory);
667+
S32 free_budget = (S32Megabytes)getFreeSystemMemory() - MIN_FREE_MAIN_MEMORY;
668+
if (free_budget < 0)
669+
{
670+
// should range from 1 to 2
671+
return 1.f - free_budget / MIN_FREE_MAIN_MEMORY;
672+
}
673+
return 1.f;
648674
}
649675

650676
//end of static functions

indra/newview/llviewertexture.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ class LLViewerTexture : public LLGLTexture
115115
static void initClass();
116116
static void updateClass();
117117
static bool isSystemMemoryLow();
118+
static F32 getSystemMemoryBudgetFactor();
118119

119120
LLViewerTexture(bool usemipmaps = true);
120121
LLViewerTexture(const LLUUID& id, bool usemipmaps) ;
@@ -189,6 +190,8 @@ class LLViewerTexture : public LLGLTexture
189190
friend class LLBumpImageList;
190191
friend class LLUIImageList;
191192

193+
static U32Megabytes getFreeSystemMemory();
194+
192195
protected:
193196
friend class LLViewerTextureList;
194197
LLUUID mID;

indra/newview/llvocache.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -486,14 +486,19 @@ void LLVOCacheEntry::updateDebugSettings()
486486
//min radius: all objects within this radius remain loaded in memory
487487
static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
488488
static const F32 MIN_RADIUS = 1.0f;
489-
const F32 draw_radius = gAgentCamera.mDrawDistance;
489+
490+
F32 draw_radius = gAgentCamera.mDrawDistance;
491+
if (LLViewerTexture::sDesiredDiscardBias > 2.f && LLViewerTexture::isSystemMemoryLow())
492+
{
493+
draw_radius = llmax(gAgentCamera.mDrawDistance / (LLViewerTexture::sDesiredDiscardBias - 1.f), draw_radius/2.f);
494+
}
490495
const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance]
491496
sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor);
492497

493498
// a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold
494499
static LLCachedControl<F32> rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction");
495500
const F32 min_radius_plus_one = sNearRadius + 1.f;
496-
const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance;
501+
const F32 max_radius = rear_max_radius_frac * draw_radius;
497502
const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance]
498503
sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor);
499504

0 commit comments

Comments
 (0)