From 09aedbb7a9b4bfa56b7acd3250d10c483a5ac219 Mon Sep 17 00:00:00 2001
From: RunitaiLinden <davep@lindenlab.com>
Date: Mon, 16 Oct 2023 13:54:38 -0500
Subject: [PATCH] SL-20258 Fix for LSL spamming new probes into the scene
 deadlocking probe updater.  Add probe update debug display.

---
 indra/newview/llreflectionmapmanager.cpp      | 23 +++++++++++++++++--
 indra/newview/llviewermenu.cpp                |  6 ++++-
 indra/newview/pipeline.h                      |  3 ++-
 .../skins/default/xui/en/menu_viewer.xml      | 10 ++++++++
 4 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 915c8893a4e..283c97ff0a1 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -39,6 +39,8 @@
 extern BOOL gCubeSnapshot;
 extern BOOL gTeleportDisplay;
 
+static U32 sUpdateCount = 0;
+
 // get the next highest power of two of v (or v if v is already a power of two)
 //defined in llvertexbuffer.cpp
 extern U32 nhpo2(U32 v);
@@ -91,7 +93,7 @@ static bool check_priority(LLReflectionMap* a, LLReflectionMap* b)
         return false;
     }
     else if (b->mCubeIndex == -1)
-    { // certainly higher priority than b
+    { // b is not a candidate for updating, a is higher priority by default
         return true;
     }
     else if (!a->mComplete && !b->mComplete)
@@ -103,7 +105,13 @@ static bool check_priority(LLReflectionMap* a, LLReflectionMap* b)
         return update_score(a) > update_score(b);
     }
 
-    // one of these probes is not complete, if b is complete, a is higher priority
+    // a or b is not complete,
+    if (sUpdateCount % 3 == 0)
+    { // every third update, allow complete probes to cut in line in front of non-complete probes to avoid spammy probe generators from deadlocking scheduler (SL-20258))
+        return !b->mComplete;
+    }
+
+    // prioritize incomplete probe
     return b->mComplete;
 }
 
@@ -351,6 +359,7 @@ void LLReflectionMapManager::update()
         
         probe->autoAdjustOrigin();
 
+        sUpdateCount++;
         mUpdatingProbe = probe;
         doProbeUpdate();
     }
@@ -537,8 +546,14 @@ void LLReflectionMapManager::doProbeUpdate()
 
     updateProbeFace(mUpdatingProbe, mUpdatingFace);
     
+    bool debug_updates = gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PROBE_UPDATES) && mUpdatingProbe->mViewerObject;
+
     if (++mUpdatingFace == 6)
     {
+        if (debug_updates)
+        {
+            mUpdatingProbe->mViewerObject->setDebugText(llformat("%.1f", (F32)gFrameTimeSeconds), LLColor4(1, 1, 1, 1));
+        }
         updateNeighbors(mUpdatingProbe);
         mUpdatingFace = 0;
         if (isRadiancePass())
@@ -552,6 +567,10 @@ void LLReflectionMapManager::doProbeUpdate()
             mRadiancePass = true;
         }
     }
+    else if (debug_updates)
+    {
+        mUpdatingProbe->mViewerObject->setDebugText(llformat("%.1f", (F32)gFrameTimeSeconds), LLColor4(1, 1, 0, 1));
+    }
 }
 
 // Do the reflection map update render passes.
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 3708ad82e81..553eaaf9b2a 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -1089,7 +1089,11 @@ U64 info_display_from_string(std::string info_display)
 	}
     else if ("reflection probes" == info_display)
     {
-    return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES;
+        return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES;
+    }
+    else if ("probe updates" == info_display)
+    {
+        return LLPipeline::RENDER_DEBUG_PROBE_UPDATES;
     }
 	else
 	{
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index d4c6432e55a..6e4c9c7a972 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -605,7 +605,8 @@ class LLPipeline
 		RENDER_DEBUG_TEXEL_DENSITY		=  0x40000000,
 		RENDER_DEBUG_TRIANGLE_COUNT		=  0x80000000,
 		RENDER_DEBUG_IMPOSTORS			= 0x100000000,
-        RENDER_DEBUG_REFLECTION_PROBES  = 0x200000000
+        RENDER_DEBUG_REFLECTION_PROBES  = 0x200000000,
+        RENDER_DEBUG_PROBE_UPDATES      = 0x400000000
 	};
 
 public:
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 8b39ea192bd..0bfdead6e78 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2974,6 +2974,16 @@ function="World.EnvPreset"
            function="Advanced.ToggleInfoDisplay"
            parameter="reflection probes" />
         </menu_item_check>
+        <menu_item_check
+         label="Probe Updates"
+         name="Probe Updates">
+          <menu_item_check.on_check
+           function="Advanced.CheckInfoDisplay"
+           parameter="probe updates" />
+          <menu_item_check.on_click
+           function="Advanced.ToggleInfoDisplay"
+           parameter="probe updates" />
+        </menu_item_check>
         <menu_item_check
          label="Particles"
          name="Particles">
-- 
GitLab