Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions indra/newview/llfloaterpreference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)

// Forget previous language changes.
mLanguageChanged = false;
mLastQualityLevel = gSavedSettings.getU32("RenderQualityPerformance");

// Display selected maturity icons.
onChangeMaturity();
Expand Down Expand Up @@ -1327,6 +1328,33 @@ void LLFloaterPreference::onCommitWindowedMode()
void LLFloaterPreference::onChangeQuality(const LLSD& data)
{
U32 level = (U32)(data.asReal());
constexpr U32 LVL_HIGH = 4;
if (level >= LVL_HIGH && mLastQualityLevel < level)
{
constexpr U32 LOW_MEM_THRESHOLD = 4097;
U32 total_mem = (U32Megabytes)LLMemory::getMaxMemKB();
if (total_mem < LOW_MEM_THRESHOLD)
{
LLSD args;
args["TOTAL_MEM"] = LLSD::Integer(total_mem);
LLNotificationsUtil::add("PreferenceQualityWithLowMemory", args, LLSD(), [this](const LLSD& notification, const LLSD& response)
{
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
// If cancel pressed
if (option == 1)
{
constexpr U32 LVL_MED_PLUS = 3;
gSavedSettings.setU32("RenderQualityPerformance", LVL_MED_PLUS);
mLastQualityLevel = LVL_MED_PLUS;
LLFeatureManager::getInstance()->setGraphicsLevel(LVL_MED_PLUS, true);
refreshEnabledGraphics();
refresh();
}
}
);
}
}
mLastQualityLevel = level;
LLFeatureManager::getInstance()->setGraphicsLevel(level, true);
refreshEnabledGraphics();
refresh();
Expand Down
1 change: 1 addition & 0 deletions indra/newview/llfloaterpreference.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver,
bool mGotPersonalInfo;
bool mLanguageChanged;
bool mAvatarDataInitialized;
U32 mLastQualityLevel = 0;
std::string mPriorInstantMessageLogPath;

bool mOriginalHideOnlineStatus;
Expand Down
23 changes: 17 additions & 6 deletions indra/newview/llviewermessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3364,6 +3364,17 @@ void send_agent_update(bool force_send, bool send_reliable)
msg->addVector3Fast(_PREHASH_CameraUpAxis, LLViewerCamera::getInstance()->getUpAxis());

static F32 last_draw_disatance_step = 1024;
F32 memory_limited_draw_distance = gAgentCamera.mDrawDistance;

if (LLViewerTexture::sDesiredDiscardBias > 2.f && LLViewerTexture::isSystemMemoryLow())
{
// If we are low on memory, reduce requested draw distance
// Discard's bias is clamped to 4 so we need to check 2 to 4 range
// Factor is intended to go from 1.0 to 2.0
F32 factor = 1.f + (LLViewerTexture::sDesiredDiscardBias - 2.f) / 2.f;
memory_limited_draw_distance = llmax(gAgentCamera.mDrawDistance / factor, gAgentCamera.mDrawDistance / 2.f);
}

if (tp_state == LLAgent::TELEPORT_ARRIVING || LLStartUp::getStartupState() < STATE_MISC)
{
// Inform interest list, prioritize closer area.
Expand All @@ -3372,25 +3383,25 @@ void send_agent_update(bool force_send, bool send_reliable)
// closer ones.
// Todo: revise and remove once server gets distance sorting.
last_draw_disatance_step = llmax((F32)(gAgentCamera.mDrawDistance / 2.f), 50.f);
last_draw_disatance_step = llmin(last_draw_disatance_step, memory_limited_draw_distance);
msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step);
}
else if (last_draw_disatance_step < gAgentCamera.mDrawDistance)
else if (last_draw_disatance_step < memory_limited_draw_distance)
{
static LLFrameTimer last_step_time;
if (last_step_time.getElapsedTimeF32() > 1.f)
{
// gradually increase draw distance
// Idealy this should be not per second, but based on how loaded
// mesh thread is, but hopefully this is temporary.
last_step_time.reset();
F32 step = gAgentCamera.mDrawDistance * 0.1f;
last_draw_disatance_step = llmin(last_draw_disatance_step + step, gAgentCamera.mDrawDistance);
F32 step = memory_limited_draw_distance * 0.1f;
last_draw_disatance_step = llmin(last_draw_disatance_step + step, memory_limited_draw_distance);
}
msg->addF32Fast(_PREHASH_Far, last_draw_disatance_step);
}
else
{
msg->addF32Fast(_PREHASH_Far, gAgentCamera.mDrawDistance);
last_draw_disatance_step = memory_limited_draw_distance;
msg->addF32Fast(_PREHASH_Far, memory_limited_draw_distance);
}

msg->addU32Fast(_PREHASH_ControlFlags, control_flags);
Expand Down
51 changes: 41 additions & 10 deletions indra/newview/llviewertexture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,8 +527,16 @@ void LLViewerTexture::updateClass()

if (is_low && !was_low)
{
// slam to 1.5 bias the moment we hit low memory (discards off screen textures immediately)
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f);
if (is_sys_low)
{
// Not having system memory is more serious, so discard harder
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f * getSystemMemoryBudgetFactor());
}
else
{
// Slam to 1.5 bias the moment we hit low memory (discards off screen textures immediately)
sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.5f);
}

if (is_sys_low || over_pct > 2.f)
{ // if we're low on system memory, emergency purge off screen textures to avoid a death spiral
Expand Down Expand Up @@ -559,8 +567,13 @@ void LLViewerTexture::updateClass()
sEvaluationTimer.reset();

// lower discard bias over time when at least 10% of budget is free
const F32 FREE_PERCENTAGE_TRESHOLD = -0.1f;
if (sDesiredDiscardBias > 1.f && over_pct < FREE_PERCENTAGE_TRESHOLD)
constexpr F32 FREE_PERCENTAGE_TRESHOLD = -0.1f;
constexpr U32 FREE_SYS_MEM_TRESHOLD = 100;
static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512);
const S32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory() + FREE_SYS_MEM_TRESHOLD);
if (sDesiredDiscardBias > 1.f
&& over_pct < FREE_PERCENTAGE_TRESHOLD
&& getFreeSystemMemory() > MIN_FREE_MAIN_MEMORY)
{
static LLCachedControl<F32> high_mem_discard_decrement(gSavedSettings, "RenderHighMemMinDiscardDecrement", .1f);

Expand Down Expand Up @@ -627,24 +640,42 @@ void LLViewerTexture::updateClass()
}

//static
bool LLViewerTexture::isSystemMemoryLow()
U32Megabytes LLViewerTexture::getFreeSystemMemory()
{
static LLFrameTimer timer;
static U32Megabytes physical_res = U32Megabytes(U32_MAX);

static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512);
const U32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory);

if (timer.getElapsedTimeF32() < MEMORY_CHECK_WAIT_TIME) //call this once per second.
{
return physical_res < MIN_FREE_MAIN_MEMORY;
return physical_res;
}

timer.reset();

LLMemory::updateMemoryInfo();
physical_res = LLMemory::getAvailableMemKB();
return physical_res < MIN_FREE_MAIN_MEMORY;
return physical_res;
}

//static
bool LLViewerTexture::isSystemMemoryLow()
{
static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512);
const U32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory);
return getFreeSystemMemory() < MIN_FREE_MAIN_MEMORY;
}

F32 LLViewerTexture::getSystemMemoryBudgetFactor()
{
static LLCachedControl<U32> min_free_main_memory(gSavedSettings, "RenderMinFreeMainMemoryThreshold", 512);
const S32Megabytes MIN_FREE_MAIN_MEMORY(min_free_main_memory);
S32 free_budget = (S32Megabytes)getFreeSystemMemory() - MIN_FREE_MAIN_MEMORY;
if (free_budget < 0)
{
// Result should range from 1 (0 free budget) to 2 (-512 free budget)
return 1.f - free_budget / MIN_FREE_MAIN_MEMORY;
}
return 1.f;
}

//end of static functions
Expand Down
3 changes: 3 additions & 0 deletions indra/newview/llviewertexture.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class LLViewerTexture : public LLGLTexture
static void initClass();
static void updateClass();
static bool isSystemMemoryLow();
static F32 getSystemMemoryBudgetFactor();

LLViewerTexture(bool usemipmaps = true);
LLViewerTexture(const LLUUID& id, bool usemipmaps) ;
Expand Down Expand Up @@ -189,6 +190,8 @@ class LLViewerTexture : public LLGLTexture
friend class LLBumpImageList;
friend class LLUIImageList;

static U32Megabytes getFreeSystemMemory();

protected:
friend class LLViewerTextureList;
LLUUID mID;
Expand Down
13 changes: 11 additions & 2 deletions indra/newview/llvocache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -486,14 +486,23 @@ void LLVOCacheEntry::updateDebugSettings()
//min radius: all objects within this radius remain loaded in memory
static LLCachedControl<F32> min_radius(gSavedSettings,"SceneLoadMinRadius");
static const F32 MIN_RADIUS = 1.0f;
const F32 draw_radius = gAgentCamera.mDrawDistance;

F32 draw_radius = gAgentCamera.mDrawDistance;
if (LLViewerTexture::sDesiredDiscardBias > 2.f && LLViewerTexture::isSystemMemoryLow())
{
// Discard's bias maximum is 4 so we need to check 2 to 4 range
// Factor is intended to go from 1.0 to 2.0
F32 factor = 1.f + (LLViewerTexture::sDesiredDiscardBias - 2.f) / 2.f;
// For safety cap reduction at 50%, we don't want to go below half of draw distance
draw_radius = llmax(draw_radius / 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);

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

Expand Down
11 changes: 11 additions & 0 deletions indra/newview/skins/default/xui/en/notifications.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12145,6 +12145,17 @@ Cannot create large prims that intersect other residents. Please re-try when ot
yestext="OK"/>
</notification>

<notification
icon="alertmodal.tga"
name="PreferenceQualityWithLowMemory"
type="alert">
Your system has [TOTAL_MEM]MB of memory, which might not be enough to run viewer at higher settings and might result in issues.
<usetemplate
name="okcancelbuttons"
notext="Cancel"
yestext="Continue"/>
</notification>

<notification
icon="alertmodal.tga"
name="DefaultObjectPermissions"
Expand Down
Loading