diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llshadermgr.cpp | 59 | ||||
| -rw-r--r-- | indra/llrender/llshadermgr.h | 4 | ||||
| -rw-r--r-- | indra/newview/VIEWER_VERSION.txt | 2 | ||||
| -rw-r--r-- | indra/newview/installers/windows/installer_template.nsi | 86 | ||||
| -rw-r--r-- | indra/newview/llfloaterpreference.cpp | 28 | ||||
| -rw-r--r-- | indra/newview/llfloaterpreference.h | 1 | ||||
| -rw-r--r-- | indra/newview/llhudeffectresetskeleton.cpp | 9 | ||||
| -rw-r--r-- | indra/newview/llhudeffectresetskeleton.h | 13 | ||||
| -rw-r--r-- | indra/newview/llmeshrepository.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llreflectionmapmanager.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llstartup.cpp | 1 | ||||
| -rw-r--r-- | indra/newview/llviewermessage.cpp | 23 | ||||
| -rw-r--r-- | indra/newview/llviewershadermgr.cpp | 11 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.cpp | 51 | ||||
| -rw-r--r-- | indra/newview/llviewertexture.h | 3 | ||||
| -rw-r--r-- | indra/newview/llvocache.cpp | 13 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 2 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 11 |
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. |
