From eaa4d07c611d5487e79d94b037465d490bfded5b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 18 Dec 2024 11:45:43 -0800 Subject: [PATCH 01/83] #3301 Don't crash on invalid visual parameter update. (#3303) --- indra/llappearance/llwearable.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp index a7e5292fed..f30c147b91 100644 --- a/indra/llappearance/llwearable.cpp +++ b/indra/llappearance/llwearable.cpp @@ -652,7 +652,7 @@ void LLWearable::setVisualParamWeight(S32 param_index, F32 value) } else { - LL_ERRS() << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL; + LL_WARNS() << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL; } } @@ -665,7 +665,7 @@ F32 LLWearable::getVisualParamWeight(S32 param_index) const } else { - LL_WARNS() << "LLWerable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL; + LL_WARNS() << "LLWearable::getVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << LL_ENDL; } return (F32)-1.0; } From 7aca014ebc8c51aa07109eaf7dc77cbfee81c742 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 18 Dec 2024 12:00:11 -0800 Subject: [PATCH 02/83] #3305 Don't crash on invalid texture index in getTEWearableType (#3306) --- indra/llappearance/llavatarappearancedefines.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp index 5f98f2c8c1..47798844bc 100644 --- a/indra/llappearance/llavatarappearancedefines.cpp +++ b/indra/llappearance/llavatarappearancedefines.cpp @@ -300,7 +300,8 @@ EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::strin LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index ) const { - return getTexture(index)->mWearableType; + auto* tex = getTexture(index); + return tex ? tex->mWearableType : LLWearableType::WT_INVALID; } // static From c88a7d1d274b090f5ca7484a8b1f3ccc36aa1980 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Thu, 19 Dec 2024 17:06:34 +0200 Subject: [PATCH 03/83] #3302 fix crash on changing filter string when content is loading or there is no object selected --- indra/llui/llfolderview.h | 1 + indra/newview/llpanelcontents.cpp | 55 ++++++++++++++++---------- indra/newview/llpanelcontents.h | 2 + indra/newview/llpanelobjectinventory.h | 2 + 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h index 62ef2a0626..82637e33ea 100644 --- a/indra/llui/llfolderview.h +++ b/indra/llui/llfolderview.h @@ -414,6 +414,7 @@ public: virtual void doItem(LLFolderViewItem* item) {} void setApply(bool apply); void clearOpenFolders() { mOpenFolders.clear(); } + bool hasOpenFolders() { return !mOpenFolders.empty(); } protected: std::set mOpenFolders; bool mApply; diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index dbf56c2b6d..2624ef1207 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -139,32 +139,47 @@ void LLPanelContents::getState(LLViewerObject *objectp ) void LLPanelContents::onFilterEdit() { const std::string& filter_substring = mFilterEditor->getText(); - if (filter_substring.empty()) + if (!mPanelInventoryObject->hasInventory()) { - if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) - { - // The current filter and the new filter are empty, nothing to do - return; - } - - mSavedFolderState.setApply(true); - mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); - - // Add a folder with the current item to the list of previously opened folders - LLOpenFoldersWithSelection opener; - mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(opener); - mPanelInventoryObject->getRootFolder()->scrollToShowSelection(); + mDirtyFilter = true; } - else if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) + else { - // The first letter in search term, save existing folder open state - if (!mPanelInventoryObject->getFilter().isNotDefault()) + if (filter_substring.empty()) { - mSavedFolderState.setApply(false); - mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); + if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) + { + // The current filter and the new filter are empty, nothing to do + return; + } + + if (mDirtyFilter && !mSavedFolderState.hasOpenFolders()) + { + mPanelInventoryObject->getRootFolder()->setOpenArrangeRecursively(true, LLFolderViewFolder::ERecurseType::RECURSE_DOWN); + } + else + { + mSavedFolderState.setApply(true); + mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); + } + mDirtyFilter = false; + + // Add a folder with the current item to the list of previously opened folders + LLOpenFoldersWithSelection opener; + mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(opener); + mPanelInventoryObject->getRootFolder()->scrollToShowSelection(); + } + else if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) + { + // The first letter in search term, save existing folder open state + if (!mPanelInventoryObject->getFilter().isNotDefault()) + { + mSavedFolderState.setApply(false); + mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); + mDirtyFilter = false; + } } } - mPanelInventoryObject->getFilter().setFilterSubString(filter_substring); } diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h index bb6308e8b8..6e02b17bab 100644 --- a/indra/newview/llpanelcontents.h +++ b/indra/newview/llpanelcontents.h @@ -70,6 +70,8 @@ protected: void getState(LLViewerObject *object); void onFilterEdit(); + bool mDirtyFilter { false }; + public: class LLFilterEditor* mFilterEditor; LLSaveFolderState mSavedFolderState; diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index abb48dbeed..154639e4bb 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -85,6 +85,8 @@ public: static void idle(void* user_data); + bool hasInventory(){ return mHaveInventory; }; + protected: void reset(); /*virtual*/ void inventoryChanged(LLViewerObject* object, From a27515748fd1fd14a12ffc7f12b415decf6099de Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Jan 2025 17:31:23 +0200 Subject: [PATCH 04/83] #3311 RenderSkyAutoAdjustLegacy does not engage tonemapper --- indra/llinventory/llsettingssky.cpp | 22 +++++++++++----------- indra/llinventory/llsettingssky.h | 8 ++++---- indra/newview/llsettingsvo.cpp | 2 +- indra/newview/pipeline.cpp | 14 +++++++------- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp index 50b458de14..be64578d54 100644 --- a/indra/llinventory/llsettingssky.cpp +++ b/indra/llinventory/llsettingssky.cpp @@ -2032,43 +2032,43 @@ F32 LLSettingsSky::getGamma() const return mGamma; } -F32 LLSettingsSky::getHDRMin() const +F32 LLSettingsSky::getHDRMin(bool auto_adjust) const { - if (mCanAutoAdjust) + if (mCanAutoAdjust && !auto_adjust) return 0.f; return mHDRMin; } -F32 LLSettingsSky::getHDRMax() const +F32 LLSettingsSky::getHDRMax(bool auto_adjust) const { - if (mCanAutoAdjust) + if (mCanAutoAdjust && !auto_adjust) return 0.f; return mHDRMax; } -F32 LLSettingsSky::getHDROffset() const +F32 LLSettingsSky::getHDROffset(bool auto_adjust) const { - if (mCanAutoAdjust) + if (mCanAutoAdjust && !auto_adjust) return 1.0f; return mHDROffset; } -F32 LLSettingsSky::getTonemapMix() const +F32 LLSettingsSky::getTonemapMix(bool auto_adjust) const { - if (mCanAutoAdjust) + if (mCanAutoAdjust && !auto_adjust) + { + // legacy settings do not support tonemaping return 0.0f; + } return mTonemapMix; } void LLSettingsSky::setTonemapMix(F32 mix) { - if (mCanAutoAdjust) - return; - mTonemapMix = mix; } diff --git a/indra/llinventory/llsettingssky.h b/indra/llinventory/llsettingssky.h index 4c635fd946..801fafff4b 100644 --- a/indra/llinventory/llsettingssky.h +++ b/indra/llinventory/llsettingssky.h @@ -209,10 +209,10 @@ public: F32 getGamma() const; - F32 getHDRMin() const; - F32 getHDRMax() const; - F32 getHDROffset() const; - F32 getTonemapMix() const; + F32 getHDRMin(bool auto_adjust = false) const; + F32 getHDRMax(bool auto_adjust = false) const; + F32 getHDROffset(bool auto_adjust = false) const; + F32 getTonemapMix(bool auto_adjust = false) const; void setTonemapMix(F32 mix); void setGamma(F32 val); diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index cf96072ae2..6f9d4a24bc 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -807,7 +807,7 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) static LLCachedControl tonemap_mix_setting(gSavedSettings, "RenderTonemapMix", 1.f); // sky is a "classic" sky following pre SL 7.0 shading - bool classic_mode = psky->canAutoAdjust(); + bool classic_mode = psky->canAutoAdjust() && !should_auto_adjust(); if (!classic_mode) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1ca67dd88a..38f158c1df 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7076,7 +7076,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky(); - F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust); + F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust()); F32 exp_min = 1.f; F32 exp_max = 1.f; @@ -7087,13 +7087,13 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool { if (dynamic_exposure_enabled) { - exp_min = sky->getHDROffset() - sky->getHDRMin(); - exp_max = sky->getHDROffset() + sky->getHDRMax(); + exp_min = sky->getHDROffset(should_auto_adjust()) - sky->getHDRMin(should_auto_adjust()); + exp_max = sky->getHDROffset(should_auto_adjust()) + sky->getHDRMax(should_auto_adjust()); } else { - exp_min = sky->getHDROffset(); - exp_max = sky->getHDROffset(); + exp_min = sky->getHDROffset(should_auto_adjust()); + exp_max = sky->getHDROffset(should_auto_adjust()); } } else if (dynamic_exposure_enabled) @@ -7113,7 +7113,7 @@ void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst, bool shader->uniform1f(dt, gFrameIntervalSeconds); shader->uniform2f(noiseVec, ll_frand() * 2.0f - 1.0f, ll_frand() * 2.0f - 1.0f); shader->uniform4f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max, dynamic_exposure_speed_error); - shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(), exp_min, exp_max, dynamic_exposure_speed_target); + shader->uniform4f(dynamic_exposure_params2, sky->getHDROffset(should_auto_adjust()), exp_min, exp_max, dynamic_exposure_speed_target); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -7171,7 +7171,7 @@ void LLPipeline::tonemap(LLRenderTarget* src, LLRenderTarget* dst) static LLCachedControl tonemap_type_setting(gSavedSettings, "RenderTonemapType", 0U); shader.uniform1i(tonemap_type, tonemap_type_setting); - shader.uniform1f(tonemap_mix, psky->getTonemapMix()); + shader.uniform1f(tonemap_mix, psky->getTonemapMix(should_auto_adjust())); mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); From cba1807a9164442880dbcbd48e1faff7a82153c7 Mon Sep 17 00:00:00 2001 From: "Jonathan \"Geenz\" Goodman" Date: Thu, 2 Jan 2025 14:42:49 -0500 Subject: [PATCH 05/83] #3326 Skip ambient probe sampling when we're in classic mode. Ensure that our passed in ambient lighting is the only thing that gets applied. (#3327) --- .../shaders/class3/deferred/reflectionProbeF.glsl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 5dfa196cf6..a975b1f121 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -38,6 +38,8 @@ uniform float max_probe_lod; uniform bool transparent_surface; +uniform int classic_mode; + #define MAX_REFMAP_COUNT 256 // must match LL_MAX_REFLECTION_PROBE_COUNT layout (std140) uniform ReflectionProbes @@ -739,7 +741,10 @@ void doProbeSample(inout vec3 ambenv, inout vec3 glossenv, vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - ambenv = sampleProbeAmbient(pos, norm, amblit); + ambenv = amblit; + + if (classic_mode == 0) + ambenv = sampleProbeAmbient(pos, norm, amblit); float lod = (1.0-glossiness)*reflection_lods; glossenv = sampleProbes(pos, normalize(refnormpersp), lod); @@ -845,7 +850,10 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 refnormpersp = reflect(pos.xyz, norm.xyz); - ambenv = sampleProbeAmbient(pos, norm, amblit); + ambenv = amblit; + + if (classic_mode == 0) + ambenv = sampleProbeAmbient(pos, norm, amblit); if (glossiness > 0.0) { From a259316dc6212744194f340246b840e0a42b0191 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Jan 2025 23:01:14 +0200 Subject: [PATCH 06/83] #3329 Crash at LLSpatialGroup::dirtyGeom --- indra/newview/llvovolume.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6514db0814..99f31f33df 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -645,8 +645,12 @@ void LLVOVolume::animateTextures() // LLVOVolume::updateTextureVirtualSize when the // mTextureMatrix is not yet present gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); - mDrawable->getSpatialGroup()->dirtyGeom(); - gPipeline.markRebuild(mDrawable->getSpatialGroup()); + LLSpatialGroup* group = mDrawable->getSpatialGroup(); + if (group) + { + group->dirtyGeom(); + gPipeline.markRebuild(group); + } } } From 85162a4f609efaf3aa7412c6cd422f3900ba0cb3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Jan 2025 23:08:38 +0200 Subject: [PATCH 07/83] #3302 Crash at LLSaveFolderState::doFolder --- indra/newview/llpanelcontents.cpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp index 2624ef1207..7910bcb41d 100644 --- a/indra/newview/llpanelcontents.cpp +++ b/indra/newview/llpanelcontents.cpp @@ -145,6 +145,7 @@ void LLPanelContents::onFilterEdit() } else { + LLFolderView* root_folder = mPanelInventoryObject->getRootFolder(); if (filter_substring.empty()) { if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) @@ -155,19 +156,28 @@ void LLPanelContents::onFilterEdit() if (mDirtyFilter && !mSavedFolderState.hasOpenFolders()) { - mPanelInventoryObject->getRootFolder()->setOpenArrangeRecursively(true, LLFolderViewFolder::ERecurseType::RECURSE_DOWN); + if (root_folder) + { + root_folder->setOpenArrangeRecursively(true, LLFolderViewFolder::ERecurseType::RECURSE_DOWN); + } } else { mSavedFolderState.setApply(true); - mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); + if (root_folder) + { + root_folder->applyFunctorRecursively(mSavedFolderState); + } } mDirtyFilter = false; // Add a folder with the current item to the list of previously opened folders - LLOpenFoldersWithSelection opener; - mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(opener); - mPanelInventoryObject->getRootFolder()->scrollToShowSelection(); + if (root_folder) + { + LLOpenFoldersWithSelection opener; + root_folder->applyFunctorRecursively(opener); + root_folder->scrollToShowSelection(); + } } else if (mPanelInventoryObject->getFilter().getFilterSubString().empty()) { @@ -175,7 +185,10 @@ void LLPanelContents::onFilterEdit() if (!mPanelInventoryObject->getFilter().isNotDefault()) { mSavedFolderState.setApply(false); - mPanelInventoryObject->getRootFolder()->applyFunctorRecursively(mSavedFolderState); + if (root_folder) + { + root_folder->applyFunctorRecursively(mSavedFolderState); + } mDirtyFilter = false; } } From edebc8f7a785be10753eb0b826b5fac3905e34ca Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 6 Jan 2025 17:54:23 +0200 Subject: [PATCH 08/83] #3344 Crash at LLFloater::openFloater --- indra/newview/llstartup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index b32b80331a..3726a95f64 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1507,7 +1507,7 @@ bool idle_startup() // create a container's instance for start a controlling conversation windows // by the voice's events LLFloaterIMContainer *im_inst = LLFloaterIMContainer::getInstance(); - if(gAgent.isFirstLogin()) + if(gAgent.isFirstLogin() && im_inst) { im_inst->openFloater(im_inst->getKey()); } From 12303e21c9bfa6a32bef2a6a5f2f5a7978356b50 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 6 Jan 2025 22:54:59 +0200 Subject: [PATCH 09/83] #3347 Crashes in LLFontFreetype::renderGlyph Try to handle this more gracefully, but primary purpose of this change is to log wchars in case issue is reproducible. --- indra/llrender/llfontfreetype.cpp | 25 +++++++++++++++++++++---- indra/llrender/llfontfreetype.h | 2 +- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 6128e03fa7..1f14d82bf1 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -552,7 +552,7 @@ LLFontGlyphInfo* LLFontFreetype::addGlyphFromFont(const LLFontFreetype *fontp, l return NULL; llassert(!mIsFallback); - fontp->renderGlyph(requested_glyph_type, glyph_index); + fontp->renderGlyph(requested_glyph_type, glyph_index, wch); EFontGlyphType bitmap_glyph_type = EFontGlyphType::Unspecified; switch (fontp->mFTFace->glyph->bitmap.pixel_mode) @@ -697,7 +697,7 @@ void LLFontFreetype::insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const } } -void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const +void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const { if (mFTFace == NULL) return; @@ -712,11 +712,28 @@ void LLFontFreetype::renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) co FT_Error error = FT_Load_Glyph(mFTFace, glyph_index, load_flags); if (FT_Err_Ok != error) { + if (error == FT_Err_Out_Of_Memory) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS() << "Out of memory loading glyph for character " << wch << LL_ENDL; + } + std::string message = llformat( - "Error %d (%s) loading glyph %u: bitmap_type=%u, load_flags=%d", - error, FT_Error_String(error), glyph_index, bitmap_type, load_flags); + "Error %d (%s) loading wchar %u glyph %u/%u: bitmap_type=%u, load_flags=%d", + error, FT_Error_String(error), wch, glyph_index, mFTFace->num_glyphs, bitmap_type, load_flags); LL_WARNS_ONCE() << message << LL_ENDL; error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR); + if (FT_Err_Invalid_Outline == error + || FT_Err_Invalid_Composite == error + || (FT_Err_Ok != error && LLStringOps::isEmoji(wch))) + { + glyph_index = FT_Get_Char_Index(mFTFace, '?'); + // if '?' is not present, potentially can use last index, that's supposed to be null glyph + if (glyph_index > 0) + { + error = FT_Load_Glyph(mFTFace, glyph_index, load_flags ^ FT_LOAD_COLOR); + } + } llassert_always_msg(FT_Err_Ok == error, message.c_str()); } diff --git a/indra/llrender/llfontfreetype.h b/indra/llrender/llfontfreetype.h index eba89f5def..1ad795060a 100644 --- a/indra/llrender/llfontfreetype.h +++ b/indra/llrender/llfontfreetype.h @@ -156,7 +156,7 @@ private: bool hasGlyph(llwchar wch) const; // Has a glyph for this character LLFontGlyphInfo* addGlyph(llwchar wch, EFontGlyphType glyph_type) const; // Add a new character to the font if necessary LLFontGlyphInfo* addGlyphFromFont(const LLFontFreetype *fontp, llwchar wch, U32 glyph_index, EFontGlyphType bitmap_type) const; // Add a glyph from this font to the other (returns the glyph_index, 0 if not found) - void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index) const; + void renderGlyph(EFontGlyphType bitmap_type, U32 glyph_index, llwchar wch) const; void insertGlyphInfo(llwchar wch, LLFontGlyphInfo* gi) const; std::string mName; From 97b1ab3455fe0fa7980441ba8d5954a233bf51e9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 7 Jan 2025 17:20:06 +0200 Subject: [PATCH 10/83] #3360 Crash in LLReflectionMapManager::update() --- indra/newview/llreflectionmapmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 8f75b108cc..4a2ecee694 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -306,7 +306,7 @@ void LLReflectionMapManager::update() LLReflectionMap* probe = mProbes[i]; llassert(probe != nullptr); - if (probe->mCubeIndex != -1 && mUpdatingProbe != probe) + if (probe && probe->mCubeIndex != -1 && mUpdatingProbe != probe) { // free this index mCubeFree.push_back(probe->mCubeIndex); From 98473aa0c090447f0bd81630f40da7cb0ce9cf1a Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Wed, 8 Jan 2025 21:34:04 +0200 Subject: [PATCH 11/83] #3349 keep object selection after showing confirmation dialog --- indra/newview/llviewermenu.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 80c75ec919..d92faf4d1b 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -5199,15 +5199,16 @@ void handle_take(bool take_separate) // MAINT-290 // Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez. // Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened - params.functor.function([take_separate](const LLSD ¬ification, const LLSD &response) + LLObjectSelectionHandle obj_selection = LLSelectMgr::instance().getSelection(); + params.functor.function([take_separate, obj_selection](const LLSD ¬ification, const LLSD &response) { if (take_separate) { - confirm_take_separate(notification, response, LLSelectMgr::instance().getSelection()); + confirm_take_separate(notification, response, obj_selection); } else { - confirm_take(notification, response, LLSelectMgr::instance().getSelection()); + confirm_take(notification, response, obj_selection); } }); From 8d57388a9ec67c6fb4dc2a17c0317f71ea294681 Mon Sep 17 00:00:00 2001 From: Rye Date: Thu, 9 Jan 2025 20:02:54 -0500 Subject: [PATCH 12/83] Fix world going black and white in certain locations on apple gpu (#2558) --- indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl | 2 +- .../newview/app_settings/shaders/class3/deferred/materialF.glsl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 3e702f26be..cc9d72fae6 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -150,7 +150,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec float amb_da = 0.0;//ambiance; if (da > 0) { - lit = max(da * dist_atten,0.0); + lit = clamp(da * dist_atten, 0.0, 1.0); col = lit * light_col * diffuse; amb_da += (da*0.5+0.5) * ambiance; } diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index 7f871c0d5e..5708fc319f 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -140,7 +140,7 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spe float amb_da = ambiance; if (da >= 0) { - lit = max(da * dist_atten, 0.0); + lit = clamp(da * dist_atten, 0.0, 1.0); col = lit * light_col * diffuse; amb_da += (da*0.5 + 0.5) * ambiance; } From c883c7f2d97787c8db0050b1cfac9c22cb5e2309 Mon Sep 17 00:00:00 2001 From: Rye Date: Thu, 9 Jan 2025 20:43:45 -0500 Subject: [PATCH 13/83] Drop reflection probes and mirrors to RGBA8 when hdr is disabled to minimize vram usage and chance of probe nans (#2558) --- indra/llrender/llcubemaparray.cpp | 6 +++++- indra/llrender/llcubemaparray.h | 2 +- indra/newview/llheroprobemanager.cpp | 10 +++++++--- indra/newview/llreflectionmapmanager.cpp | 12 ++++++++---- indra/newview/llviewercontrol.cpp | 6 ++++-- 5 files changed, 25 insertions(+), 11 deletions(-) diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp index 4f5e13765a..635f079581 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -109,7 +109,7 @@ LLCubeMapArray::~LLCubeMapArray() { } -void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips) +void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool use_mips, bool hdr) { U32 texname = 0; mWidth = resolution; @@ -128,6 +128,10 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, bool us free_cur_tex_image(); U32 format = components == 4 ? GL_RGBA16F : GL_RGB16F; + if (!hdr) + { + format = components == 4 ? GL_RGBA8 : GL_RGB8; + } U32 mip = 0; U32 mip_resolution = resolution; while (mip_resolution >= 1) diff --git a/indra/llrender/llcubemaparray.h b/indra/llrender/llcubemaparray.h index 675aaaf07c..bfc72a321d 100644 --- a/indra/llrender/llcubemaparray.h +++ b/indra/llrender/llcubemaparray.h @@ -52,7 +52,7 @@ public: // components - number of components per pixel // count - number of cube maps in the array // use_mips - if true, mipmaps will be allocated for this cube map array and anisotropic filtering will be used - void allocate(U32 res, U32 components, U32 count, bool use_mips = true); + void allocate(U32 res, U32 components, U32 count, bool use_mips = true, bool hdr = true); void bind(S32 stage); void unbind(); diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index ce419498cf..aa6371eff4 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -89,9 +89,11 @@ void LLHeroProbeManager::update() initReflectionMaps(); + static LLCachedControl render_hdr(gSavedSettings, "RenderHDREnabled", true); + if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGBA16F; + U32 color_fmt = render_hdr ? GL_RGBA16F : GL_RGBA8; mRenderTarget.allocate(mProbeResolution, mProbeResolution, color_fmt, true); } @@ -103,7 +105,7 @@ void LLHeroProbeManager::update() mMipChain.resize(count); for (U32 i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGBA16F); + mMipChain[i].allocate(res, res, render_hdr ? GL_RGBA16F : GL_RGBA8); res /= 2; } } @@ -537,8 +539,10 @@ void LLHeroProbeManager::initReflectionMaps() mTexture = new LLCubeMapArray(); + static LLCachedControl render_hdr(gSavedSettings, "RenderHDREnabled", true); + // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); + mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr); if (mDefaultProbe.isNull()) { diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 4a2ecee694..4760ab376e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -223,9 +223,11 @@ void LLReflectionMapManager::update() initReflectionMaps(); + static LLCachedControl render_hdr(gSavedSettings, "RenderHDREnabled", true); + if (!mRenderTarget.isComplete()) { - U32 color_fmt = GL_RGB16F; + U32 color_fmt = render_hdr ? GL_RGBA16F : GL_RGBA8; U32 targetRes = mProbeResolution * 4; // super sample mRenderTarget.allocate(targetRes, targetRes, color_fmt, true); } @@ -238,7 +240,7 @@ void LLReflectionMapManager::update() mMipChain.resize(count); for (U32 i = 0; i < count; ++i) { - mMipChain[i].allocate(res, res, GL_RGB16F); + mMipChain[i].allocate(res, res, render_hdr ? GL_RGB16F : GL_RGB8); res /= 2; } } @@ -1415,11 +1417,13 @@ void LLReflectionMapManager::initReflectionMaps() { mTexture = new LLCubeMapArray(); + static LLCachedControl render_hdr(gSavedSettings, "RenderHDREnabled", true); + // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source) - mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2); + mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2, true, render_hdr); mIrradianceMaps = new LLCubeMapArray(); - mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false); + mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, false, render_hdr); } // reset probe state diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 18746e76fc..d4a033bd42 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -261,6 +261,8 @@ static bool handleDisableVintageMode(const LLSD& newvalue) static bool handleEnableHDR(const LLSD& newvalue) { + gPipeline.mReflectionMapManager.reset(); + gPipeline.mHeroProbeManager.reset(); return handleReleaseGLBufferChanged(newvalue) && handleSetShaderChanged(newvalue); } @@ -448,11 +450,11 @@ static bool handleReflectionProbeDetailChanged(const LLSD& newvalue) if (gPipeline.isInit()) { LLPipeline::refreshCachedSettings(); + gPipeline.mReflectionMapManager.reset(); + gPipeline.mHeroProbeManager.reset(); gPipeline.releaseGLBuffers(); gPipeline.createGLBuffers(); LLViewerShaderMgr::instance()->setShaders(); - gPipeline.mReflectionMapManager.reset(); - gPipeline.mHeroProbeManager.reset(); } return true; } From 4ff1cbfbfffe17edbbf4e3b5a6c3984a0618c7ad Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 10 Jan 2025 20:13:21 +0200 Subject: [PATCH 14/83] #3316 Crash in LLReflectionMap::getIsDynamic() --- indra/newview/llheroprobemanager.cpp | 5 +++-- indra/newview/llreflectionmap.cpp | 27 +++++++++++++++------------ indra/newview/llreflectionmap.h | 12 ++++++------ 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/indra/newview/llheroprobemanager.cpp b/indra/newview/llheroprobemanager.cpp index aa6371eff4..e754de2fd1 100644 --- a/indra/newview/llheroprobemanager.cpp +++ b/indra/newview/llheroprobemanager.cpp @@ -222,7 +222,7 @@ void LLHeroProbeManager::renderProbes() static LLCachedControl sUpdateRate(gSavedSettings, "RenderHeroProbeUpdateRate", 0); F32 near_clip = 0.01f; - if (mNearestHero != nullptr && + if (mNearestHero != nullptr && !mNearestHero->isDead() && !gTeleportDisplay && !gDisconnected && !LLAppViewer::instance()->logoutRequestSent()) { LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("hpmu - realtime"); @@ -251,12 +251,13 @@ void LLHeroProbeManager::renderProbes() LL_PROFILE_ZONE_NUM(gFrameCount % rate); LL_PROFILE_ZONE_NUM(rate); + bool dynamic = mNearestHero->getReflectionProbeIsDynamic() && sDetail() > 0; for (U32 i = 0; i < 6; ++i) { if ((gFrameCount % rate) == (i % rate)) { // update 6/rate faces per frame LL_PROFILE_ZONE_NUM(i); - updateProbeFace(mProbes[0], i, mNearestHero->getReflectionProbeIsDynamic() && sDetail > 0, near_clip); + updateProbeFace(mProbes[0], i, dynamic, near_clip); } } generateRadiance(mProbes[0]); diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index f77d37f821..1196d138e9 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -65,8 +65,9 @@ void LLReflectionMap::update(U32 resolution, U32 face, bool force_dynamic, F32 n } F32 clip = (near_clip > 0) ? near_clip : getNearClip(); + bool dynamic = force_dynamic || getIsDynamic(); - gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, getIsDynamic() || force_dynamic, useClipPlane, clipPlane); + gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, clip, dynamic, useClipPlane, clipPlane); } void LLReflectionMap::autoAdjustOrigin() @@ -185,7 +186,7 @@ void LLReflectionMap::autoAdjustOrigin() } } -bool LLReflectionMap::intersects(LLReflectionMap* other) +bool LLReflectionMap::intersects(LLReflectionMap* other) const { LLVector4a delta; delta.setSub(other->mOrigin, mOrigin); @@ -201,24 +202,24 @@ bool LLReflectionMap::intersects(LLReflectionMap* other) extern LLControlGroup gSavedSettings; -F32 LLReflectionMap::getAmbiance() +F32 LLReflectionMap::getAmbiance() const { F32 ret = 0.f; - if (mViewerObject && mViewerObject->getVolume()) + if (mViewerObject && mViewerObject->getVolumeConst()) { - ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance(); + ret = mViewerObject->getReflectionProbeAmbiance(); } return ret; } -F32 LLReflectionMap::getNearClip() +F32 LLReflectionMap::getNearClip() const { const F32 MINIMUM_NEAR_CLIP = 0.1f; F32 ret = 0.f; - if (mViewerObject && mViewerObject->getVolume()) + if (mViewerObject && mViewerObject->getVolumeConst()) { ret = mViewerObject->getReflectionProbeNearClip(); } @@ -234,11 +235,13 @@ F32 LLReflectionMap::getNearClip() return llmax(ret, MINIMUM_NEAR_CLIP); } -bool LLReflectionMap::getIsDynamic() +bool LLReflectionMap::getIsDynamic() const { - if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY && + static LLCachedControl detail(gSavedSettings, "RenderReflectionProbeDetail", 1); + if (detail() > (S32)LLReflectionMapManager::DetailLevel::STATIC_ONLY && mViewerObject && - mViewerObject->getVolume()) + !mViewerObject->isDead() && + mViewerObject->getVolumeConst()) { return mViewerObject->getReflectionProbeIsDynamic(); } @@ -278,12 +281,12 @@ bool LLReflectionMap::getBox(LLMatrix4& box) return false; } -bool LLReflectionMap::isActive() +bool LLReflectionMap::isActive() const { return mCubeIndex != -1; } -bool LLReflectionMap::isRelevant() +bool LLReflectionMap::isRelevant() const { static LLCachedControl RenderReflectionProbeLevel(gSavedSettings, "RenderReflectionProbeLevel", 3); diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index 117ea4cfa6..d20bba7059 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -58,16 +58,16 @@ public: void autoAdjustOrigin(); // return true if given Reflection Map's influence volume intersect's with this one's - bool intersects(LLReflectionMap* other); + bool intersects(LLReflectionMap* other) const; // Get the ambiance value to use for this probe - F32 getAmbiance(); + F32 getAmbiance() const; // Get the near clip plane distance to use for this probe - F32 getNearClip(); + F32 getNearClip() const; // Return true if this probe should include avatars in its reflection map - bool getIsDynamic(); + bool getIsDynamic() const; // get the encoded bounding box of this probe's influence volume // will only return a box if this probe is associated with a VOVolume @@ -76,13 +76,13 @@ public: bool getBox(LLMatrix4& box); // return true if this probe is active for rendering - bool isActive(); + bool isActive() const; // perform occlusion query/readback void doOcclusion(const LLVector4a& eye); // return false if this probe isn't currently relevant (for example, disabled due to graphics preferences) - bool isRelevant(); + bool isRelevant() const; // point at which environment map was last generated from (in agent space) LLVector4a mOrigin; From 203ef2f8d89a593ffe3af2f9556eebffd8d535a5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 9 Jan 2025 17:15:15 +0200 Subject: [PATCH 15/83] #3364 Decrement bias only if there is 10prcnt free space Instead of when there is any space. --- indra/newview/llviewertexture.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 36b6787ace..26eaa3c5bb 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -556,12 +556,13 @@ void LLViewerTexture::updateClass() // don't execute above until the slam to 1.5 has a chance to take effect sEvaluationTimer.reset(); - // lower discard bias over time when free memory is available - if (sDesiredDiscardBias > 1.f && over_pct < 0.f) + // 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) { static LLCachedControl high_mem_discard_decrement(gSavedSettings, "RenderHighMemMinDiscardDecrement", .1f); - F32 decrement = high_mem_discard_decrement - llmin(over_pct, 0.f); + F32 decrement = high_mem_discard_decrement - llmin(over_pct - FREE_PERCENTAGE_TRESHOLD, 0.f); sDesiredDiscardBias -= decrement * gFrameIntervalSeconds; } } From eb48eead2b029d5a85a9a58be4e30cb14d191ff0 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 9 Jan 2025 18:06:11 +0200 Subject: [PATCH 16/83] #3364 Cap intel adapters' vram to 25% of ram --- indra/llwindow/llwindowwin32.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 91437b98d1..547da681b3 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -44,6 +44,7 @@ #include "llstring.h" #include "lldir.h" #include "llsdutil.h" +#include "llsys.h" #include "llglslshader.h" #include "llthreadsafequeue.h" #include "stringize.h" @@ -4681,6 +4682,23 @@ void LLWindowWin32::LLWindowWin32Thread::checkDXMem() // Alternatively use GetDesc from below to get adapter's memory UINT64 budget_mb = info.Budget / (1024 * 1024); + if (gGLManager.mIsIntel) + { + U32Megabytes phys_mb = gSysMemory.getPhysicalMemoryKB(); + LL_WARNS() << "Physical memory: " << phys_mb << " MB" << LL_ENDL; + + if (phys_mb > 0) + { + // Intel uses 'shared' vram, cap it to 25% of total memory + // Todo: consider caping all adapters at least to 50% ram + budget_mb = llmin(budget_mb, (UINT64)(phys_mb * 0.25)); + } + else + { + // if no data available, cap to 2Gb + budget_mb = llmin(budget_mb, (UINT64)2048); + } + } if (gGLManager.mVRAM < (S32)budget_mb) { gGLManager.mVRAM = (S32)budget_mb; From f34af8f7d1a6182468ef72637dfab076b4d569ab Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 14 Jan 2025 01:13:10 +0200 Subject: [PATCH 17/83] #3398 Remove 3p logos from the viewer --- indra/newview/llprogressview.cpp | 124 ------------------ indra/newview/llprogressview.h | 19 --- .../default/textures/3p_icons/fmod_logo.png | Bin 14486 -> 0 bytes .../default/textures/3p_icons/havok_logo.png | Bin 41488 -> 0 bytes .../default/textures/3p_icons/vivox_logo.png | Bin 2331 -> 0 bytes .../skins/default/xui/de/panel_progress.xml | 2 - .../skins/default/xui/en/panel_progress.xml | 40 +----- .../skins/default/xui/es/panel_progress.xml | 2 - .../skins/default/xui/fr/panel_progress.xml | 2 - .../skins/default/xui/it/panel_progress.xml | 2 - .../skins/default/xui/ja/panel_progress.xml | 4 - .../skins/default/xui/pl/panel_progress.xml | 5 - .../skins/default/xui/pt/panel_progress.xml | 2 - 13 files changed, 4 insertions(+), 198 deletions(-) delete mode 100644 indra/newview/skins/default/textures/3p_icons/fmod_logo.png delete mode 100644 indra/newview/skins/default/textures/3p_icons/havok_logo.png delete mode 100644 indra/newview/skins/default/textures/3p_icons/vivox_logo.png diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index 80e403dfde..f207b19593 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -81,8 +81,6 @@ bool LLProgressView::postBuild() { mProgressBar = getChild("login_progress_bar"); - mLogosLabel = getChild("logos_lbl"); - mProgressText = getChild("progress_text"); mMessageText = getChild("message_text"); @@ -234,33 +232,6 @@ void LLProgressView::drawStartTexture(F32 alpha) gGL.popMatrix(); } -void LLProgressView::drawLogos(F32 alpha) -{ - if (mLogosList.empty()) - { - return; - } - - // logos are tied to label, - // due to potential resizes we have to figure offsets out on draw or resize - S32 offset_x, offset_y; - mLogosLabel->localPointToScreen(0, 0, &offset_x, &offset_y); - std::vector::const_iterator iter = mLogosList.begin(); - std::vector::const_iterator end = mLogosList.end(); - for (; iter != end; iter++) - { - gl_draw_scaled_image_with_border(iter->mDrawRect.mLeft + offset_x, - iter->mDrawRect.mBottom + offset_y, - iter->mDrawRect.getWidth(), - iter->mDrawRect.getHeight(), - iter->mTexturep.get(), - UI_VERTEX_COLOR % alpha, - false, - iter->mClipRect, - iter->mOffsetRect); - } -} - void LLProgressView::draw() { static LLTimer timer; @@ -276,7 +247,6 @@ void LLProgressView::draw() } LLPanel::draw(); - drawLogos(alpha); return; } @@ -289,7 +259,6 @@ void LLProgressView::draw() drawStartTexture(alpha); LLPanel::draw(); - drawLogos(alpha); // faded out completely - remove panel and reveal world if (mFadeToWorldTimer.getElapsedTimeF32() > FADE_TO_WORLD_TIME ) @@ -324,7 +293,6 @@ void LLProgressView::draw() drawStartTexture(1.0f); // draw children LLPanel::draw(); - drawLogos(1.0f); } void LLProgressView::setText(const std::string& text) @@ -343,90 +311,6 @@ void LLProgressView::setMessage(const std::string& msg) mMessageText->setValue(mMessage); } -void LLProgressView::loadLogo(const std::string &path, - const U8 image_codec, - const LLRect &pos_rect, - const LLRectf &clip_rect, - const LLRectf &offset_rect) -{ - // We need these images very early, so we have to force-load them, otherwise they might not load in time. - if (!gDirUtilp->fileExists(path)) - { - return; - } - - LLPointer start_image_frmted = LLImageFormatted::createFromType(image_codec); - if (!start_image_frmted->load(path)) - { - LL_WARNS("AppInit") << "Image load failed: " << path << LL_ENDL; - return; - } - - LLPointer raw = new LLImageRaw; - if (!start_image_frmted->decode(raw, 0.0f)) - { - LL_WARNS("AppInit") << "Image decode failed " << path << LL_ENDL; - return; - } - // HACK: getLocalTexture allows only power of two dimentions - raw->expandToPowerOfTwo(); - - TextureData data; - data.mTexturep = LLViewerTextureManager::getLocalTexture(raw.get(), false); - data.mDrawRect = pos_rect; - data.mClipRect = clip_rect; - data.mOffsetRect = offset_rect; - mLogosList.push_back(data); -} - -void LLProgressView::initLogos() -{ - mLogosList.clear(); - - const U8 image_codec = IMG_CODEC_PNG; - const LLRectf default_clip(0.f, 1.f, 1.f, 0.f); - const S32 default_height = 28; - const S32 default_pad = 15; - - S32 icon_width, icon_height; - - // We don't know final screen rect yet, so we can't precalculate position fully - S32 texture_start_x = (S32)mLogosLabel->getFont()->getWidthF32(mLogosLabel->getWText().c_str()) + default_pad; - S32 texture_start_y = -7; - - // Normally we would just preload these textures from textures.xml, - // and display them via icon control, but they are only needed on - // startup and preloaded/UI ones stay forever - // (and this code was done already so simply reused it) - std::string temp_str = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "textures", "3p_icons"); - - temp_str += gDirUtilp->getDirDelimiter(); - -#ifdef LL_HAVOK - // original image size is 342x113, central element is on a larger side - // plus internal padding, so it gets slightly more height than desired 32 - icon_width = 88; - icon_height = 29; - S32 pad_havok_y = -1; - loadLogo(temp_str + "havok_logo.png", - image_codec, - LLRect(texture_start_x, texture_start_y + pad_havok_y + icon_height, texture_start_x + icon_width, texture_start_y + pad_havok_y), - default_clip, - default_clip); - - texture_start_x += icon_width + default_pad; -#endif //LL_HAVOK - - // 108x41 - icon_width = 74; - icon_height = default_height; - loadLogo(temp_str + "vivox_logo.png", - image_codec, - LLRect(texture_start_x, texture_start_y + icon_height, texture_start_x + icon_width, texture_start_y), - default_clip, - default_clip); -} - void LLProgressView::initStartTexture(S32 location_id, bool is_in_production) { if (gStartTexture.notNull()) @@ -505,19 +389,11 @@ void LLProgressView::initStartTexture(S32 location_id, bool is_in_production) void LLProgressView::initTextures(S32 location_id, bool is_in_production) { initStartTexture(location_id, is_in_production); - initLogos(); - - childSetVisible("panel_icons", !mLogosList.empty()); - childSetVisible("panel_top_spacer", mLogosList.empty()); } void LLProgressView::releaseTextures() { gStartTexture = NULL; - mLogosList.clear(); - - childSetVisible("panel_top_spacer", true); - childSetVisible("panel_icons", false); } void LLProgressView::setCancelButtonVisible(bool b, const std::string& label) diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index 15b04a8eb9..a630c4a273 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -53,7 +53,6 @@ public: /*virtual*/ void draw(); void drawStartTexture(F32 alpha); - void drawLogos(F32 alpha); /*virtual*/ bool handleHover(S32 x, S32 y, MASK mask); /*virtual*/ bool handleKeyHere(KEY key, MASK mask); @@ -86,7 +85,6 @@ public: protected: LLProgressBar* mProgressBar; LLMediaCtrl* mMediaCtrl; - LLTextBox* mLogosLabel = nullptr; LLTextBox* mProgressText = nullptr; LLTextBox* mMessageText = nullptr; F32 mPercentDone; @@ -105,25 +103,8 @@ protected: bool handleUpdate(const LLSD& event_data); static void onIdle(void* user_data); - void loadLogo(const std::string &path, const U8 image_codec, const LLRect &pos_rect, const LLRectf &clip_rect, const LLRectf &offset_rect); - // logos have unusual location and need to be preloaded to not appear grey, then deleted - void initLogos(); // Loads a bitmap to display during load void initStartTexture(S32 location_id, bool is_in_production); - -private: - // We need to draw textures on login, but only once. - // So this vector gets filled up for textures to render and gets cleaned later - // Some textures have unusual requirements, so we are rendering directly - class TextureData - { - public: - LLPointer mTexturep; - LLRect mDrawRect; - LLRectf mClipRect; - LLRectf mOffsetRect; - }; - std::vector mLogosList; }; #endif // LL_LLPROGRESSVIEW_H diff --git a/indra/newview/skins/default/textures/3p_icons/fmod_logo.png b/indra/newview/skins/default/textures/3p_icons/fmod_logo.png deleted file mode 100644 index 5a50e0ad34b54c63357a87094a102ba26d0782d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14486 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 j=}QWnc@$V+@snix#7EjcYJPq diff --git a/indra/newview/skins/default/textures/3p_icons/havok_logo.png b/indra/newview/skins/default/textures/3p_icons/havok_logo.png deleted file mode 100644 index ff1ea3a72e8baf13cf235021482f9d57bab2ef08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41488 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 BXaxWO diff --git a/indra/newview/skins/default/xui/de/panel_progress.xml b/indra/newview/skins/default/xui/de/panel_progress.xml index 8d1abdcac1..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/de/panel_progress.xml +++ b/indra/newview/skins/default/xui/de/panel_progress.xml @@ -1,10 +1,8 @@ - - Second Life verwendet diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml index 242b96b695..337335e1aa 100644 --- a/indra/newview/skins/default/xui/en/panel_progress.xml +++ b/indra/newview/skins/default/xui/en/panel_progress.xml @@ -44,15 +44,15 @@ width="670" /> - - - - - - Second Life uses - - - - Usos de Second Life diff --git a/indra/newview/skins/default/xui/fr/panel_progress.xml b/indra/newview/skins/default/xui/fr/panel_progress.xml index 673ec63642..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/fr/panel_progress.xml +++ b/indra/newview/skins/default/xui/fr/panel_progress.xml @@ -1,10 +1,8 @@ - - Second Life utilise diff --git a/indra/newview/skins/default/xui/it/panel_progress.xml b/indra/newview/skins/default/xui/it/panel_progress.xml index fd2892a88f..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/it/panel_progress.xml +++ b/indra/newview/skins/default/xui/it/panel_progress.xml @@ -1,10 +1,8 @@ - - Utilizzi di Second Life diff --git a/indra/newview/skins/default/xui/ja/panel_progress.xml b/indra/newview/skins/default/xui/ja/panel_progress.xml index 7fd7d5ab5c..1edada6098 100644 --- a/indra/newview/skins/default/xui/ja/panel_progress.xml +++ b/indra/newview/skins/default/xui/ja/panel_progress.xml @@ -1,12 +1,8 @@ - - - セカンドライフ使用 - diff --git a/indra/newview/skins/default/xui/pl/panel_progress.xml b/indra/newview/skins/default/xui/pl/panel_progress.xml index 22b6a8fcf5..125cb91bdb 100644 --- a/indra/newview/skins/default/xui/pl/panel_progress.xml +++ b/indra/newview/skins/default/xui/pl/panel_progress.xml @@ -5,11 +5,6 @@ - - - Second Life używa - - diff --git a/indra/newview/skins/default/xui/pt/panel_progress.xml b/indra/newview/skins/default/xui/pt/panel_progress.xml index 63bb663cfc..c9bed9fd9b 100644 --- a/indra/newview/skins/default/xui/pt/panel_progress.xml +++ b/indra/newview/skins/default/xui/pt/panel_progress.xml @@ -1,10 +1,8 @@ - - Usos do Second Life From c2d491905b668702d5640c7c5472629f7acc27e0 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 14 Jan 2025 23:37:02 +0200 Subject: [PATCH 18/83] #3405 MotD dynamic resizing --- indra/newview/llprogressview.cpp | 19 +++++++++++++++++++ indra/newview/llprogressview.h | 7 +++++++ .../skins/default/xui/en/panel_progress.xml | 18 +++++++++--------- .../skins/default/xui/pl/panel_progress.xml | 4 ++-- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp index f207b19593..2c09943b83 100644 --- a/indra/newview/llprogressview.cpp +++ b/indra/newview/llprogressview.cpp @@ -83,6 +83,7 @@ bool LLProgressView::postBuild() mProgressText = getChild("progress_text"); mMessageText = getChild("message_text"); + mMessageTextRectInitial = mMessageText->getRect(); // auto resizes, save initial size // media control that is used to play intro video mMediaCtrl = getChild("login_media_panel"); @@ -94,6 +95,12 @@ bool LLProgressView::postBuild() mCancelBtn = getChild("cancel_btn"); mCancelBtn->setClickedCallback( LLProgressView::onCancelButtonClicked, NULL ); + mLayoutPanel4 = getChild("panel4"); + mLayoutPanel4RectInitial = mLayoutPanel4->getRect(); + + mLayoutMOTD = getChild("panel_motd"); + mLayoutMOTDRectInitial = mLayoutMOTD->getRect(); + getChild("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle())); getChild("message_text")->setClickedCallback(onClickMessage, this); @@ -309,6 +316,18 @@ void LLProgressView::setMessage(const std::string& msg) { mMessage = msg; mMessageText->setValue(mMessage); + S32 height = mMessageText->getTextPixelHeight(); + S32 delta = height - mMessageTextRectInitial.getHeight(); + if (delta > 0) + { + mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight() + delta); + mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight() + delta); + } + else + { + mLayoutPanel4->reshape(mLayoutPanel4RectInitial.getWidth(), mLayoutPanel4RectInitial.getHeight()); + mLayoutMOTD->reshape(mLayoutMOTDRectInitial.getWidth(), mLayoutMOTDRectInitial.getHeight()); + } } void LLProgressView::initStartTexture(S32 location_id, bool is_in_production) diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h index a630c4a273..250ee511d7 100644 --- a/indra/newview/llprogressview.h +++ b/indra/newview/llprogressview.h @@ -93,6 +93,13 @@ protected: LLFrameTimer mFadeToWorldTimer; LLFrameTimer mFadeFromLoginTimer; LLRect mOutlineRect; + LLView* mLayoutPanel4 = nullptr; + LLView* mLayoutMOTD = nullptr; + // Rects for resizing purposes + LLRect mMessageTextRectInitial; + LLRect mLayoutPanel4RectInitial; + LLRect mLayoutMOTDRectInitial; + bool mMouseDownInActiveArea; bool mStartupComplete; diff --git a/indra/newview/skins/default/xui/en/panel_progress.xml b/indra/newview/skins/default/xui/en/panel_progress.xml index 337335e1aa..6b19907372 100644 --- a/indra/newview/skins/default/xui/en/panel_progress.xml +++ b/indra/newview/skins/default/xui/en/panel_progress.xml @@ -33,7 +33,7 @@ layout="topleft" left="0" orientation="vertical" - name="vertical_centering" + name="vertical_centering1" top="0" width="670"> @@ -113,9 +113,9 @@ - + - + From 6dc819e22aaf35054764a57dc51bb0ed629c6703 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 15 Jan 2025 18:28:09 +0200 Subject: [PATCH 19/83] #3364 Fix update rate being stuck high due to bias if bias stays unchanged at 4.f, there is no reason to keep refreshing at high rate. --- indra/newview/llviewertexture.cpp | 8 ++++++++ indra/newview/llviewertexture.h | 1 + indra/newview/llviewertexturelist.cpp | 11 +++++++++-- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 26eaa3c5bb..271460f2cc 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -87,6 +87,7 @@ S32 LLViewerTexture::sRawCount = 0; S32 LLViewerTexture::sAuxCount = 0; LLFrameTimer LLViewerTexture::sEvaluationTimer; F32 LLViewerTexture::sDesiredDiscardBias = 0.f; +U32 LLViewerTexture::sBiasTexturesUpdated = 0; S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size constexpr S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64; @@ -518,6 +519,7 @@ void LLViewerTexture::updateClass() bool is_sys_low = isSystemMemoryLow(); bool is_low = is_sys_low || over_pct > 0.f; + F32 discard_bias = sDesiredDiscardBias; static bool was_low = false; static bool was_sys_low = false; @@ -604,6 +606,12 @@ void LLViewerTexture::updateClass() } sDesiredDiscardBias = llclamp(sDesiredDiscardBias, 1.f, 4.f); + if (discard_bias != sDesiredDiscardBias) + { + // bias changed, reset texture update counter to + // let updates happen at an increased rate. + sBiasTexturesUpdated = 0; + } LLViewerTexture::sFreezeImageUpdates = false; } diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index 4241ef958f..31b089226f 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -220,6 +220,7 @@ public: static S32 sAuxCount; static LLFrameTimer sEvaluationTimer; static F32 sDesiredDiscardBias; + static U32 sBiasTexturesUpdated; static S32 sMaxSculptRez ; static U32 sMinLargeImageSize ; static U32 sMaxSmallImageSize ; diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 0b79c2d8e0..7f38642623 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1198,10 +1198,17 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) //update MIN_UPDATE_COUNT or 5% of other textures, whichever is greater update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/20); - if (LLViewerTexture::sDesiredDiscardBias > 1.f) + if (LLViewerTexture::sDesiredDiscardBias > 1.f + && LLViewerTexture::sBiasTexturesUpdated < (U32)mUUIDMap.size()) { - // we are over memory target, update more agresively + // We are over memory target. Bias affects discard rates, so update + // existing textures agresively to free memory faster. update_count = (S32)(update_count * LLViewerTexture::sDesiredDiscardBias); + + // This isn't particularly precise and can overshoot, but it doesn't need + // to be, just making sure it did a full circle and doesn't get stuck updating + // at bias = 4 with 4 times the rate permanently. + LLViewerTexture::sBiasTexturesUpdated += update_count; } update_count = llmin(update_count, (U32) mUUIDMap.size()); From b1bd083728d0fb630abdff64cd57cefb833bd0b9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 16 Jan 2025 20:57:23 +0200 Subject: [PATCH 20/83] #3413 Crash at removeFromLocalIDTable Callstacks indicate that this happens only on shutdown. No point to erase items one at a time, just clear the list beforehand. --- indra/newview/llviewerobjectlist.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index d667fdbea8..d8f446db05 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -1309,7 +1309,10 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) // << objectp->getRegion()->getHost().getPort() << LL_ENDL; //} - removeFromLocalIDTable(objectp); + if (!mIndexAndLocalIDToUUID.empty()) + { + removeFromLocalIDTable(objectp); + } if (objectp->onActiveList()) { @@ -1381,11 +1384,19 @@ void LLViewerObjectList::killObjects(LLViewerRegion *regionp) void LLViewerObjectList::killAllObjects() { // Used only on global destruction. - LLViewerObject *objectp; + // Mass cleanup to not clear lists one item at a time + mIndexAndLocalIDToUUID.clear(); + mActiveObjects.clear(); + mMapObjects.clear(); + + LLViewerObject *objectp; for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) { objectp = *iter; + objectp->setOnActiveList(false); + objectp->setListIndex(-1); + objectp->mOnMap = false; killObject(objectp); // Object must be dead, or it's the LLVOAvatarSelf which never dies. llassert((objectp == gAgentAvatarp) || objectp->isDead()); @@ -1398,18 +1409,6 @@ void LLViewerObjectList::killAllObjects() LL_WARNS() << "LLViewerObjectList::killAllObjects still has entries in mObjects: " << mObjects.size() << LL_ENDL; mObjects.clear(); } - - if (!mActiveObjects.empty()) - { - LL_WARNS() << "Some objects still on active object list!" << LL_ENDL; - mActiveObjects.clear(); - } - - if (!mMapObjects.empty()) - { - LL_WARNS() << "Some objects still on map object list!" << LL_ENDL; - mMapObjects.clear(); - } } void LLViewerObjectList::cleanDeadObjects(bool use_timer) From 306e9e6d0293ed6470db19c0882930fff0cd145f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 17 Jan 2025 17:57:03 +0200 Subject: [PATCH 21/83] #3413 Crash at removeFromLocalIDTable #2 Don't rely onto region for cleanup --- indra/newview/llviewerobject.h | 3 ++ indra/newview/llviewerobjectlist.cpp | 42 +++++++++++++--------------- indra/newview/llviewerobjectlist.h | 5 ++-- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index b6846c6716..206840ebfb 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -727,6 +727,9 @@ public: // index into LLViewerObjectList::mActiveObjects or -1 if not in list S32 mListIndex; + // last index data for mIndexAndLocalIDToUUID + U32 mRegionIndex; + LLPointer *mTEImages; LLPointer *mTENormalMaps; LLPointer *mTESpecularMaps; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index d8f446db05..cd9d152437 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -164,21 +164,14 @@ U64 LLViewerObjectList::getIndex(const U32 local_id, return (((U64)index) << 32) | (U64)local_id; } -bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) +bool LLViewerObjectList::removeFromLocalIDTable(LLViewerObject* objectp) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; - if(objectp && objectp->getRegion()) + if(objectp && objectp->mRegionIndex != 0) { U32 local_id = objectp->mLocalID; - U32 ip = objectp->getRegion()->getHost().getAddress(); - U32 port = objectp->getRegion()->getHost().getPort(); - U64 ipport = (((U64)ip) << 32) | (U64)port; - U32 index = mIPAndPortToIndex[ipport]; - - // LL_INFOS() << "Removing object from table, local ID " << local_id << ", ip " << ip << ":" << port << LL_ENDL; - - U64 indexid = (((U64)index) << 32) | (U64)local_id; + U64 indexid = (((U64)objectp->mRegionIndex) << 32) | (U64)local_id; std::map::iterator iter = mIndexAndLocalIDToUUID.find(indexid); if (iter == mIndexAndLocalIDToUUID.end()) @@ -190,6 +183,7 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) if (iter->second == objectp->getID()) { // Full UUIDs match, so remove the entry mIndexAndLocalIDToUUID.erase(iter); + objectp->mRegionIndex = 0; return true; } // UUIDs did not match - this would zap a valid entry, so don't erase it @@ -203,7 +197,8 @@ bool LLViewerObjectList::removeFromLocalIDTable(const LLViewerObject* objectp) void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id, const U32 local_id, const U32 ip, - const U32 port) + const U32 port, + LLViewerObject* objectp) { U64 ipport = (((U64)ip) << 32) | (U64)port; @@ -215,6 +210,7 @@ void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id, mIPAndPortToIndex[ipport] = index; } + objectp->mRegionIndex = index; // should never be zero, sSimulatorMachineIndex starts from 1 U64 indexid = (((U64)index) << 32) | (U64)local_id; mIndexAndLocalIDToUUID[indexid] = id; @@ -335,7 +331,8 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry* removeFromLocalIDTable(objectp); setUUIDAndLocal(fullid, entry->getLocalID(), regionp->getHost().getAddress(), - regionp->getHost().getPort()); + regionp->getHost().getPort(), + objectp); if (objectp->mLocalID != entry->getLocalID()) { // Update local ID in object with the one sent from the region @@ -582,7 +579,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys, setUUIDAndLocal(fullid, local_id, gMessageSystem->getSenderIP(), - gMessageSystem->getSenderPort()); + gMessageSystem->getSenderPort(), + objectp); if (objectp->mLocalID != local_id) { // Update local ID in object with the one sent from the region @@ -1309,10 +1307,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp) // << objectp->getRegion()->getHost().getPort() << LL_ENDL; //} - if (!mIndexAndLocalIDToUUID.empty()) - { - removeFromLocalIDTable(objectp); - } + removeFromLocalIDTable(objectp); if (objectp->onActiveList()) { @@ -1396,6 +1391,7 @@ void LLViewerObjectList::killAllObjects() objectp = *iter; objectp->setOnActiveList(false); objectp->setListIndex(-1); + objectp->mRegionIndex = 0; objectp->mOnMap = false; killObject(objectp); // Object must be dead, or it's the LLVOAvatarSelf which never dies. @@ -1508,9 +1504,9 @@ void LLViewerObjectList::updateActive(LLViewerObject *objectp) mActiveObjects.push_back(objectp); objectp->setListIndex(static_cast(mActiveObjects.size()) - 1); objectp->setOnActiveList(true); - } - else - { + } + else + { llassert(idx < mActiveObjects.size()); llassert(mActiveObjects[idx] == objectp); @@ -1862,7 +1858,8 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L setUUIDAndLocal(uuid, local_id, regionp->getHost().getAddress(), - regionp->getHost().getPort()); + regionp->getHost().getPort(), + objectp); mObjects.push_back(objectp); updateActive(objectp); @@ -1900,7 +1897,8 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe setUUIDAndLocal(fullid, local_id, gMessageSystem->getSenderIP(), - gMessageSystem->getSenderPort()); + gMessageSystem->getSenderPort(), + objectp); mObjects.push_back(objectp); diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h index dc31995eb1..547ef9fb2d 100644 --- a/indra/newview/llviewerobjectlist.h +++ b/indra/newview/llviewerobjectlist.h @@ -179,9 +179,10 @@ public: void setUUIDAndLocal(const LLUUID &id, const U32 local_id, const U32 ip, - const U32 port); // Requires knowledge of message system info! + const U32 port, + LLViewerObject* objectp); // Requires knowledge of message system info! - bool removeFromLocalIDTable(const LLViewerObject* objectp); + bool removeFromLocalIDTable(LLViewerObject* objectp); // Used ONLY by the orphaned object code. U64 getIndex(const U32 local_id, const U32 ip, const U32 port); From 75a01bf4286338f3726add4da6d0dc07f033815f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 18 Jan 2025 04:00:10 +0200 Subject: [PATCH 22/83] #3319 Crash at LLInitParam::Param::setProvided Most crashes are related to LLStyle, log analysis suggests that it might be a number of different issues, including memory and disk issues. Just avoid recreating expensive LLStyle without reason. --- indra/llui/llstyle.cpp | 7 ++++++- indra/llui/llstyle.h | 1 + indra/llui/lltextbase.cpp | 10 ++++------ indra/llui/lltextbox.cpp | 3 ++- indra/newview/llfloaterimsessiontab.cpp | 3 ++- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/indra/llui/llstyle.cpp b/indra/llui/llstyle.cpp index df4b0ef6a0..4714665e8b 100644 --- a/indra/llui/llstyle.cpp +++ b/indra/llui/llstyle.cpp @@ -39,7 +39,7 @@ LLStyle::Params::Params() readonly_color("readonly_color", LLColor4::black), selected_color("selected_color", LLColor4::black), alpha("alpha", 1.f), - font("font", LLFontGL::getFontMonospace()), + font("font", LLStyle::getDefaultFont()), image("image"), link_href("href"), is_link("is_link") @@ -70,6 +70,11 @@ const LLFontGL* LLStyle::getFont() const return mFont; } +const LLFontGL* LLStyle::getDefaultFont() +{ + return LLFontGL::getFontMonospace(); +} + void LLStyle::setLinkHREF(const std::string& href) { mLink = href; diff --git a/indra/llui/llstyle.h b/indra/llui/llstyle.h index e506895de5..0c78fe5a9f 100644 --- a/indra/llui/llstyle.h +++ b/indra/llui/llstyle.h @@ -72,6 +72,7 @@ public: void setFont(const LLFontGL* font); const LLFontGL* getFont() const; + static const LLFontGL* getDefaultFont(); const std::string& getLinkHREF() const { return mLink; } void setLinkHREF(const std::string& href); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index cbbf83d679..fae22fd248 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1438,7 +1438,8 @@ void LLTextBase::onVisibilityChange( bool new_visibility ) //virtual void LLTextBase::setValue(const LLSD& value ) { - setText(value.asString()); + static const LLStyle::Params input_params = LLStyle::Params(); + setText(value.asString(), input_params); } //virtual @@ -3880,8 +3881,7 @@ bool LLInlineViewSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w if (mForceNewLine) { // Chat, string can't be smaller then font height even if it is empty - LLStyleSP s(new LLStyle(LLStyle::Params().visible(true))); - height = s->getFont()->getLineHeight(); + height = LLStyle::getDefaultFont()->getLineHeight(); return true; // new line } @@ -3945,9 +3945,7 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor) LLLineBreakTextSegment::LLLineBreakTextSegment(S32 pos):LLTextSegment(pos,pos+1) { - LLStyleSP s( new LLStyle(LLStyle::Params().visible(true))); - - mFontHeight = s->getFont()->getLineHeight(); + mFontHeight = LLStyle::getDefaultFont()->getLineHeight(); } LLLineBreakTextSegment::LLLineBreakTextSegment(LLStyleConstSP style,S32 pos):LLTextSegment(pos,pos+1) { diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp index 05af36b71e..9f945d3735 100644 --- a/indra/llui/lltextbox.cpp +++ b/indra/llui/lltextbox.cpp @@ -159,7 +159,8 @@ LLSD LLTextBox::getValue() const bool LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text ) { mText.setArg(key, text); - LLTextBase::setText(mText.getString()); + static const LLStyle::Params input_params = LLStyle::Params(); + LLTextBase::setText(mText.getString(), input_params); return true; } diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index af38d696bc..655674357f 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -633,7 +633,8 @@ void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD& args) chat_args["show_names_for_p2p_conv"] = !mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv"); - mChatHistory->appendMessage(chat, chat_args); + static const LLStyle::Params input_append_params = LLStyle::Params(); + mChatHistory->appendMessage(chat, chat_args, input_append_params); } void LLFloaterIMSessionTab::updateUsedEmojis(LLWStringView text) From ebae60c5a7ee99c2b4ad5149b420acb63e44e5d5 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Mon, 20 Jan 2025 17:41:26 +0200 Subject: [PATCH 23/83] #3424 Update 'Second Life Blogs' link --- indra/newview/skins/default/xui/en/menu_login.xml | 9 +-------- indra/newview/skins/default/xui/en/menu_viewer.xml | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml index 1d1b81e31a..5fff9b7bc0 100644 --- a/indra/newview/skins/default/xui/en/menu_login.xml +++ b/indra/newview/skins/default/xui/en/menu_login.xml @@ -94,19 +94,12 @@ parameter="https://support.secondlife.com/"/> - - - + parameter="https://community.secondlife.com/news/"/> - - - + parameter="https://community.secondlife.com/news/"/> From 2ee845c02869b2b3db5810c9ad550efaa46a5289 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Jan 2025 20:52:28 +0200 Subject: [PATCH 24/83] #3436 Better handling of 'teleport_strings.xml' parsing failure --- indra/newview/llagent.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 26c080bf89..8756baa04a 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -4879,10 +4879,19 @@ void LLAgent::parseTeleportMessages(const std::string& xml_filename) LLXMLNodePtr root; bool success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); - if (!success || !root || !root->hasName( "teleport_messages" )) + if (!success) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Problem reading teleport string XML file: " - << xml_filename << LL_ENDL; + << xml_filename << LL_ENDL; + return; + } + + if (!root || !root->hasName("teleport_messages")) + { + LLError::LLUserWarningMsg::showMissingFiles(); + LL_ERRS() << "Invalid teleport string XML file: " + << xml_filename << LL_ENDL; return; } From fa963b6b15187739b808f16d42086e64aeebbacc Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Jan 2025 21:42:33 +0200 Subject: [PATCH 25/83] #3438 Crash when ParcelProperties' Bitmap is of wrong size --- indra/newview/llviewerparcelmgr.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 8c24b2438b..8e6657b4b9 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1824,6 +1824,16 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use S32 bitmap_size = parcel_mgr.mParcelsPerEdge * parcel_mgr.mParcelsPerEdge / 8; + S32 size = msg->getSizeFast(_PREHASH_ParcelData, _PREHASH_Bitmap); + if (size != bitmap_size) + { + // Might be better to ignore bitmap and drop highlights + LL_WARNS("ParcelMgr") << "Parcel Bitmap size expected: " << bitmap_size + << " actual " << size + << ". Bitmap might be corrupted!" << LL_ENDL; + bitmap_size = size; + } + U8* bitmap = new U8[ bitmap_size ]; msg->getBinaryDataFast(_PREHASH_ParcelData, _PREHASH_Bitmap, bitmap, bitmap_size); From 74cdfcefa03021d04539750683e555d2cf5d5e66 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Jan 2025 22:04:13 +0200 Subject: [PATCH 26/83] #3440 Crash at updateCombinationVisibility --- indra/newview/llpanelmaininventory.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp index 377af4384a..a5b4db0580 100644 --- a/indra/newview/llpanelmaininventory.cpp +++ b/indra/newview/llpanelmaininventory.cpp @@ -2425,10 +2425,14 @@ void LLPanelMainInventory::updateCombinationVisibility() mCombinationGalleryLayoutPanel->setVisible(!is_gallery_empty); mCombinationListLayoutPanel->setVisible(show_inv_pane); - mCombinationInventoryPanel->getRootFolder()->setForceArrange(!show_inv_pane); - if(mCombinationInventoryPanel->hasVisibleItems()) + LLFolderView* root_folder = mCombinationInventoryPanel->getRootFolder(); + if (root_folder) { - mForceShowInvLayout = false; + root_folder->setForceArrange(!show_inv_pane); + if (mCombinationInventoryPanel->hasVisibleItems()) + { + mForceShowInvLayout = false; + } } if(is_gallery_empty) { From 75e01f894d52f75c1a79746bf2d3294b3ca48afe Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Jan 2025 22:09:20 +0200 Subject: [PATCH 27/83] #3436 Better handling in setting_get_control --- indra/newview/llviewercontrol.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index d4a033bd42..598ad89907 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -764,9 +764,9 @@ LLPointer setting_get_control(LLControlGroup& group, const st LLPointer cntrl_ptr = group.getControl(setting); if (cntrl_ptr.isNull()) { + LLError::LLUserWarningMsg::showMissingFiles(); LL_ERRS() << "Unable to set up setting listener for " << setting - << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." - << LL_ENDL; + << "." << LL_ENDL; } return cntrl_ptr; } From f490bf6463e5b4b46fd940adc6bba19ebc11591d Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 21 Jan 2025 16:25:01 +0200 Subject: [PATCH 28/83] #3442 Crash at LLDrawable::isState --- indra/newview/pipeline.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 38f158c1df..c6e6c454de 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3855,7 +3855,12 @@ void LLPipeline::renderSelectedFaces(const LLColor4& color) for (auto facep : mSelectedFaces) { - if (!facep || facep->getDrawable()->isDead()) + if (!facep || !facep->getViewerObject()) + { + LLSelectMgr::getInstance()->clearSelections(); + return; + } + if (!facep->getDrawable() || facep->getDrawable()->isDead()) { LL_ERRS() << "Bad face on selection" << LL_ENDL; return; From c85880aca971493ea5f7c80b8f152e0e8d00813c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 13 Jan 2025 17:54:02 +0200 Subject: [PATCH 29/83] #3371 Texture resolution cap --- indra/newview/featuretable.txt | 9 ++++ indra/newview/featuretable_mac.txt | 9 ++++ indra/newview/llviewertexture.cpp | 16 +++++- .../floater_preferences_graphics_advanced.xml | 53 +++++++++++++++---- 4 files changed, 76 insertions(+), 11 deletions(-) diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index d894e1b24e..cb79410d72 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -85,6 +85,7 @@ RenderExposure 1 4 RenderTonemapType 1 1 RenderTonemapMix 1 1 RenderDisableVintageMode 1 1 +RenderMaxTextureResolution 1 2048 // // Low Graphics Settings @@ -126,6 +127,7 @@ RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 512 // // Medium Low Graphics Settings @@ -167,6 +169,7 @@ RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 1024 // // Medium Graphics Settings (standard) @@ -207,6 +210,7 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // Medium High Graphics Settings @@ -247,6 +251,7 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // High Graphics Settings (SSAO + sun shadows) @@ -287,6 +292,7 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // High Ultra Graphics Settings (deferred + SSAO + all shadows) @@ -327,6 +333,7 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // Ultra graphics (REALLY PURTY!) @@ -367,6 +374,7 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // Class Unknown Hardware (unknown) @@ -399,6 +407,7 @@ RenderShadowDetail 0 0 RenderReflectionProbeDetail 0 -1 RenderMirrors 0 0 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 2048 list Intel RenderAnisotropic 1 0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index cfcd96d650..dc9473b042 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -85,6 +85,7 @@ RenderTonemapType 1 1 RenderTonemapMix 1 1 RenderDisableVintageMode 1 1 RenderDownScaleMethod 1 0 +RenderMaxTextureResolution 1 2048 // // Low Graphics Settings @@ -126,6 +127,7 @@ RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 512 // // Medium Low Graphics Settings @@ -167,6 +169,7 @@ RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 1024 // // Medium Graphics Settings (standard) @@ -207,6 +210,7 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // Medium High Graphics Settings @@ -247,6 +251,7 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // High Graphics Settings (SSAO + sun shadows) @@ -287,6 +292,7 @@ RenderCASSharpness 1 0 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // High Ultra Graphics Settings (SSAO + all shadows) @@ -327,6 +333,7 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // Ultra graphics (REALLY PURTY!) @@ -367,6 +374,7 @@ RenderCASSharpness 1 0.4 RenderExposure 1 1 RenderTonemapType 1 1 RenderTonemapMix 1 0.7 +RenderMaxTextureResolution 1 2048 // // Class Unknown Hardware (unknown) @@ -398,6 +406,7 @@ RenderDeferredSSAO 0 0 RenderShadowDetail 0 0 RenderMirrors 0 0 RenderDisableVintageMode 1 0 +RenderMaxTextureResolution 1 2048 list TexUnit8orLess RenderDeferredSSAO 0 0 diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 271460f2cc..3f30a42b0e 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1694,6 +1694,16 @@ void LLViewerFetchedTexture::processTextureStats() static LLCachedControl textures_fullres(gSavedSettings,"TextureLoadFullRes", false); + if (mBoostLevel < LLGLTexture::BOOST_HIGH) + { + // restrict texture resolution to download based on RenderMaxTextureResolution + static LLCachedControl max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048); + // sanity clamp debug setting to avoid settings hack shenanigans + F32 tex_res = (F32)llclamp((S32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT); + tex_res *= tex_res; + mMaxVirtualSize = llmin(mMaxVirtualSize, tex_res); + } + if (textures_fullres) { mDesiredDiscardLevel = 0; @@ -2948,10 +2958,12 @@ void LLViewerLODTexture::processTextureStats() static LLCachedControl textures_fullres(gSavedSettings,"TextureLoadFullRes", false); - { // restrict texture resolution to download based on RenderMaxTextureResolution + if (mBoostLevel < LLGLTexture::BOOST_HIGH) + { + // restrict texture resolution to download based on RenderMaxTextureResolution static LLCachedControl max_texture_resolution(gSavedSettings, "RenderMaxTextureResolution", 2048); // sanity clamp debug setting to avoid settings hack shenanigans - F32 tex_res = (F32)llclamp((S32)max_texture_resolution, 512, 2048); + F32 tex_res = (F32)llclamp((S32)max_texture_resolution, 512, MAX_IMAGE_SIZE_DEFAULT); tex_res *= tex_res; mMaxVirtualSize = llmin(mMaxVirtualSize, tex_res); } diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 65b98c65cf..567dd715a0 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -1,6 +1,6 @@ + + Maximum LOD resolution: + + + + + + Avatar display: @@ -160,10 +195,10 @@ + width="130"> Antialiasing: + width="130"> Antialiasing Quality: