From 1af45ee1dfdda1e6408e5f9b3fdeee9a2647bfd0 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 24 Feb 2022 13:04:09 +0200
Subject: SL-16921 FIXED Viewer crashes on disconnect if 'About land' floater
 is opened

---
 indra/newview/llviewerparcelmgr.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 56370df751..e69b0347f8 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -878,7 +878,7 @@ LLParcel* LLViewerParcelMgr::getCollisionParcel() const
 
 void LLViewerParcelMgr::render()
 {
-	if (mSelected && mRenderSelection && gSavedSettings.getBOOL("RenderParcelSelection"))
+	if (mSelected && mRenderSelection && gSavedSettings.getBOOL("RenderParcelSelection") && !gDisconnected)
 	{
 		// Rendering is done in agent-coordinates, so need to supply
 		// an appropriate offset to the render code.
-- 
cgit v1.2.3


From 21baea0907027c655c5170975c0ea669430c9c40 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Thu, 24 Feb 2022 00:35:00 +0200
Subject: SL-3787 Fixed mesh uploader LoD generation returning worse results
 than higher lod

---
 indra/newview/llmodelpreview.cpp | 61 +++++++++++++++++++++++++++++-----------
 1 file changed, 44 insertions(+), 17 deletions(-)

diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 5d81d2c9b3..9e5a31d71e 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -1759,19 +1759,15 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
                 {
                     genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, true);
                 }
-
-                LL_INFOS() << "Model " << target_model->getName()
-                    << " lod " << which_lod
-                    << " simplified using per face method." << LL_ENDL;
             }
 
             if (model_meshopt_mode == MESH_OPTIMIZER_AUTO)
             {
-                // Switches between 'combine' method and 'per model sloppy' based on combine's result.
+                // Switches between 'combine' method and 'sloppy' based on combine's result.
                 F32 allowed_ratio_drift = 2.f;
-                F32 res_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
-
-                if (res_ratio < 0)
+                F32 precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+                
+                if (precise_ratio < 0)
                 {
                     // U16 vertices overflow, shouldn't happen, but just in case
                     for (U32 face_idx = 0; face_idx < base->getNumVolumeFaces(); ++face_idx)
@@ -1779,42 +1775,72 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
                         genMeshOptimizerPerFace(base, target_model, face_idx, indices_decimator, lod_error_threshold, false);
                     }
                 }
-                else if (res_ratio * allowed_ratio_drift < indices_decimator)
+                else if (precise_ratio * allowed_ratio_drift < indices_decimator)
                 {
                     // Try sloppy variant if normal one failed to simplify model enough.
-                    res_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
+                    // Sloppy variant can fail entirely and has issues with precision,
+                    // so code needs to do multiple attempts with different decimators.
+                    // Todo: this is a bit of a mess, needs to be refined and improved
+                    F32 last_working_decimator = 0.f;
+                    F32 last_working_ratio = F32_MAX;
+
+                    F32 sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
+
+                    if (sloppy_ratio > 0)
+                    {
+                        // Would be better to do a copy of target_model here, but if
+                        // we need to use sloppy decimation, model should be cheap
+                        // and fast to generate and it won't affect end result
+                        last_working_decimator = indices_decimator;
+                        last_working_ratio = sloppy_ratio;
+                    }
 
                     // Sloppy has a tendecy to error into lower side, so a request for 100
                     // triangles turns into ~70, so check for significant difference from target decimation
                     F32 sloppy_ratio_drift = 1.4f;
                     if (lod_mode == LIMIT_TRIANGLES
-                        && (res_ratio > indices_decimator * sloppy_ratio_drift || res_ratio < 0))
+                        && (sloppy_ratio > indices_decimator * sloppy_ratio_drift || sloppy_ratio < 0))
                     {
                         // Apply a correction to compensate.
 
                         // (indices_decimator / res_ratio) by itself is likely to overshoot to a differend
                         // side due to overal lack of precision, and we don't need an ideal result, which
                         // likely does not exist, just a better one, so a partial correction is enough.
-                        F32 sloppy_decimator = indices_decimator * (indices_decimator / res_ratio + 1) / 2;
-                        res_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
+                        F32 sloppy_decimator = indices_decimator * (indices_decimator / sloppy_ratio + 1) / 2;
+                        sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
                     }
 
+                    if (last_working_decimator > 0 && sloppy_ratio < last_working_ratio)
+                    {
+                        // Compensation didn't work, return back to previous decimator
+                        sloppy_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, true);
+                    }
+
+                    if (sloppy_ratio < 0)
+                    {
+                        // sloppy method didn't work, final attempt with lower decimation
+                        F32 sloppy_decimator = indices_decimator / decimation;
+                        sloppy_ratio = genMeshOptimizerPerModel(base, target_model, sloppy_decimator, lod_error_threshold, true);
+                    }
 
-                    if (res_ratio < 0)
+                    if (sloppy_ratio < 0 || sloppy_ratio < precise_ratio)
                     {
-                        // Sloppy variant failed to generate triangles.
+                        // Sloppy variant failed to generate triangles or is worse.
                         // Can happen with models that are too simple as is.
-                        // Fallback to normal method or use lower decimator.
-                        genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
+                        // Fallback to normal method
+
+                        precise_ratio = genMeshOptimizerPerModel(base, target_model, indices_decimator, lod_error_threshold, false);
 
                         LL_INFOS() << "Model " << target_model->getName()
                             << " lod " << which_lod
+                            << " resulting ratio " << precise_ratio
                             << " simplified using per model method." << LL_ENDL;
                     }
                     else
                     {
                         LL_INFOS() << "Model " << target_model->getName()
                             << " lod " << which_lod
+                            << " resulting ratio " << sloppy_ratio
                             << " sloppily simplified using per model method." << LL_ENDL;
                     }
                 }
@@ -1822,6 +1848,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
                 {
                     LL_INFOS() << "Model " << target_model->getName()
                         << " lod " << which_lod
+                        << " resulting ratio " << precise_ratio
                         << " simplified using per model method." << LL_ENDL;
                 }
             }
-- 
cgit v1.2.3