@@ -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
@@ -559,8 +567,13 @@ void LLViewerTexture::updateClass()
559567 sEvaluationTimer .reset ();
560568
561569 // lower discard bias over time when at least 10% of budget is free
562- const F32 FREE_PERCENTAGE_TRESHOLD = -0 .1f ;
563- if (sDesiredDiscardBias > 1 .f && over_pct < FREE_PERCENTAGE_TRESHOLD)
570+ constexpr F32 FREE_PERCENTAGE_TRESHOLD = -0 .1f ;
571+ constexpr U32 FREE_SYS_MEM_TRESHOLD = 100 ;
572+ static LLCachedControl<U32> min_free_main_memory (gSavedSettings , " RenderMinFreeMainMemoryThreshold" , 512 );
573+ const S32Megabytes MIN_FREE_MAIN_MEMORY (min_free_main_memory () + FREE_SYS_MEM_TRESHOLD);
574+ if (sDesiredDiscardBias > 1 .f
575+ && over_pct < FREE_PERCENTAGE_TRESHOLD
576+ && getFreeSystemMemory () > MIN_FREE_MAIN_MEMORY)
564577 {
565578 static LLCachedControl<F32> high_mem_discard_decrement (gSavedSettings , " RenderHighMemMinDiscardDecrement" , .1f );
566579
@@ -627,24 +640,42 @@ void LLViewerTexture::updateClass()
627640}
628641
629642// static
630- bool LLViewerTexture::isSystemMemoryLow ()
643+ U32Megabytes LLViewerTexture::getFreeSystemMemory ()
631644{
632645 static LLFrameTimer timer;
633646 static U32Megabytes physical_res = U32Megabytes (U32_MAX);
634647
635- static LLCachedControl<U32> min_free_main_memory (gSavedSettings , " RenderMinFreeMainMemoryThreshold" , 512 );
636- const U32Megabytes MIN_FREE_MAIN_MEMORY (min_free_main_memory);
637-
638648 if (timer.getElapsedTimeF32 () < MEMORY_CHECK_WAIT_TIME) // call this once per second.
639649 {
640- return physical_res < MIN_FREE_MAIN_MEMORY ;
650+ return physical_res;
641651 }
642652
643653 timer.reset ();
644654
645655 LLMemory::updateMemoryInfo ();
646656 physical_res = LLMemory::getAvailableMemKB ();
647- return physical_res < MIN_FREE_MAIN_MEMORY;
657+ return physical_res;
658+ }
659+
660+ // static
661+ bool LLViewerTexture::isSystemMemoryLow ()
662+ {
663+ static LLCachedControl<U32> min_free_main_memory (gSavedSettings , " RenderMinFreeMainMemoryThreshold" , 512 );
664+ const U32Megabytes MIN_FREE_MAIN_MEMORY (min_free_main_memory);
665+ return getFreeSystemMemory () < MIN_FREE_MAIN_MEMORY;
666+ }
667+
668+ F32 LLViewerTexture::getSystemMemoryBudgetFactor ()
669+ {
670+ static LLCachedControl<U32> min_free_main_memory (gSavedSettings , " RenderMinFreeMainMemoryThreshold" , 512 );
671+ const S32Megabytes MIN_FREE_MAIN_MEMORY (min_free_main_memory);
672+ S32 free_budget = (S32Megabytes)getFreeSystemMemory () - MIN_FREE_MAIN_MEMORY;
673+ if (free_budget < 0 )
674+ {
675+ // should range from 1 to 2
676+ return 1 .f - free_budget / MIN_FREE_MAIN_MEMORY;
677+ }
678+ return 1 .f ;
648679}
649680
650681// end of static functions
0 commit comments