summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llrender/llshadermgr.cpp59
-rw-r--r--indra/llrender/llshadermgr.h4
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/installers/windows/installer_template.nsi86
-rw-r--r--indra/newview/llfloaterpreference.cpp28
-rw-r--r--indra/newview/llfloaterpreference.h1
-rw-r--r--indra/newview/llhudeffectresetskeleton.cpp9
-rw-r--r--indra/newview/llhudeffectresetskeleton.h13
-rw-r--r--indra/newview/llmeshrepository.cpp1
-rw-r--r--indra/newview/llreflectionmapmanager.cpp1
-rw-r--r--indra/newview/llstartup.cpp1
-rw-r--r--indra/newview/llviewermessage.cpp23
-rw-r--r--indra/newview/llviewershadermgr.cpp11
-rw-r--r--indra/newview/llviewertexture.cpp51
-rw-r--r--indra/newview/llviewertexture.h3
-rw-r--r--indra/newview/llvocache.cpp13
-rw-r--r--indra/newview/pipeline.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml11
18 files changed, 271 insertions, 48 deletions
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 725380b4b2..9cdd02f403 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -989,16 +989,17 @@ bool LLShaderMgr::validateProgramObject(GLuint obj)
return success;
}
-void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version)
+void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version, bool second_instance)
{
- LL_INFOS() << "Initializing shader cache" << LL_ENDL;
+ LL_PROFILE_ZONE_SCOPED;
+ LL_INFOS("ShaderMgr") << "Initializing shader cache" << LL_ENDL;
mShaderCacheEnabled = gGLManager.mGLVersion >= 4.09 && enabled;
- if(!mShaderCacheEnabled || mShaderCacheInitialized)
+ if(!mShaderCacheEnabled || mShaderCacheVersion.notNull())
return;
- mShaderCacheInitialized = true;
+ mShaderCacheVersion = current_cache_version;
mShaderCacheDir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache");
LLFile::mkdir(mShaderCacheDir);
@@ -1007,16 +1008,19 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version,
std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd");
if (gDirUtilp->fileExists(meta_out_path))
{
- LL_INFOS() << "Loading shader cache metadata" << LL_ENDL;
+ LL_PROFILE_ZONE_NAMED("shader_cache");
+ LL_INFOS("ShaderMgr") << "Loading shader cache metadata" << LL_ENDL;
- llifstream instream(meta_out_path);
+ llifstream instream(meta_out_path, std::ifstream::in | std::ifstream::binary);
LLSD in_data;
- LLSDSerialize::fromNotation(in_data, instream, LLSDSerialize::SIZE_UNLIMITED);
+ // todo: this is likely very expensive to parse, should use binary
+ LLSDSerialize::fromBinary(in_data, instream, LLSDSerialize::SIZE_UNLIMITED);
instream.close();
- if (old_cache_version == current_cache_version)
+ if (old_cache_version == current_cache_version
+ && in_data["version"].asUUID() == current_cache_version)
{
- for (const auto& data_pair : llsd::inMap(in_data))
+ for (const auto& data_pair : llsd::inMap(in_data["shaders"]))
{
ProgramBinaryData binary_info = ProgramBinaryData();
binary_info.mBinaryFormat = data_pair.second["binary_format"].asInteger();
@@ -1025,11 +1029,15 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version,
mShaderBinaryCache.insert_or_assign(LLUUID(data_pair.first), binary_info);
}
}
- else
+ else if (!second_instance)
{
- LL_INFOS() << "Shader cache version mismatch detected. Purging." << LL_ENDL;
+ LL_INFOS("ShaderMgr") << "Shader cache version mismatch detected. Purging." << LL_ENDL;
clearShaderCache();
}
+ else
+ {
+ LL_INFOS("ShaderMgr") << "Shader cache version mismatch detected." << LL_ENDL;
+ }
}
}
}
@@ -1037,7 +1045,7 @@ void LLShaderMgr::initShaderCache(bool enabled, const LLUUID& old_cache_version,
void LLShaderMgr::clearShaderCache()
{
std::string shader_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "shader_cache");
- LL_INFOS() << "Removing shader cache at " << shader_cache << LL_ENDL;
+ LL_INFOS("ShaderMgr") << "Removing shader cache at " << shader_cache << LL_ENDL;
const std::string mask = "*";
gDirUtilp->deleteFilesInDir(shader_cache, mask);
mShaderBinaryCache.clear();
@@ -1046,10 +1054,22 @@ void LLShaderMgr::clearShaderCache()
void LLShaderMgr::persistShaderCacheMetadata()
{
if(!mShaderCacheEnabled) return;
+ if (mShaderCacheVersion.isNull())
+ {
+ LL_WARNS("ShaderMgr") << "Attempted to save shader cache with no version set" << LL_ENDL;
+ return;
+ }
- LL_INFOS() << "Persisting shader cache metadata to disk" << LL_ENDL;
+ LL_INFOS("ShaderMgr") << "Persisting shader cache metadata to disk" << LL_ENDL;
- LLSD out = LLSD::emptyMap();
+ LLSD out;
+ // Settings and shader cache get saved at different time, thus making
+ // RenderShaderCacheVersion unreliable when running multiple viewer
+ // instances, or for cases where viewer crashes before saving settings.
+ // Dupplicate version to the cache itself.
+ out["version"] = mShaderCacheVersion;
+ out["shaders"] = LLSD::emptyMap();
+ LLSD &shaders = out["shaders"];
static const F32 LRU_TIME = (60.f * 60.f) * 24.f * 7.f; // 14 days
const F32 current_time = (F32)LLTimer::getTotalSeconds();
@@ -1068,14 +1088,19 @@ void LLShaderMgr::persistShaderCacheMetadata()
data["binary_format"] = LLSD::Integer(shader_metadata.mBinaryFormat);
data["binary_size"] = LLSD::Integer(shader_metadata.mBinaryLength);
data["last_used"] = LLSD::Real(shader_metadata.mLastUsedTime);
- out[it->first.asString()] = data;
+ shaders[it->first.asString()] = data;
++it;
}
}
std::string meta_out_path = gDirUtilp->add(mShaderCacheDir, "shaderdata.llsd");
- llofstream outstream(meta_out_path);
- LLSDSerialize::toNotation(out, outstream);
+ llofstream outstream(meta_out_path, std::ios_base::out | std::ios_base::binary);
+ if (!outstream.is_open())
+ {
+ LL_WARNS("ShaderMgr") << "Failed to open file. Unable to save shader cache to: " << mShaderCacheDir << LL_ENDL;
+ return;
+ }
+ LLSDSerialize::toBinary(out, outstream);
outstream.close();
}
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index 46788841a5..1b638e6e06 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -363,7 +363,7 @@ public:
// Implemented in the application to actually update out of date uniforms for a particular shader
virtual void updateShaderUniforms(LLGLSLShader * shader) = 0; // Pure Virtual
- void initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version);
+ void initShaderCache(bool enabled, const LLUUID& old_cache_version, const LLUUID& current_cache_version, bool second_instance);
void clearShaderCache();
void persistShaderCacheMetadata();
@@ -387,7 +387,7 @@ public:
F32 mLastUsedTime = 0.0;
};
std::map<LLUUID, ProgramBinaryData> mShaderBinaryCache;
- bool mShaderCacheInitialized = false;
+ LLUUID mShaderCacheVersion;
bool mShaderCacheEnabled = false;
std::string mShaderCacheDir;
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index b26a34e470..77f5bec5b2 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-7.2.1
+7.2.2
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 77f24ac6a6..0e36698018 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -164,6 +164,74 @@ Var DO_UNINSTALL_V2 # If non-null, path to a previous Viewer 2 installation
!include "x64.nsh" # for 64bit detection
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Substring function
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+!define StrStr "!insertmacro StrStr"
+
+!macro StrStr ResultVar String SubString
+ Push `${String}`
+ Push `${SubString}`
+ Call StrStr
+ Pop `${ResultVar}`
+!macroend
+
+Function StrStr
+
+# After this point:
+# ------------------------------------------
+# $R0 = SubString (input)
+# $R1 = String (input)
+# $R2 = SubStringLen (temp)
+# $R3 = StrLen (temp)
+# $R4 = StartCharPos (temp)
+# $R5 = TempStr (temp)
+# function from nsis.sourceforge.io/StrStr
+
+ ;Get input from user
+ Exch $R0
+ Exch
+ Exch $R1
+ Push $R2
+ Push $R3
+ Push $R4
+ Push $R5
+
+ ;Get "String" and "SubString" length
+ StrLen $R2 $R0
+ StrLen $R3 $R1
+ ;Start "StartCharPos" counter
+ StrCpy $R4 0
+
+ ;Loop until "SubString" is found or "String" reaches its end
+ ${Do}
+ ;Remove everything before and after the searched part ("TempStr")
+ StrCpy $R5 $R1 $R2 $R4
+
+ ;Compare "TempStr" with "SubString"
+ ${IfThen} $R5 == $R0 ${|} ${ExitDo} ${|}
+ ;If not "SubString", this could be "String"'s end
+ ${IfThen} $R4 >= $R3 ${|} ${ExitDo} ${|}
+ ;If not, continue the loop
+ IntOp $R4 $R4 + 1
+ ${Loop}
+
+# After this point:
+# ------------------------------------------
+# $R0 = ResultVar (output)
+
+ ;Remove part before "SubString" on "String" (if there has one)
+ StrCpy $R0 $R1 `` $R4
+
+ ;Return output to user
+ Pop $R5
+ Pop $R4
+ Pop $R3
+ Pop $R2
+ Pop $R1
+ Exch $R0
+FunctionEnd
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pre-directory page callback
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Function dirPre
@@ -190,15 +258,31 @@ Function .onInit
# However, SL-10506 complains about the resulting behavior, so the logic below
# is adapted from before we introduced MultiUser.nsh.
+# Check if user specified /D= on the command line
+System::Call 'kernel32::GetCommandLine()t .r0'
+Push $0
+Push " /D="
+Call StrStr
+Pop $1
+${If} $1 != ""
+ # /D= was specified, extract the path
+ # spaces are allowed in path after /D=, it's expected to be the last parameter
+ StrLen $2 $1
+ StrCpy $INSTDIR $1 $2 4 # Skip over " /D="
+ Goto after_instdir
+${EndIf}
+
# if $0 is empty, this is the first time for this viewer name
ReadRegStr $0 SHELL_CONTEXT "${INSTNAME_KEY}" ""
# viewer with this name was installed before
${If} $0 != ""
- # use the value we got from registry as install location
+ # use the value we got from registry as install location
StrCpy $INSTDIR $0
${EndIf}
+after_instdir:
+
Call CheckCPUFlags # Make sure we have SSE2 support
Call CheckWindowsVersion # Don't install On unsupported systems
Push $0
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index b74736a39d..291f22d78f 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -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();
@@ -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();
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 40806c22fc..a784d502ef 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -218,6 +218,7 @@ private:
bool mGotPersonalInfo;
bool mLanguageChanged;
bool mAvatarDataInitialized;
+ U32 mLastQualityLevel = 0;
std::string mPriorInstantMessageLogPath;
bool mOriginalHideOnlineStatus;
diff --git a/indra/newview/llhudeffectresetskeleton.cpp b/indra/newview/llhudeffectresetskeleton.cpp
index 31065a3e76..2bb5696f59 100644
--- a/indra/newview/llhudeffectresetskeleton.cpp
+++ b/indra/newview/llhudeffectresetskeleton.cpp
@@ -56,6 +56,15 @@ LLHUDEffectResetSkeleton::~LLHUDEffectResetSkeleton()
//-----------------------------------------------------------------------------
// packData()
//-----------------------------------------------------------------------------
+void LLHUDEffectResetSkeleton::render()
+{
+ // HUDEffectResetSkeleton is a fake effect meant to reset skeleton only.
+ // Just wait for an update() call to do its work and then die.
+}
+
+//-----------------------------------------------------------------------------
+// packData()
+//-----------------------------------------------------------------------------
void LLHUDEffectResetSkeleton::packData(LLMessageSystem *mesgsys)
{
// Pack the default data
diff --git a/indra/newview/llhudeffectresetskeleton.h b/indra/newview/llhudeffectresetskeleton.h
index 39a6137054..c89516d7fc 100644
--- a/indra/newview/llhudeffectresetskeleton.h
+++ b/indra/newview/llhudeffectresetskeleton.h
@@ -38,20 +38,21 @@ class LLHUDEffectResetSkeleton final : public LLHUDEffect
public:
friend class LLHUDObject;
- /*virtual*/ void markDead();
- /*virtual*/ void setSourceObject(LLViewerObject* objectp);
+ /*virtual*/ void markDead() override;
+ /*virtual*/ void setSourceObject(LLViewerObject* objectp) override;
- void setTargetObject(LLViewerObject *objp);
+ void setTargetObject(LLViewerObject *objp) override;
void setResetAnimations(bool enable){ mResetAnimations = enable; };
protected:
LLHUDEffectResetSkeleton(const U8 type);
~LLHUDEffectResetSkeleton();
- /*virtual*/ void packData(LLMessageSystem *mesgsys);
- /*virtual*/ void unpackData(LLMessageSystem *mesgsys, S32 blocknum);
+ void render() override;
+ void packData(LLMessageSystem *mesgsys) override;
+ void unpackData(LLMessageSystem *mesgsys, S32 blocknum) override;
- void update();
+ void update() override;
private:
bool mResetAnimations;
};
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 997fc28333..8d5f94cdbb 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -2310,6 +2310,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
}
if (request_skin)
{
+ LLMutexLock lock(mMutex);
mSkinRequests.push_back(UUIDBasedRequest(mesh_id));
}
}
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index c69d1a823b..eb7fe06e7d 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -145,7 +145,6 @@ static void touch_default_probe(LLReflectionMap* probe)
LLReflectionMapManager::LLReflectionMapManager()
{
mDynamicProbeCount = LL_MAX_REFLECTION_PROBE_COUNT;
- refreshSettings();
initCubeFree();
}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index ba7437798a..5df7eca5f5 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -397,6 +397,7 @@ bool idle_startup()
LL_WARNS_ONCE() << "gViewerWindow is not initialized" << LL_ENDL;
return false; // No world yet
}
+ LL_PROFILE_ZONE_SCOPED;
const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay");
static LLTimer timeout;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 7d39cc6059..d0e6af799c 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -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.
@@ -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);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index a0a9906724..a9c58d5a06 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -545,7 +545,11 @@ void LLViewerShaderMgr::setShaders()
gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString());
}
- initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version);
+ initShaderCache(
+ shader_cache_enabled,
+ old_cache_version,
+ current_cache_version,
+ LLAppViewer::instance()->isSecondInstance());
}
static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
@@ -703,7 +707,10 @@ void LLViewerShaderMgr::setShaders()
loaded = loaded && loadShadersDeferred();
llassert(loaded);
- persistShaderCacheMetadata();
+ if (!LLAppViewer::instance()->isSecondInstance())
+ {
+ persistShaderCacheMetadata();
+ }
if (gViewerWindow)
{
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 52939dbbae..7a25fb03a5 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -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
@@ -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);
@@ -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
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index f9311d85cb..d32c302d8e 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -115,6 +115,7 @@ public:
static void initClass();
static void updateClass();
static bool isSystemMemoryLow();
+ static F32 getSystemMemoryBudgetFactor();
LLViewerTexture(bool usemipmaps = true);
LLViewerTexture(const LLUUID& id, bool usemipmaps) ;
@@ -189,6 +190,8 @@ private:
friend class LLBumpImageList;
friend class LLUIImageList;
+ static U32Megabytes getFreeSystemMemory();
+
protected:
friend class LLViewerTextureList;
LLUUID mID;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 501828eee8..ac73c2def6 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -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);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9edfbf7a88..6413c08e44 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -426,6 +426,8 @@ void LLPipeline::init()
sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
+ mReflectionMapManager.refreshSettings();
+
mInitialized = true;
stop_glerror();
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index b182a241d8..7fc96af55d 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -12147,6 +12147,17 @@ Cannot create large prims that intersect other residents. Please re-try when ot
<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"
type="alert">
There was a problem saving the default object permissions: [REASON]. Please try setting the default permissions later.