From 10a770047d90045e882a65e5347da3530b189c42 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 11 Jun 2021 19:10:43 +0300
Subject: SL-15297 WIP Implement performance floater

---
 indra/newview/CMakeLists.txt                       |   2 +
 indra/newview/llavatarrendernotifier.cpp           |   2 +
 indra/newview/llavatarrendernotifier.h             |   3 +
 indra/newview/llfloaterperformance.cpp             | 216 ++++++++++
 indra/newview/llfloaterperformance.h               |  65 +++
 indra/newview/llnamelistctrl.cpp                   |  39 +-
 indra/newview/llnamelistctrl.h                     |  23 +-
 indra/newview/llviewerfloaterreg.cpp               |   2 +
 indra/newview/skins/default/colors.xml             |   6 +
 .../skins/default/textures/icons/green_dot.png     | Bin 0 -> 18614 bytes
 indra/newview/skins/default/textures/textures.xml  |   2 +
 .../skins/default/xui/en/floater_performance.xml   | 447 +++++++++++++++++++++
 indra/newview/skins/default/xui/en/menu_viewer.xml |   7 +
 .../default/xui/en/panel_performance_huds.xml      | 112 ++++++
 .../default/xui/en/panel_performance_nearby.xml    | 161 ++++++++
 .../xui/en/panel_performance_preferences.xml       | 257 ++++++++++++
 .../default/xui/en/panel_performance_scripts.xml   |  82 ++++
 .../xui/en/panel_performance_troubleshooting.xml   | 190 +++++++++
 18 files changed, 1602 insertions(+), 14 deletions(-)
 create mode 100644 indra/newview/llfloaterperformance.cpp
 create mode 100644 indra/newview/llfloaterperformance.h
 create mode 100644 indra/newview/skins/default/textures/icons/green_dot.png
 create mode 100644 indra/newview/skins/default/xui/en/floater_performance.xml
 create mode 100644 indra/newview/skins/default/xui/en/panel_performance_huds.xml
 create mode 100644 indra/newview/skins/default/xui/en/panel_performance_nearby.xml
 create mode 100644 indra/newview/skins/default/xui/en/panel_performance_preferences.xml
 create mode 100644 indra/newview/skins/default/xui/en/panel_performance_scripts.xml
 create mode 100644 indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml

(limited to 'indra/newview')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index fc8d8b805b..1ec1e2cc24 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -286,6 +286,7 @@ set(viewer_SOURCE_FILES
     llfloaterpathfindinglinksets.cpp
     llfloaterpathfindingobjects.cpp
     llfloaterpay.cpp
+    llfloaterperformance.cpp
     llfloaterperms.cpp
     llfloaterpostprocess.cpp
     llfloaterpreference.cpp
@@ -924,6 +925,7 @@ set(viewer_HEADER_FILES
     llfloaterpathfindinglinksets.h
     llfloaterpathfindingobjects.h
     llfloaterpay.h
+    llfloaterperformance.h
     llfloaterperms.h
     llfloaterpostprocess.h
     llfloaterpreference.h
diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp
index 94584a623b..4fd57c7341 100644
--- a/indra/newview/llavatarrendernotifier.cpp
+++ b/indra/newview/llavatarrendernotifier.cpp
@@ -298,6 +298,8 @@ void LLHUDRenderNotifier::updateNotificationHUD(hud_complexity_list_t complexity
         return;
     }
 
+    mHUDComplexityList = complexity;
+
     // TODO:
     // Find a way to show message with list of issues, but without making it too large
     // and intrusive.
diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h
index ec17b3d9e6..3fd7a32d84 100644
--- a/indra/newview/llavatarrendernotifier.h
+++ b/indra/newview/llavatarrendernotifier.h
@@ -121,6 +121,8 @@ public:
     void updateNotificationHUD(hud_complexity_list_t complexity);
     bool isNotificationVisible();
 
+    hud_complexity_list_t getHUDComplexityList() { return mHUDComplexityList; }
+
 private:
     enum EWarnLevel
     {
@@ -141,6 +143,7 @@ private:
     EWarnLevel mReportedHUDWarning;
     LLHUDComplexity mLatestHUDComplexity;
     LLFrameTimer mHUDPopUpDelayTimer;
+    hud_complexity_list_t mHUDComplexityList;
 };
 
 #endif /* ! defined(LL_llavatarrendernotifier_H) */
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
new file mode 100644
index 0000000000..8024d1539c
--- /dev/null
+++ b/indra/newview/llfloaterperformance.cpp
@@ -0,0 +1,216 @@
+/** 
+ * @file llfloaterperformance.cpp
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterperformance.h"
+
+#include "llappearancemgr.h"
+#include "llavatarrendernotifier.h"
+#include "llfeaturemanager.h"
+#include "llfloaterreg.h"
+#include "llnamelistctrl.h"
+#include "lltextbox.h"
+#include "llvoavatar.h"
+
+
+LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
+    : LLFloater(key)
+{
+
+}
+
+LLFloaterPerformance::~LLFloaterPerformance()
+{
+}
+
+BOOL LLFloaterPerformance::postBuild()
+{
+    mMainPanel = getChild<LLPanel>("panel_performance_main");
+    mTroubleshootingPanel = getChild<LLPanel>("panel_performance_troubleshooting");
+    mNearbyPanel = getChild<LLPanel>("panel_performance_nearby");
+    mScriptsPanel = getChild<LLPanel>("panel_performance_scripts");
+    mPreferencesPanel = getChild<LLPanel>("panel_performance_preferences");
+    mHUDsPanel = getChild<LLPanel>("panel_performance_huds");
+
+    getChild<LLPanel>("troubleshooting_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mTroubleshootingPanel));
+    getChild<LLPanel>("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel));
+    getChild<LLPanel>("scripts_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mScriptsPanel));
+    getChild<LLPanel>("preferences_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mPreferencesPanel));
+    getChild<LLPanel>("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel));
+
+    initBackBtn(mTroubleshootingPanel);
+    initBackBtn(mNearbyPanel);
+    initBackBtn(mScriptsPanel);
+    initBackBtn(mPreferencesPanel);
+    initBackBtn(mHUDsPanel);
+
+
+    mHUDsPanel->getChild<LLButton>("refresh_list_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::populateHUDList, this));
+ 
+    mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");
+    mHUDList->setNameListType(LLNameListCtrl::SPECIAL);
+    mHUDList->setHoverIconName("StopReload_Off");
+    mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
+
+    mPreferencesPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
+    mPreferencesPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickRecommended, this));
+
+    mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
+    mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
+ 
+    return TRUE;
+}
+
+void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
+{
+    selected_panel->setVisible(TRUE);
+    mMainPanel->setVisible(FALSE);
+
+    if (mHUDsPanel == selected_panel)
+    {
+        populateHUDList();
+    }
+    else if (mNearbyPanel == selected_panel)
+    {
+        populateNearbyList();
+    }
+}
+
+void LLFloaterPerformance::showMainPanel()
+{
+    mTroubleshootingPanel->setVisible(FALSE);
+    mNearbyPanel->setVisible(FALSE);
+    mScriptsPanel->setVisible(FALSE);
+    mHUDsPanel->setVisible(FALSE);
+    mPreferencesPanel->setVisible(FALSE);
+    mMainPanel->setVisible(TRUE);
+}
+
+void LLFloaterPerformance::initBackBtn(LLPanel* panel)
+{
+    panel->getChild<LLButton>("back_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::showMainPanel, this));
+
+    panel->getChild<LLTextBox>("back_lbl")->setShowCursorHand(false);
+    panel->getChild<LLTextBox>("back_lbl")->setSoundFlags(LLView::MOUSE_UP);
+    panel->getChild<LLTextBox>("back_lbl")->setClickedCallback(boost::bind(&LLFloaterPerformance::showMainPanel, this));
+}
+
+void LLFloaterPerformance::populateHUDList()
+{
+    mHUDList->clearRows();
+    mHUDList->updateColumns(true);
+
+    hud_complexity_list_t complexity_list = LLHUDRenderNotifier::getInstance()->getHUDComplexityList();
+
+    hud_complexity_list_t::iterator iter = complexity_list.begin();
+    hud_complexity_list_t::iterator end = complexity_list.end();
+   
+    for (; iter != end; ++iter)
+    {
+        LLHUDComplexity hud_object_complexity = *iter;        
+
+        LLSD item;
+        item["special_id"] = hud_object_complexity.objectId;
+        item["target"] = LLNameListCtrl::SPECIAL;
+        LLSD& row = item["columns"];
+        row[0]["column"] = "complex_visual";
+        row[0]["type"] = "text";
+        row[0]["value"] = "*";
+
+        row[1]["column"] = "complex_value";
+        row[1]["type"] = "text";
+        row[1]["value"] = std::to_string(hud_object_complexity.objectsCost);
+        row[1]["font"]["name"] = "SANSSERIF";
+ 
+        row[2]["column"] = "name";
+        row[2]["type"] = "text";
+        row[2]["value"] = hud_object_complexity.objectName;
+        row[2]["font"]["name"] = "SANSSERIF";
+
+        mHUDList->addElement(item);
+    }
+
+    mHUDsPanel->getChild<LLTextBox>("huds_value")->setValue(std::to_string(complexity_list.size()));
+}
+
+void LLFloaterPerformance::populateNearbyList()
+{
+    mNearbyList->clearRows();
+    mNearbyList->updateColumns(true);
+
+    std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
+    while (char_iter != LLCharacter::sInstances.end())
+    {
+        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
+        if (avatar && !avatar->isDead() && !avatar->isControlAvatar())
+        {
+            avatar->calculateUpdateRenderComplexity(); 
+
+            LLSD item;
+            item["id"] = avatar->getID();
+            LLSD& row = item["columns"];
+            row[0]["column"] = "complex_visual";
+            row[0]["type"] = "text";
+            row[0]["value"] = "*";
+
+            row[1]["column"] = "complex_value";
+            row[1]["type"] = "text";
+            row[1]["value"] = std::to_string( avatar->getVisualComplexity());
+            row[1]["font"]["name"] = "SANSSERIF";
+
+            row[2]["column"] = "name";
+            row[2]["type"] = "text";
+            row[2]["value"] = avatar->getFullname();
+            row[2]["font"]["name"] = "SANSSERIF";
+
+            mNearbyList->addElement(item);
+        }
+        char_iter++;
+    }
+
+}
+
+void LLFloaterPerformance::detachItem(const LLUUID& item_id)
+{
+    LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
+    mHUDList->removeNameItem(item_id);
+}
+
+void LLFloaterPerformance::onClickRecommended()
+{
+    LLFeatureManager::getInstance()->applyRecommendedSettings();
+}
+
+void LLFloaterPerformance::onClickAdvanced()
+{
+    LLFloaterReg::showInstance("prefs_graphics_advanced");
+}
+
+void LLFloaterPerformance::onClickExceptions()
+{
+    LLFloaterReg::showInstance("avatar_render_settings");
+}
+
+// EOF
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
new file mode 100644
index 0000000000..a70a328d3a
--- /dev/null
+++ b/indra/newview/llfloaterperformance.h
@@ -0,0 +1,65 @@
+/** 
+ * @file llfloaterperformance.h
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERPERFORMANCE_H
+#define LL_LLFLOATERPERFORMANCE_H
+
+#include "llfloater.h"
+
+class LLNameListCtrl;
+
+class LLFloaterPerformance : public LLFloater
+{
+public:
+    LLFloaterPerformance(const LLSD& key);
+    virtual ~LLFloaterPerformance();
+
+    /*virtual*/ BOOL postBuild();
+
+    void showSelectedPanel(LLPanel* selected_panel);
+    void showMainPanel();
+
+    void detachItem(const LLUUID& item_id);
+
+private:
+    void initBackBtn(LLPanel* panel);
+    void populateHUDList();
+    void populateNearbyList();
+
+    void onClickAdvanced();
+    void onClickRecommended();
+    void onClickExceptions();
+
+    LLPanel* mMainPanel;
+    LLPanel* mTroubleshootingPanel;
+    LLPanel* mNearbyPanel;
+    LLPanel* mScriptsPanel;
+    LLPanel* mHUDsPanel;
+    LLPanel* mPreferencesPanel;
+    LLNameListCtrl* mHUDList;
+    LLNameListCtrl* mNearbyList;
+};
+
+#endif // LL_LLFLOATERPERFORMANCE_H
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 3209d23e43..e1bf9b1a17 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -67,7 +67,9 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
 	mNameColumn(p.name_column.column_name),
 	mAllowCallingCardDrop(p.allow_calling_card_drop),
 	mShortNames(p.short_names),
-	mPendingLookupsRemaining(0)
+	mPendingLookupsRemaining(0),
+    mHoverIconName("Info_Small"),
+    mNameListType(INDIVIDUAL)
 {}
 
 // public
@@ -134,7 +136,12 @@ BOOL LLNameListCtrl::handleDragAndDrop(
 
 void LLNameListCtrl::showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience)
 {
-	if(is_experience)
+    if (isSpecialType())
+    {
+        mIconClickedSignal(avatar_id);
+        return;
+    }
+    if(is_experience)
 	{
 		LLFloaterReg::showInstance("experience_profile", avatar_id, true);
 		return;
@@ -215,14 +222,16 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
 	S32 column_index = getColumnIndexFromOffset(x);
 	LLNameListItem* hit_item = dynamic_cast<LLNameListItem*>(hitItem(x, y));
 	LLFloater* floater = gFloaterView->getParentFloater(this);
-	if (floater 
+
+
+    if (floater 
 		&& floater->isFrontmost()
 		&& hit_item
-		&& column_index == mNameColumnIndex)
+		&& ((column_index == mNameColumnIndex) || isSpecialType()))
 	{
-		// ...this is the column with the avatar name
-		LLUUID avatar_id = hit_item->getUUID();
-		if (avatar_id.notNull())
+        // ...this is the column with the avatar name
+		LLUUID item_id = isSpecialType() ? hit_item->getSpecialID() : hit_item->getUUID();
+		if (item_id.notNull())
 		{
 			// ...valid avatar id
 
@@ -230,13 +239,13 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
 			if (hit_cell)
 			{
 				S32 row_index = getItemIndex(hit_item);
-				LLRect cell_rect = getCellRect(row_index, column_index);
+				LLRect cell_rect = getCellRect(row_index, isSpecialType() ? getNumColumns() - 1 : column_index);
 				// Convert rect local to screen coordinates
 				LLRect sticky_rect;
 				localRectToScreen(cell_rect, &sticky_rect);
 
 				// Spawn at right side of cell
-				LLPointer<LLUIImage> icon = LLUI::getUIImage("Info_Small");
+				LLPointer<LLUIImage> icon = LLUI::getUIImage(mHoverIconName);
 				S32 screenX = sticky_rect.mRight - info_icon_size;
 				S32 screenY = sticky_rect.mTop - (sticky_rect.getHeight() - icon->getHeight()) / 2;
 				LLCoordGL pos(screenX, screenY);
@@ -250,7 +259,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
 
 					LLToolTip::Params params;
 					params.background_visible(false);
-					params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, avatar_id, is_group, is_experience));
+					params.click_callback(boost::bind(&LLNameListCtrl::showInspector, this, item_id, is_group, is_experience));
 					params.delay_time(0.0f);		// spawn instantly on hover
 					params.image(icon);
 					params.message("");
@@ -321,6 +330,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
 
 	// use supplied name by default
 	std::string fullname = name_item.name;
+
 	switch(name_item.target)
 	{
 	case GROUP:
@@ -339,8 +349,10 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
 		}
 		break;
 	case SPECIAL:
-		// just use supplied name
-		break;
+        {
+        item->setSpecialID(name_item.special_id());
+        return item;
+        }
 	case INDIVIDUAL:
 		{
 			LLAvatarName av_name;
@@ -420,7 +432,8 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
 	for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++)
 	{
 		LLScrollListItem* item = *it;
-		if (item->getUUID() == agent_id)
+        LLUUID cur_id = isSpecialType() ? dynamic_cast<LLNameListItem*>(item)->getSpecialID() : item->getUUID();
+        if (cur_id == agent_id)
 		{
 			idx = getItemIndex(item);
 			break;
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index ef0be135e6..1a31b1cc10 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -46,6 +46,8 @@ public:
 	void setIsGroup(bool is_group) { mIsGroup = is_group; }
 	bool isExperience() const { return mIsExperience; }
 	void setIsExperience(bool is_experience) { mIsExperience = is_experience; }
+    void setSpecialID(const LLUUID& special_id) { mSpecialID = special_id; }
+    const LLUUID& getSpecialID() const { return mSpecialID; }
 
 protected:
 	friend class LLNameListCtrl;
@@ -68,6 +70,8 @@ protected:
 private:
 	bool mIsGroup;
 	bool mIsExperience;
+
+    LLUUID mSpecialID;
 };
 
 
@@ -95,10 +99,12 @@ public:
 	{
 		Optional<std::string>				name;
 		Optional<ENameType, NameTypeNames>	target;
+        Optional<LLUUID>                    special_id;
 
 		NameItem()
 		:	name("name"),
-			target("target", INDIVIDUAL)
+			target("target", INDIVIDUAL),
+            special_id("special_id", LLUUID())
 		{}
 	};
 
@@ -170,6 +176,12 @@ public:
 	/*virtual*/ void updateColumns(bool force_update);
 
 	/*virtual*/ void mouseOverHighlightNthItem( S32 index );
+
+    bool isSpecialType() { return (mNameListType == SPECIAL); }
+
+    void setNameListType(e_name_type type) { mNameListType = type; }
+    void setHoverIconName(std::string icon_name) { mHoverIconName = icon_name; }
+
 private:
 	void showInspector(const LLUUID& avatar_id, bool is_group, bool is_experience = false);
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name, std::string suffix, std::string prefix, LLHandle<LLNameListItem> item);
@@ -186,6 +198,11 @@ private:
 
 	S32 mPendingLookupsRemaining;
 	namelist_complete_signal_t mNameListCompleteSignal;
+
+    std::string     mHoverIconName;
+    e_name_type     mNameListType;
+
+    boost::signals2::signal<void(const LLUUID &)> mIconClickedSignal;
 	
 public:
 	boost::signals2::connection setOnNameListCompleteCallback(boost::function<void(bool)> onNameListCompleteCallback) 
@@ -193,6 +210,10 @@ public:
 		return mNameListCompleteSignal.connect(onNameListCompleteCallback); 
 	}
 
+    boost::signals2::connection setIconClickedCallback(boost::function<void(const LLUUID &)> cb) 
+    { 
+        return mIconClickedSignal.connect(cb); 
+    }
 };
 
 
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 414ae1fad6..eabdb67188 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -102,6 +102,7 @@
 #include "llfloaterpathfindingconsole.h"
 #include "llfloaterpathfindinglinksets.h"
 #include "llfloaterpay.h"
+#include "llfloaterperformance.h"
 #include "llfloaterperms.h"
 #include "llfloaterpostprocess.h"
 #include "llfloaterpreference.h"
@@ -299,6 +300,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("pathfinding_linksets", "floater_pathfinding_linksets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingLinksets>);
 	LLFloaterReg::add("pathfinding_console", "floater_pathfinding_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPathfindingConsole>);
 	LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
+	LLFloaterReg::add("performance", "floater_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerformance>);
 	LLFloaterReg::add("perms_default", "floater_perms_default.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPermsDefault>);
 	LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index efe8102f83..3816bf7e9a 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -963,4 +963,10 @@
   <color
     name="OutfitGalleryItemUnselected"
     value="0.4 0.4 0.4 1" />
+  <color
+    name="PerformanceFloaterGray"
+    value="0.27 0.27 0.27 1" />
+  <color
+    name="PerformanceMid"
+    value="1 0.8 0 1" />
 </colors>
diff --git a/indra/newview/skins/default/textures/icons/green_dot.png b/indra/newview/skins/default/textures/icons/green_dot.png
new file mode 100644
index 0000000000..02c07810c2
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/green_dot.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a875c4e848..51bb91cbf9 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -234,6 +234,8 @@ with the same filename but different name
   <texture name="Generic_Person" file_name="icons/Generic_Person.png" preload="false" />
   <texture name="Generic_Person_Large" file_name="icons/Generic_Person_Large.png" preload="false" />
 
+  <texture name="Green_dot" file_name="icons/green_dot.png" preload="false" />
+
   <texture name="Hand" file_name="icons/hand.png" preload="false" />
   
   <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
new file mode 100644
index 0000000000..42269ba34a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -0,0 +1,447 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="550"
+ layout="topleft"
+ name="performance"
+ save_rect="true"
+ title="IMPROVE GRAPHICS SPEED"
+ width="580">
+  <panel
+   bevel_style="none"
+   follows="left|top"
+   height="490"
+   width="580"
+   name="panel_performance_main"
+   visible="true"
+   layout="topleft"
+   left="0"   
+   top="0">
+    <text
+     follows="left|top"
+     font="SansSerifHuge"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="fps_lbl"
+     top="17"
+     width="130">
+        Current FPS
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerifHugeBold"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left_pad="5"
+     name="fps_value"
+     width="100">
+        75.2
+    </text>
+  
+    <icon
+     height="16"
+     width="16"
+     image_name="Green_dot"
+     mouse_opaque="true"
+     name="icon_arrow4"
+     follows="right|top"
+     top="16"
+     right="-154"/>
+    <icon
+     height="16"
+     width="16"
+     image_name="Green_dot"
+     mouse_opaque="true"
+     name="icon_arrow4"
+     follows="right|top"
+     top_pad="9"/>
+    <icon
+     height="16"
+     width="16"
+     image_name="Green_dot"
+     mouse_opaque="true"
+     name="icon_arrow4"
+     follows="right|top"
+     top_pad="8"/>
+ 
+    <text
+     follows="right|top"
+     font="SansSerif"
+     height="20"
+     layout="topleft"
+     top="17"
+     right="-90"
+     name="client_lbl"
+     width="60">
+        Client:
+    </text>
+    <text
+     follows="right|top"
+     font="SansSerif"
+     height="20"
+     layout="topleft"
+     top_pad="5"
+     name="client_lbl"
+     width="60">
+        Network:
+    </text>
+    <text
+     follows="right|top"
+     font="SansSerif"
+     height="20"
+     layout="topleft"
+     top_pad="5"
+     name="client_lbl"
+     width="60">
+        Server:
+    </text>
+    <text
+     follows="right|top"
+     font="SansSerif"
+     height="20"
+     layout="topleft"
+     right="-15"
+     name="client_value"
+     top="17"
+     width="45">
+        Normal
+    </text>
+    <text
+     follows="right|top"
+     font="SansSerif"
+     height="20"
+     layout="topleft"
+     name="network_value"
+     top_pad="5"
+     width="45">
+        Normal
+    </text>
+    <text
+     follows="right|top"
+     font="SansSerif"
+     height="20"
+     layout="topleft"
+     name="server_value"
+     top_pad="5"
+     width="45">
+        Normal
+    </text> 
+  <panel
+   bg_alpha_color="PerformanceFloaterGray"
+   background_visible="true"
+   background_opaque="false"
+   border="true"
+   bevel_style="none"
+   follows="left|top"
+   height="60"
+   width="560"
+   name="troubleshooting_subpanel"
+   layout="topleft"
+   left="10"
+   top="102">
+    <text
+     follows="left|top"
+     font="SansSerifLarge"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="troubleshooting_lbl"
+     top="12"
+     width="395">
+        General troubleshooting
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerif"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="troubleshooting_info"
+     top_pad="5"
+     width="395">
+        Choose among common problems and see what you can do.
+    </text>
+    <icon
+     height="16"
+     width="16"
+     image_name="Arrow_Right_Off"
+     mouse_opaque="true"
+     name="icon_arrow1"
+     follows="right|top"
+     top="24"
+     right="-20"/>
+  </panel>
+  <panel
+   bg_alpha_color="PerformanceFloaterGray"
+   background_visible="true"
+   background_opaque="false"
+   border="true"
+   bevel_style="none"
+   follows="left|top"
+   height="60"
+   width="560"
+   name="nearby_subpanel"
+   layout="topleft"
+   top_pad="20">
+    <text
+     follows="left|top"
+     font="SansSerifLarge"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="avatars_nearby_lbl"
+     top="12"
+     width="115">
+        Avatars nearby:
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerifLarge"
+     text_color="PerformanceMid"
+     height="20"
+     layout="topleft"
+     left_pad="3"
+     name="avatars_nearby_value"
+     width="100">
+        42 (very high)
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerif"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="avatars_nearby_info"
+     top_pad="5"
+     width="395">
+        Click to review avatars and choose a complexity limit.
+    </text>
+    <icon
+     height="16"
+     width="16"
+     image_name="Arrow_Right_Off"
+     mouse_opaque="true"
+     name="icon_arrow2"
+     follows="right|top"
+     top="24"
+     right="-20"/>
+  </panel>
+  <panel
+   bg_alpha_color="PerformanceFloaterGray"
+   background_visible="true"
+   background_opaque="false"
+   border="true"
+   bevel_style="none"
+   follows="left|top"
+   height="60"
+   width="560"
+   name="preferences_subpanel"
+   layout="topleft"
+   top_pad="20">
+    <text
+     follows="left|top"
+     font="SansSerifLarge"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="complexity_lbl"
+     top="12"
+     width="110">
+        This location is
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerifLarge"
+     text_color="PerformanceMid"
+     height="20"
+     layout="topleft"
+     left_pad="3"
+     name="complexity_value"
+     width="100">
+        very complex
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerif"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="complexity_info"
+     top_pad="5"
+     width="395">
+        Try changing graphics quality or draw distance.
+    </text>
+    <icon
+     height="16"
+     width="16"
+     image_name="Arrow_Right_Off"
+     mouse_opaque="true"
+     name="icon_arrow3"
+     follows="right|top"
+     top="24"
+     right="-20"/>
+  </panel>
+  <panel
+   bg_alpha_color="PerformanceFloaterGray"
+   background_visible="true"
+   background_opaque="false"
+   border="true"
+   bevel_style="none"
+   follows="left|top"
+   height="60"
+   width="560"
+   name="scripts_subpanel"
+   layout="topleft"
+   top_pad="20">
+    <text
+     follows="left|top"
+     font="SansSerifLarge"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="scripts_lbl"
+     top="12"
+     width="88">
+        Your avatar:
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerifLarge"
+     text_color="PerformanceMid"
+     height="20"
+     layout="topleft"
+     left_pad="2"
+     name="scripts_value"
+     width="100">
+        12 scripts
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerif"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="scripts_info"
+     top_pad="5"
+     width="395">
+        Removing high-impact attachments may improve graphics speed.
+    </text>
+    <icon
+     height="16"
+     width="16"
+     image_name="Arrow_Right_Off"
+     mouse_opaque="true"
+     name="icon_arrow4"
+     follows="right|top"
+     top="24"
+     right="-20"/>
+  </panel>
+  <panel
+   bg_alpha_color="PerformanceFloaterGray"
+   background_visible="true"
+   background_opaque="false"
+   border="true"
+   bevel_style="none"
+   follows="left|top"
+   height="60"
+   width="560"
+   name="huds_subpanel"
+   layout="topleft"
+   top_pad="20">
+    <text
+     follows="left|top"
+     font="SansSerifLarge"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="huds_lbl"
+     top="12"
+     width="80">
+        Your HUDs:
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerifLarge"
+     text_color="PerformanceMid"
+     height="20"
+     layout="topleft"
+     left_pad="3"
+     name="huds_value"
+     width="100">
+        7
+    </text>
+    <text
+     follows="left|top"
+     font="SansSerif"
+     text_color="White"
+     height="20"
+     layout="topleft"
+     left="10"
+     name="huds_info"
+     top_pad="5"
+     width="395">
+        Removing HUDs you are not using can improve graphics speed.
+    </text>
+    <icon
+     height="16"
+     width="16"
+     image_name="Arrow_Right_Off"
+     mouse_opaque="true"
+     name="icon_arrow4"
+     follows="right|top"
+     top="24"
+     right="-20"/>
+  </panel>
+ </panel>
+  <panel
+    filename="panel_performance_troubleshooting.xml"
+    follows="all"
+    layout="topleft"
+    left="0"
+    name="panel_performance_troubleshooting"
+    visible="false"
+    top="0" />
+  <panel
+    filename="panel_performance_nearby.xml"
+    follows="all"
+    layout="topleft"
+    left="0"
+    name="panel_performance_nearby"
+    visible="false"
+    top="0" />
+  <panel
+    filename="panel_performance_scripts.xml"
+    follows="all"
+    layout="topleft"
+    left="0"
+    name="panel_performance_scripts"
+    visible="false"
+    top="0" />
+  <panel
+    filename="panel_performance_preferences.xml"
+    follows="all"
+    layout="topleft"
+    left="0"
+    name="panel_performance_preferences"
+    visible="false"
+    top="0" />
+  <panel
+    filename="panel_performance_huds.xml"
+    follows="all"
+    layout="topleft"
+    left="0"
+    name="panel_performance_huds"
+    visible="false"
+    top="0" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 0a50ff089f..f275b309a1 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -238,6 +238,13 @@
             <menu_item_call.on_click
              function="Floater.Toggle"
              parameter="preferences" />
+        </menu_item_call>
+        <menu_item_call
+          label="Performance..."
+          name="Performance">
+          <menu_item_call.on_click
+           function="Floater.Toggle"
+           parameter="performance" />
         </menu_item_call>
          <menu_item_call
          label="Toolbar buttons..."
diff --git a/indra/newview/skins/default/xui/en/panel_performance_huds.xml b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
new file mode 100644
index 0000000000..c881fadbe8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="left|top"
+ height="490"
+ width="580"
+ name="panel_performance_huds"
+ layout="topleft"
+ left="0"
+ top="0">
+  <button
+    height="16"
+    width="16"
+    layout="topleft"
+    mouse_opaque="true"
+    follows="left|top"
+    name="back_btn"
+    top="10"
+    image_selected="Arrow_Left_Off"
+    image_pressed="Arrow_Left_Off"
+    image_unselected="Arrow_Left_Off"
+    left="15"
+    is_toggle="true">
+  </button>
+  <text
+   follows="left|top"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   top="13"
+   name="back_lbl"
+   width="40">
+    Back
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="PerformanceMid"
+   height="20"
+   layout="topleft"
+   left="20"
+   top_pad="10"
+   name="huds_title"
+   width="120">
+    HUDs displayed: 
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLargeBold"
+   text_color="PerformanceMid"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   name="huds_value"
+   width="70">
+    7
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   left="20"
+   name="huds_desc1"
+   width="540">
+    If there are any you don't need, detaching them may improve graphics speed.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="3"
+   left="20"
+   name="huds_desc2"
+   width="540">
+    Note: Using a HUD's minimize button does not save memory. 
+  </text>
+  <name_list
+    column_padding="0"
+    draw_stripes="true"
+    height="220"
+    follows="left|top"
+    layout="topleft"
+    name="hud_list"
+    top_pad="10"
+    width="540">
+        <name_list.columns
+         label=""
+         name="complex_visual"
+         width="90" />
+        <name_list.columns
+         label=""
+         name="complex_value"
+         width="40" />
+        <name_list.columns
+         label=""
+         name="name"/>
+  </name_list>
+  <button
+   follows="left|top"
+   height="19"
+   label="Refresh List"
+   layout="topleft"
+   name="refresh_list_btn"
+   top_pad="20"
+   width="100" />
+</panel>
+
diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
new file mode 100644
index 0000000000..ade5f99451
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="left|top"
+ height="490"
+ width="580"
+ name="panel_performance_nearby"
+ layout="topleft"
+ left="0"
+ top="0">
+  <button
+    height="16"
+    width="16"
+    layout="topleft"
+    mouse_opaque="true"
+    follows="left|top"
+    name="back_btn"
+    top="10"
+    image_selected="Arrow_Left_Off"
+    image_pressed="Arrow_Left_Off"
+    image_unselected="Arrow_Left_Off"
+    left="15"
+    is_toggle="true">
+  </button>
+  <text
+   follows="left|top"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   top="13"
+   name="back_lbl"
+   width="40">
+    Back
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="PerformanceMid"
+   height="20"
+   layout="topleft"
+   left="20"
+   top_pad="10"
+   name="av_nearby_title"
+   width="215">
+    Avatars within draw distance:
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLargeBold"
+   text_color="PerformanceMid"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   name="av_nearby_value"
+   width="150">
+    42 (very high)
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left="20"
+   top_pad="5"
+   name="av_nearby_desc"
+   width="580">
+    Some avatars nearby are slow to display. Choosing complexity limit may help graphics speed.
+  </text>
+  <slider
+    control_name="IndirectMaxComplexity"
+    tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
+    follows="left|top"
+    height="16"
+    initial_value="101"
+    increment="1"
+    label="Avatar Maximum Complexity:"
+    label_width="165"
+    layout="topleft"
+    min_val="1"
+    max_val="101"
+    name="IndirectMaxComplexity"
+    show_text="false"
+    top_pad="10"
+    width="300">
+    <slider.commit_callback
+      function="Pref.UpdateIndirectMaxComplexity"
+      parameter="IndirectMaxComlexityText" />
+  </slider>
+  <text
+    type="string"
+    length="1"
+    follows="left|top"
+    height="16"
+    layout="topleft"
+    top_delta="0"
+    left_delta="304"
+    text_readonly_color="LabelDisabledColor"
+    name="IndirectMaxComplexityText"
+    width="65">
+    0
+  </text>
+  <name_list
+    column_padding="0"
+    draw_stripes="true"
+    height="220"
+    left="20"
+    follows="left|top"
+    layout="topleft"
+    sort_column="complex_value"
+    name="nearby_list"
+    name_column="name"
+    top_pad="10"
+    width="540">
+        <name_list.columns
+         label=""
+         name="complex_visual"
+         width="90" />
+        <name_list.columns
+         label=""
+         name="complex_value"
+         width="40" />
+        <name_list.columns
+         label=""
+         name="name"/>
+  </name_list>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left="20"
+   top_pad="10"
+   name="av_nearby_desc2"
+   width="580">
+     You can also right-click on an avatar to control display.
+  </text>
+  <button
+    height="23"
+    label="Exceptions..."
+    layout="topleft"
+    left="460"
+    top_delta="2"
+    name="exceptions_btn"
+    width="100">
+  </button>
+  <check_box
+    control_name="AlwaysRenderFriends"
+    height="16"
+    initial_value="true"
+    label="Always display friends"
+    layout="topleft"
+    name="display_friends"
+    top_pad="3"
+    left="18"
+    width="256">
+  </check_box>
+
+ 
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
new file mode 100644
index 0000000000..81605b35a2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -0,0 +1,257 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="left|top"
+ height="490"
+ width="580"
+ name="panel_performance_preferences"
+ layout="topleft"
+ left="0"
+ top="0">
+  <button
+    height="16"
+    width="16"
+    layout="topleft"
+    mouse_opaque="true"
+    follows="left|top"
+    name="back_btn"
+    top="10"
+    image_selected="Arrow_Left_Off"
+    image_pressed="Arrow_Left_Off"
+    image_unselected="Arrow_Left_Off"
+    left="15"
+    is_toggle="true">
+  </button>
+  <text
+   follows="left|top"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   top="13"
+   name="back_lbl"
+   width="40">
+    Back
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="PerformanceMid"
+   height="20"
+   layout="topleft"
+   left="20"
+   top_pad="10"
+   name="preferences_title"
+   width="300">
+    This location is very complex
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   name="preferences_desc"
+   width="580">
+    While you are here, you may want to reduce graphics quality or draw distance.
+  </text>
+
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="35"
+   name="quality_lbl"
+   width="100">
+    Graphics quality
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left_pad="40"
+   name="fastest_lbl"
+   width="40">
+    Fastest
+  </text>
+  <slider
+    control_name="RenderQualityPerformance"
+    decimal_digits="0"
+    follows="left|top"
+    height="16"
+    increment="1"
+    initial_value="0"
+    layout="topleft"
+    left_pad="5"
+    max_val="6"
+    name="graphics_quality"
+    show_text="false"
+    top_delta="-1"
+    width="275">
+  </slider>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left_pad="10"
+   top_delta="1"
+   name="quality_lbl"
+   width="70">
+    Best quality
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="40"
+   left="20"
+   name="enhancements_lbl"
+   width="100">
+    Enhancements
+  </text>
+  <check_box
+    control_name="WindLightUseAtmosShaders"
+    height="16"
+    initial_value="true"
+    label="Atmospheric shaders"
+    layout="topleft"
+    name="atmospheric_shaders"
+    left_pad="37"
+    width="280">
+  </check_box>
+  <check_box
+    control_name="RenderDeferred"
+    height="16"
+    initial_value="true"
+    label="Advanced Lighting Model"
+    layout="topleft"
+    name="advanced_lighting_model"
+    top_delta="24"
+    width="256">
+  </check_box>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="40"
+   left="20"
+   name="distance_lbl"
+   width="100">
+    Draw distance
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left_pad="40"
+   name="faster_lbl"
+   width="40">
+    Faster
+  </text>
+  <slider
+    control_name="RenderFarClip"
+    decimal_digits="0"
+    follows="left|top"
+    top_delta="-1"
+    height="16"
+    increment="8"
+    initial_value="160"
+    label_width="90"
+    layout="topleft"
+    min_val="64"
+    max_val="512"
+    name="draw_distance"
+    left_pad="5"
+    width="250" />
+  <text
+    type="string"
+    length="1"
+    follows="left|top"
+    height="12"
+    layout="topleft"
+    left_pad="1"
+    top_delta="0"
+    name="draw_distance_m"
+    width="20">
+    m
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left_pad="10"
+   top_delta="1"
+   name="farther_lbl"
+   width="40">
+    Farther
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="20"
+   left="160"
+   name="distance_desc1"
+   width="100">
+    Regions are 256 m x 256 m.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   left="160"
+   name="distance_desc2"
+   width="400">
+    To zoom out and see long distances, increase the draw distance.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   left="160"
+   name="distance_desc3"
+   width="400">
+    If you are socializing in a small area, decrease the draw distance.
+  </text>
+  <button
+    follows="top|left"
+    height="23"
+    label="Reset to recommended settings"
+    layout="topleft"
+    left="20"
+    name="defaults_btn"
+    top_delta="50"
+    width="210">
+  </button>
+  <button
+    follows="top|left"
+    height="23"
+    label="Advanced Settings..."
+    layout="topleft"
+    left_pad="10"
+    name="advanced_btn"
+    top_delta="0"
+    width="200"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_scripts.xml b/indra/newview/skins/default/xui/en/panel_performance_scripts.xml
new file mode 100644
index 0000000000..e6dc4a217d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_performance_scripts.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="left|top"
+ height="490"
+ width="580"
+ name="panel_performance_scripts"
+ layout="topleft"
+ left="0"
+ top="0">
+  <button
+    height="16"
+    width="16"
+    layout="topleft"
+    mouse_opaque="true"
+    follows="left|top"
+    name="back_btn"
+    top="10"
+    image_selected="Arrow_Left_Off"
+    image_pressed="Arrow_Left_Off"
+    image_unselected="Arrow_Left_Off"
+    left="15"
+    is_toggle="true">
+  </button>
+  <text
+   follows="left|top"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   top="13"
+   name="back_lbl"
+   width="40">
+    Back
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="PerformanceMid"
+   height="20"
+   layout="topleft"
+   left="20"
+   top_pad="10"
+   name="attachments_title"
+   width="195">
+    Avatar attachment scripts: 
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLargeBold"
+   text_color="PerformanceMid"
+   height="20"
+   layout="topleft"
+   left_pad="5"
+   name="attachments_value"
+   width="70">
+    12
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   left="20"
+   name="attachments_desc1"
+   width="580">
+    These attachments contain scripts (embedded apps) that use memory.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="3"
+   left="20"
+   name="attachments_desc2"
+   width="580">
+    If there are any you don't need, detaching them may improve graphics speed.
+  </text>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml b/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml
new file mode 100644
index 0000000000..d942580880
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="left|top"
+ height="490"
+ width="580"
+ name="panel_performance_troubleshooting"
+ layout="topleft"
+ left="0"
+ top="0">
+  <button
+    height="16"
+    width="16"
+    layout="topleft"
+    mouse_opaque="true"
+    follows="left|top"
+    name="back_btn"
+    top="10"
+    image_selected="Arrow_Left_Off"
+    image_pressed="Arrow_Left_Off"
+    image_unselected="Arrow_Left_Off"
+    left="15"
+    is_toggle="true">
+  </button>
+  <text
+   follows="left|top"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   top="13"
+   name="back_lbl"
+   width="40">
+    Back
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="PerformanceMid"
+   height="20"
+   layout="topleft"
+   left="20"
+   top_pad="10"
+   name="troubleshooting_title"
+   width="300">
+    Fixes for common problems
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   name="troubleshooting_desc"
+   width="580">
+    Some problems result from the complexity of the location where you are. All you can do is leave.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="White"
+   height="20"
+   layout="topleft"
+   top_pad="30"
+   name="rubberbanding_title"
+   width="580">
+    Rubberbanding
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   name="rubberbanding_desc"
+   width="580">
+    When you walk, your avatar may be pulled backward again and again.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="3"
+   name="rubberbanding_fix"
+   width="580">
+    Fix: XXXXXXX
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="White"
+   height="20"
+   layout="topleft"
+   top_pad="25"
+   name="tex_thrashing_title"
+   width="580">
+    Texture thrashing
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   name="tex_thrashing_desc"
+   width="580">
+    On objects near you, you may see their surfaces get blurry, then sharp, then blurry again.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="3"
+   name="tex_thrashing_fix"
+   width="580">
+    Fix: XXXXXXX
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="White"
+   height="20"
+   layout="topleft"
+   top_pad="25"
+   name="av_moving_title"
+   width="580">
+    Avatars are not moving smoothly
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   name="av_moving_desc"
+   width="580">
+    Lorem ipsum dolor sit amet.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="3"
+   name="av_moving_fix"
+   width="580">
+    Fix: XXXXXXX
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="White"
+   height="20"
+   layout="topleft"
+   top_pad="25"
+   name="av_moving_title"
+   width="580">
+    Will a better graphics card or new computer help?
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   name="av_moving_desc"
+   width="580">
+    Lorem ipsum dolor sit amet.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="3"
+   name="av_moving_fix"
+   width="580">
+    Fix: XXXXXXX
+  </text>
+</panel>
-- 
cgit v1.2.3


From 0914f5c48f777705bdc57188e7372707f7977e5a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 15 Jun 2021 19:25:08 +0300
Subject: SL-15297 WIP Implement performance floater #2

---
 indra/newview/CMakeLists.txt                       |   2 +
 indra/newview/llfloaterperformance.cpp             |  36 +-
 indra/newview/llfloaterperformance.h               |   5 +
 indra/newview/llfloaterpreference.cpp              | 409 +-----------------
 indra/newview/llfloaterpreference.h                |  31 +-
 .../llfloaterpreferencesgraphicsadvanced.cpp       | 466 +++++++++++++++++++++
 .../newview/llfloaterpreferencesgraphicsadvanced.h |  63 +++
 indra/newview/llviewerfloaterreg.cpp               |   1 +
 .../default/xui/en/panel_performance_nearby.xml    |   3 -
 9 files changed, 575 insertions(+), 441 deletions(-)
 create mode 100644 indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
 create mode 100644 indra/newview/llfloaterpreferencesgraphicsadvanced.h

(limited to 'indra/newview')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 1ec1e2cc24..888796015b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -290,6 +290,7 @@ set(viewer_SOURCE_FILES
     llfloaterperms.cpp
     llfloaterpostprocess.cpp
     llfloaterpreference.cpp
+    llfloaterpreferencesgraphicsadvanced.cpp
     llfloaterpreferenceviewadvanced.cpp
     llfloaterpreviewtrash.cpp
     llfloaterproperties.cpp
@@ -929,6 +930,7 @@ set(viewer_HEADER_FILES
     llfloaterperms.h
     llfloaterpostprocess.h
     llfloaterpreference.h
+    llfloaterpreferencesgraphicsadvanced.h
     llfloaterpreferenceviewadvanced.h
     llfloaterpreviewtrash.h
     llfloaterproperties.h
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 8024d1539c..a44c3a262d 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -27,11 +27,15 @@
 #include "llfloaterperformance.h"
 
 #include "llappearancemgr.h"
+#include "llavataractions.h"
 #include "llavatarrendernotifier.h"
 #include "llfeaturemanager.h"
 #include "llfloaterreg.h"
 #include "llnamelistctrl.h"
+#include "llfloaterpreference.h" // LLAvatarComplexityControls
+#include "llsliderctrl.h"
 #include "lltextbox.h"
+#include "lltrans.h"
 #include "llvoavatar.h"
 
 
@@ -43,6 +47,7 @@ LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
 
 LLFloaterPerformance::~LLFloaterPerformance()
 {
+    mComplexityChangedSignal.disconnect();
 }
 
 BOOL LLFloaterPerformance::postBuild()
@@ -79,7 +84,11 @@ BOOL LLFloaterPerformance::postBuild()
 
     mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
     mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
- 
+
+    updateComplexityText();
+    mComplexityChangedSignal = gSavedSettings.getControl("IndirectMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this));
+    mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxComplexity, this));
+
     return TRUE;
 }
 
@@ -151,6 +160,7 @@ void LLFloaterPerformance::populateHUDList()
 
         mHUDList->addElement(item);
     }
+    mHUDList->sortByColumnIndex(1, FALSE);
 
     mHUDsPanel->getChild<LLTextBox>("huds_value")->setValue(std::to_string(complexity_list.size()));
 }
@@ -185,10 +195,19 @@ void LLFloaterPerformance::populateNearbyList()
             row[2]["value"] = avatar->getFullname();
             row[2]["font"]["name"] = "SANSSERIF";
 
-            mNearbyList->addElement(item);
+            LLScrollListItem* av_item = mNearbyList->addElement(item);
+            if(av_item && LLAvatarActions::isFriend(avatar->getID()))
+            {
+                LLScrollListText* name_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(2));
+                if (name_text)
+                {
+                    name_text->setColor(LLUIColorTable::instance().getColor("ConversationFriendColor"));
+                }
+            }
         }
         char_iter++;
     }
+    mNearbyList->sortByColumnIndex(1, FALSE);
 
 }
 
@@ -213,4 +232,17 @@ void LLFloaterPerformance::onClickExceptions()
     LLFloaterReg::showInstance("avatar_render_settings");
 }
 
+void LLFloaterPerformance::updateMaxComplexity()
+{
+    LLAvatarComplexityControls::updateMax(
+        mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
+        mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText"));
+}
+
+void LLFloaterPerformance::updateComplexityText()
+{
+    LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
+        mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText", true));
+}
+
 // EOF
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index a70a328d3a..0cba07f21e 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -52,6 +52,9 @@ private:
     void onClickRecommended();
     void onClickExceptions();
 
+    void updateMaxComplexity();
+    void updateComplexityText();
+
     LLPanel* mMainPanel;
     LLPanel* mTroubleshootingPanel;
     LLPanel* mNearbyPanel;
@@ -60,6 +63,8 @@ private:
     LLPanel* mPreferencesPanel;
     LLNameListCtrl* mHUDList;
     LLNameListCtrl* mNearbyList;
+
+    boost::signals2::connection	mComplexityChangedSignal;
 };
 
 #endif // LL_LLFLOATERPERFORMANCE_H
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 6bf2136f60..1ab6621c4c 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -50,6 +50,7 @@
 #include "llfloaterreg.h"
 #include "llfloaterabout.h"
 #include "llfavoritesbar.h"
+#include "llfloaterpreferencesgraphicsadvanced.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfloaterimsession.h"
 #include "llkeyboard.h"
@@ -74,7 +75,6 @@
 #include "llviewereventrecorder.h"
 #include "llviewermessage.h"
 #include "llviewerwindow.h"
-#include "llviewershadermgr.h"
 #include "llviewerthrottle.h"
 #include "llvoavatarself.h"
 #include "llvotree.h"
@@ -98,11 +98,9 @@
 #include "lltextbox.h"
 #include "llui.h"
 #include "llviewerobjectlist.h"
-#include "llvoavatar.h"
 #include "llvovolume.h"
 #include "llwindow.h"
 #include "llworld.h"
-#include "pipeline.h"
 #include "lluictrlfactory.h"
 #include "llviewermedia.h"
 #include "llpluginclassmedia.h"
@@ -115,8 +113,6 @@
 #include "llpresetsmanager.h"
 #include "llviewercontrol.h"
 #include "llpresetsmanager.h"
-#include "llfeaturemanager.h"
-#include "llviewertexturelist.h"
 
 #include "llsearchableui.h"
 
@@ -751,33 +747,6 @@ void LLFloaterPreference::onRenderOptionEnable()
 	refreshEnabledGraphics();
 }
 
-void LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable()
-{
-	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
-	if (instance)
-	{
-		instance->refresh();
-	}
-
-	refreshEnabledGraphics();
-}
-
-void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable()
-{
-	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
-	if (instance)
-	{
-		instance->refresh();
-	}
-
-	refreshEnabledGraphics();
-}
-
-void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledGraphics()
-{
-	refreshEnabledState();
-}
-
 void LLFloaterPreference::onAvatarImpostorsEnable()
 {
 	refreshEnabledGraphics();
@@ -1216,124 +1185,6 @@ void LLFloaterPreference::refreshEnabledState()
 	getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
 }
 
-void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
-{
-	LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
-	LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
-
-	// Reflections
-    BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
-	ctrl_reflections->setEnabled(reflections);
-	reflections_text->setEnabled(reflections);
-
-    // Transparent Water
-    LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
-
-	// Bump & Shiny	
-	LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
-	bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
-	bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
-    
-	// Avatar Mode
-	// Enable Avatar Shaders
-	LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
-	// Avatar Render Mode
-	LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
-	
-	bool avatar_vp_enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP");
-	if (LLViewerShaderMgr::sInitialized)
-	{
-		S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel;
-		avatar_vp_enabled = (max_avatar_shader > 0) ? TRUE : FALSE;
-	}
-
-	ctrl_avatar_vp->setEnabled(avatar_vp_enabled);
-	
-    if (gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
-    {
-        ctrl_avatar_cloth->setEnabled(FALSE);
-    } 
-    else
-    {
-        ctrl_avatar_cloth->setEnabled(TRUE);
-    }
-
-    // Vertex Shaders, Global Shader Enable
-    // SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code
-    LLSliderCtrl* terrain_detail = getChild<LLSliderCtrl>("TerrainDetail");   // can be linked with control var
-    LLTextBox* terrain_text = getChild<LLTextBox>("TerrainDetailText");
-
-    terrain_detail->setEnabled(FALSE);
-    terrain_text->setEnabled(FALSE);
-
-    // WindLight
-    LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
-    LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
-    LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
-    ctrl_wind_light->setEnabled(TRUE);
-    sky->setEnabled(TRUE);
-    sky_text->setEnabled(TRUE);
-
-    //Deferred/SSAO/Shadows
-    LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
-    
-    BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
-                        ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
-                        ((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
-                        gGLManager.mHasFramebufferObject &&
-                        gSavedSettings.getBOOL("RenderAvatarVP") &&
-                        (ctrl_wind_light->get()) ? TRUE : FALSE;
-
-    ctrl_deferred->setEnabled(enabled);
-
-	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
-	LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
-	LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
-	LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText");
-
-	// note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
-	enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
-	
-	ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
-
-	ctrl_ssao->setEnabled(enabled);
-	ctrl_dof->setEnabled(enabled);
-
-	enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail");
-
-	ctrl_shadow->setEnabled(enabled);
-	shadow_text->setEnabled(enabled);
-
-	// Hardware settings
-	F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
-	S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
-	S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
-	getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value());
-	getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
-
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
-		!gGLManager.mHasVertexBufferObject)
-	{
-		getChildView("vbo")->setEnabled(FALSE);
-	}
-
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
-		!gGLManager.mHasVertexBufferObject)
-	{
-		getChildView("texture compression")->setEnabled(FALSE);
-	}
-
-	// if no windlight shaders, turn off nighttime brightness, gamma, and fog distance
-	LLUICtrl* gamma_ctrl = getChild<LLUICtrl>("gamma");
-	gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders());
-	getChildView("(brightness, lower is brighter)")->setEnabled(!gPipeline.canUseWindLightShaders());
-	getChildView("fog")->setEnabled(!gPipeline.canUseWindLightShaders());
-	getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"));
-
-	// now turn off any features that are unavailable
-	disableUnavailableSettings();
-}
-
 // static
 void LLAvatarComplexityControls::setIndirectControls()
 {
@@ -1376,118 +1227,6 @@ void LLAvatarComplexityControls::setIndirectMaxArc()
 	gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc);
 }
 
-void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
-{	
-	LLComboBox* ctrl_reflections   = getChild<LLComboBox>("Reflections");
-	LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
-	LLCheckBoxCtrl* ctrl_avatar_vp     = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
-	LLCheckBoxCtrl* ctrl_avatar_cloth  = getChild<LLCheckBoxCtrl>("AvatarCloth");
-	LLCheckBoxCtrl* ctrl_wind_light    = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
-	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
-	LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
-	LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText");
-	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
-	LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
-	LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
-	LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
-
-	// disabled windlight
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
-	{
-		ctrl_wind_light->setEnabled(FALSE);
-		ctrl_wind_light->setValue(FALSE);
-
-		sky->setEnabled(FALSE);
-		sky_text->setEnabled(FALSE);
-
-		//deferred needs windlight, disable deferred
-		ctrl_shadows->setEnabled(FALSE);
-		ctrl_shadows->setValue(0);
-		shadows_text->setEnabled(FALSE);
-		
-		ctrl_ssao->setEnabled(FALSE);
-		ctrl_ssao->setValue(FALSE);
-
-		ctrl_dof->setEnabled(FALSE);
-		ctrl_dof->setValue(FALSE);
-
-		ctrl_deferred->setEnabled(FALSE);
-		ctrl_deferred->setValue(FALSE);
-	}
-
-	// disabled deferred
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
-		!gGLManager.mHasFramebufferObject)
-	{
-		ctrl_shadows->setEnabled(FALSE);
-		ctrl_shadows->setValue(0);
-		shadows_text->setEnabled(FALSE);
-		
-		ctrl_ssao->setEnabled(FALSE);
-		ctrl_ssao->setValue(FALSE);
-
-		ctrl_dof->setEnabled(FALSE);
-		ctrl_dof->setValue(FALSE);
-
-		ctrl_deferred->setEnabled(FALSE);
-		ctrl_deferred->setValue(FALSE);
-	}
-	
-	// disabled deferred SSAO
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO"))
-	{
-		ctrl_ssao->setEnabled(FALSE);
-		ctrl_ssao->setValue(FALSE);
-	}
-	
-	// disabled deferred shadows
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
-	{
-		ctrl_shadows->setEnabled(FALSE);
-		ctrl_shadows->setValue(0);
-		shadows_text->setEnabled(FALSE);
-	}
-
-	// disabled reflections
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
-	{
-		ctrl_reflections->setEnabled(FALSE);
-		ctrl_reflections->setValue(FALSE);
-		reflections_text->setEnabled(FALSE);
-	}
-	
-	// disabled av
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"))
-	{
-		ctrl_avatar_vp->setEnabled(FALSE);
-		ctrl_avatar_vp->setValue(FALSE);
-		
-		ctrl_avatar_cloth->setEnabled(FALSE);
-		ctrl_avatar_cloth->setValue(FALSE);
-
-		//deferred needs AvatarVP, disable deferred
-		ctrl_shadows->setEnabled(FALSE);
-		ctrl_shadows->setValue(0);
-		shadows_text->setEnabled(FALSE);
-		
-		ctrl_ssao->setEnabled(FALSE);
-		ctrl_ssao->setValue(FALSE);
-
-		ctrl_dof->setEnabled(FALSE);
-		ctrl_dof->setValue(FALSE);
-
-		ctrl_deferred->setEnabled(FALSE);
-		ctrl_deferred->setValue(FALSE);
-	}
-
-	// disabled cloth
-	if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
-	{
-		ctrl_avatar_cloth->setEnabled(FALSE);
-		ctrl_avatar_cloth->setValue(FALSE);
-	}
-}
-
 void LLFloaterPreference::refresh()
 {
 	LLPanel::refresh();
@@ -1503,32 +1242,6 @@ void LLFloaterPreference::refresh()
     updateClickActionViews();
 }
 
-void LLFloaterPreferenceGraphicsAdvanced::refresh()
-{
-	getChild<LLUICtrl>("fsaa")->setValue((LLSD::Integer)  gSavedSettings.getU32("RenderFSAASamples"));
-
-	// sliders and their text boxes
-	//	mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow");
-	// slider text boxes
-	updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail",		true), getChild<LLTextBox>("ObjectMeshDetailText",		true));
-	updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail",	true), getChild<LLTextBox>("FlexibleMeshDetailText",	true));
-	updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail",		true), getChild<LLTextBox>("TreeMeshDetailText",		true));
-	updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail",		true), getChild<LLTextBox>("AvatarMeshDetailText",		true));
-	updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail",	true), getChild<LLTextBox>("AvatarPhysicsDetailText",		true));
-	updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail",	true), getChild<LLTextBox>("TerrainMeshDetailText",		true));
-	updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess",	true), getChild<LLTextBox>("PostProcessText",			true));
-	updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail",		true), getChild<LLTextBox>("SkyMeshDetailText",			true));
-	updateSliderText(getChild<LLSliderCtrl>("TerrainDetail",		true), getChild<LLTextBox>("TerrainDetailText",			true));	
-    LLAvatarComplexityControls::setIndirectControls();
-	setMaxNonImpostorsText(
-        gSavedSettings.getU32("RenderAvatarMaxNonImpostors"),
-        getChild<LLTextBox>("IndirectMaxNonImpostorsText", true));
-    LLAvatarComplexityControls::setText(
-        gSavedSettings.getU32("RenderAvatarMaxComplexity"),
-        getChild<LLTextBox>("IndirectMaxComplexityText", true));
-	refreshEnabledState();
-}
-
 void LLFloaterPreference::onCommitWindowedMode()
 {
 	refresh();
@@ -1742,63 +1455,6 @@ void LLFloaterPreference::refreshUI()
 	refresh();
 }
 
-void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
-{
-	if (text_box == NULL || ctrl== NULL)
-		return;
-
-	// get range and points when text should change
-	F32 value = (F32)ctrl->getValue().asReal();
-	F32 min = ctrl->getMinValue();
-	F32 max = ctrl->getMaxValue();
-	F32 range = max - min;
-	llassert(range > 0);
-	F32 midPoint = min + range / 3.0f;
-	F32 highPoint = min + (2.0f * range / 3.0f);
-
-	// choose the right text
-	if (value < midPoint)
-	{
-		text_box->setText(LLTrans::getString("GraphicsQualityLow"));
-	} 
-	else if (value < highPoint)
-	{
-		text_box->setText(LLTrans::getString("GraphicsQualityMid"));
-	}
-	else
-	{
-		text_box->setText(LLTrans::getString("GraphicsQualityHigh"));
-	}
-}
-
-void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
-{
-	// Called when the IndirectMaxNonImpostors control changes
-	// Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors
-	LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors",true);
-	U32 value = ctrl->getValue().asInteger();
-
-	if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value)
-	{
-		value=0;
-	}
-	gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value);
-	LLVOAvatar::updateImpostorRendering(value); // make it effective immediately
-	setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
-}
-
-void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
-{
-	if (0 == value)
-	{
-		text_box->setText(LLTrans::getString("no_limit"));
-	}
-	else
-	{
-		text_box->setText(llformat("%d", value));
-	}
-}
-
 void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* value_label)
 {
 	// Called when the IndirectMaxComplexity control changes
@@ -1891,22 +1547,6 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map
     return true;
 }
 
-void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity()
-{
-	// Called when the IndirectMaxComplexity control changes
-    LLAvatarComplexityControls::updateMax(
-        getChild<LLSliderCtrl>("IndirectMaxComplexity"),
-        getChild<LLTextBox>("IndirectMaxComplexityText"));
-
-    LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
-    if (floater_preferences)
-    {
-        LLAvatarComplexityControls::updateMax(
-            floater_preferences->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
-            floater_preferences->getChild<LLTextBox>("IndirectMaxComplexityText"));
-    }
-}
-
 void LLFloaterPreference::onChangeMaturity()
 {
 	U8 sim_access = gSavedSettings.getU32("PreferredMaturity");
@@ -3310,18 +2950,6 @@ void LLPanelPreferenceControls::onCancelKeyBind()
     pControlsTable->deselectAllItems();
 }
 
-LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key)
-	: LLFloater(key)
-{
-    mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate",            boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable, this));
-	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
-	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",   boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
-}
-
-LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
-{
-}
-
 LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)
 	: LLFloater(key),
 	  mSocksSettingsDirty(false)
@@ -3331,41 +2959,6 @@ LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)
 	mCommitCallbackRegistrar.add("Proxy.Change",            boost::bind(&LLFloaterPreferenceProxy::onChangeSocksSettings, this));
 }
 
-BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
-{
-    // Don't do this on Mac as their braindead GL versioning
-    // sets this when 8x and 16x are indeed available
-    //
-#if !LL_DARWIN
-    if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
-    { //remove FSAA settings above "4x"
-        LLComboBox* combo = getChild<LLComboBox>("fsaa");
-        combo->remove("8x");
-        combo->remove("16x");
-    }
-	
-	LLCheckBoxCtrl *use_HiDPI = getChild<LLCheckBoxCtrl>("use HiDPI");
-	use_HiDPI->setVisible(FALSE);
-#endif
-
-    return TRUE;
-}
-
-void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key)
-{
-    refresh();
-}
-
-void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting)
-{
-	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
-	if (instance)
-	{
-		instance->cancel();
-	}
-	updateMaxComplexity();
-}
-
 LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy()
 {
 }
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 1268935712..f86104ed99 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -109,9 +109,10 @@ public:
 	// updates click/double-click action controls depending on values from settings.xml
 	void updateClickActionViews();
 
+    void		onBtnOK(const LLSD& userdata);
+    void		onBtnCancel(const LLSD& userdata);
+
 protected:	
-	void		onBtnOK(const LLSD& userdata);
-	void		onBtnCancel(const LLSD& userdata);
 
 	void		onClickClearCache();			// Clear viewer texture cache, vfs, and VO cache on next startup
 	void		onClickBrowserClearCache();		// Clear web history and caches as well as viewer caches above
@@ -347,32 +348,6 @@ private:
 	S32 mEditingMode;
 };
 
-class LLFloaterPreferenceGraphicsAdvanced : public LLFloater
-{
-  public: 
-	LLFloaterPreferenceGraphicsAdvanced(const LLSD& key);
-	~LLFloaterPreferenceGraphicsAdvanced();
-	/*virtual*/ BOOL postBuild();
-	void onOpen(const LLSD& key);
-	void onClickCloseBtn(bool app_quitting);
-	void disableUnavailableSettings();
-	void refreshEnabledGraphics();
-	void refreshEnabledState();
-	void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
-	void updateMaxNonImpostors();
-	void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
-	void updateMaxComplexity();
-	void setMaxComplexityText(U32 value, LLTextBox* text_box);
-	static void setIndirectControls();
-	static void setIndirectMaxNonImpostors();
-	static void setIndirectMaxArc();
-	void refresh();
-	// callback for when client modifies a render option
-	void onRenderOptionEnable();
-    void onAdvancedAtmosphericsEnable();
-	LOG_CLASS(LLFloaterPreferenceGraphicsAdvanced);
-};
-
 class LLAvatarComplexityControls
 {
   public: 
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
new file mode 100644
index 0000000000..404cdf5280
--- /dev/null
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -0,0 +1,466 @@
+/** 
+ * @file llfloaterpreferencesgraphicsadvanced.cpp
+ * @brief floater for adjusting camera position
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterpreferencesgraphicsadvanced.h"
+
+#include "llcheckboxctrl.h"
+#include "llcombobox.h"
+#include "llfeaturemanager.h"
+#include "llfloaterpreference.h"
+#include "llfloaterreg.h"
+#include "llsliderctrl.h"
+#include "lltextbox.h"
+#include "lltrans.h"
+#include "llviewershadermgr.h"
+#include "llviewertexturelist.h"
+#include "llvoavatar.h"
+#include "pipeline.h"
+
+
+LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key)
+    : LLFloater(key)
+{
+    mCommitCallbackRegistrar.add("Pref.RenderOptionUpdate",            boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable, this));
+    mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
+    mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",   boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
+
+    mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
+    mCommitCallbackRegistrar.add("Pref.OK",     boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
+}
+
+LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
+{
+}
+
+BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
+{
+    // Don't do this on Mac as their braindead GL versioning
+    // sets this when 8x and 16x are indeed available
+    //
+#if !LL_DARWIN
+    if (gGLManager.mIsIntel || gGLManager.mGLVersion < 3.f)
+    { //remove FSAA settings above "4x"
+        LLComboBox* combo = getChild<LLComboBox>("fsaa");
+        combo->remove("8x");
+        combo->remove("16x");
+    }
+
+    LLCheckBoxCtrl *use_HiDPI = getChild<LLCheckBoxCtrl>("use HiDPI");
+    use_HiDPI->setVisible(FALSE);
+#endif
+
+    return TRUE;
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key)
+{
+    refresh();
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting)
+{
+    LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {
+        instance->cancel();
+    }
+    updateMaxComplexity();
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable()
+{
+    LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {
+        instance->refresh();
+    }
+
+    refreshEnabledGraphics();
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable()
+{
+    LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {
+        instance->refresh();
+    }
+
+    refreshEnabledGraphics();
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::refresh()
+{
+    getChild<LLUICtrl>("fsaa")->setValue((LLSD::Integer)  gSavedSettings.getU32("RenderFSAASamples"));
+
+    // sliders and their text boxes
+    //	mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow");
+    // slider text boxes
+    updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail",		true), getChild<LLTextBox>("ObjectMeshDetailText",		true));
+    updateSliderText(getChild<LLSliderCtrl>("FlexibleMeshDetail",	true), getChild<LLTextBox>("FlexibleMeshDetailText",	true));
+    updateSliderText(getChild<LLSliderCtrl>("TreeMeshDetail",		true), getChild<LLTextBox>("TreeMeshDetailText",		true));
+    updateSliderText(getChild<LLSliderCtrl>("AvatarMeshDetail",		true), getChild<LLTextBox>("AvatarMeshDetailText",		true));
+    updateSliderText(getChild<LLSliderCtrl>("AvatarPhysicsDetail",	true), getChild<LLTextBox>("AvatarPhysicsDetailText",		true));
+    updateSliderText(getChild<LLSliderCtrl>("TerrainMeshDetail",	true), getChild<LLTextBox>("TerrainMeshDetailText",		true));
+    updateSliderText(getChild<LLSliderCtrl>("RenderPostProcess",	true), getChild<LLTextBox>("PostProcessText",			true));
+    updateSliderText(getChild<LLSliderCtrl>("SkyMeshDetail",		true), getChild<LLTextBox>("SkyMeshDetailText",			true));
+    updateSliderText(getChild<LLSliderCtrl>("TerrainDetail",		true), getChild<LLTextBox>("TerrainDetailText",			true));	
+    LLAvatarComplexityControls::setIndirectControls();
+    setMaxNonImpostorsText(
+        gSavedSettings.getU32("RenderAvatarMaxNonImpostors"),
+        getChild<LLTextBox>("IndirectMaxNonImpostorsText", true));
+    LLAvatarComplexityControls::setText(
+        gSavedSettings.getU32("RenderAvatarMaxComplexity"),
+        getChild<LLTextBox>("IndirectMaxComplexityText", true));
+    refreshEnabledState();
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledGraphics()
+{
+    refreshEnabledState();
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity()
+{
+    // Called when the IndirectMaxComplexity control changes
+    LLAvatarComplexityControls::updateMax(
+        getChild<LLSliderCtrl>("IndirectMaxComplexity"),
+        getChild<LLTextBox>("IndirectMaxComplexityText"));
+
+    LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+    if (floater_preferences)
+    {
+        LLAvatarComplexityControls::updateMax(
+            floater_preferences->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
+            floater_preferences->getChild<LLTextBox>("IndirectMaxComplexityText"));
+    }
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
+{
+    if (text_box == NULL || ctrl== NULL)
+        return;
+
+    // get range and points when text should change
+    F32 value = (F32)ctrl->getValue().asReal();
+    F32 min = ctrl->getMinValue();
+    F32 max = ctrl->getMaxValue();
+    F32 range = max - min;
+    llassert(range > 0);
+    F32 midPoint = min + range / 3.0f;
+    F32 highPoint = min + (2.0f * range / 3.0f);
+
+    // choose the right text
+    if (value < midPoint)
+    {
+        text_box->setText(LLTrans::getString("GraphicsQualityLow"));
+    } 
+    else if (value < highPoint)
+    {
+        text_box->setText(LLTrans::getString("GraphicsQualityMid"));
+    }
+    else
+    {
+        text_box->setText(LLTrans::getString("GraphicsQualityHigh"));
+    }
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
+{
+    // Called when the IndirectMaxNonImpostors control changes
+    // Responsible for fixing the slider label (IndirectMaxNonImpostorsText) and setting RenderAvatarMaxNonImpostors
+    LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors",true);
+    U32 value = ctrl->getValue().asInteger();
+
+    if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value)
+    {
+        value=0;
+    }
+    gSavedSettings.setU32("RenderAvatarMaxNonImpostors", value);
+    LLVOAvatar::updateImpostorRendering(value); // make it effective immediately
+    setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
+{
+    if (0 == value)
+    {
+        text_box->setText(LLTrans::getString("no_limit"));
+    }
+    else
+    {
+        text_box->setText(llformat("%d", value));
+    }
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings()
+{	
+    LLComboBox* ctrl_reflections   = getChild<LLComboBox>("Reflections");
+    LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
+    LLCheckBoxCtrl* ctrl_avatar_vp     = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
+    LLCheckBoxCtrl* ctrl_avatar_cloth  = getChild<LLCheckBoxCtrl>("AvatarCloth");
+    LLCheckBoxCtrl* ctrl_wind_light    = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
+    LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+    LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
+    LLTextBox* shadows_text = getChild<LLTextBox>("RenderShadowDetailText");
+    LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
+    LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
+    LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
+    LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
+
+    // disabled windlight
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
+    {
+        ctrl_wind_light->setEnabled(FALSE);
+        ctrl_wind_light->setValue(FALSE);
+
+        sky->setEnabled(FALSE);
+        sky_text->setEnabled(FALSE);
+
+        //deferred needs windlight, disable deferred
+        ctrl_shadows->setEnabled(FALSE);
+        ctrl_shadows->setValue(0);
+        shadows_text->setEnabled(FALSE);
+
+        ctrl_ssao->setEnabled(FALSE);
+        ctrl_ssao->setValue(FALSE);
+
+        ctrl_dof->setEnabled(FALSE);
+        ctrl_dof->setValue(FALSE);
+
+        ctrl_deferred->setEnabled(FALSE);
+        ctrl_deferred->setValue(FALSE);
+    }
+
+    // disabled deferred
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") ||
+        !gGLManager.mHasFramebufferObject)
+    {
+        ctrl_shadows->setEnabled(FALSE);
+        ctrl_shadows->setValue(0);
+        shadows_text->setEnabled(FALSE);
+
+        ctrl_ssao->setEnabled(FALSE);
+        ctrl_ssao->setValue(FALSE);
+
+        ctrl_dof->setEnabled(FALSE);
+        ctrl_dof->setValue(FALSE);
+
+        ctrl_deferred->setEnabled(FALSE);
+        ctrl_deferred->setValue(FALSE);
+    }
+
+    // disabled deferred SSAO
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO"))
+    {
+        ctrl_ssao->setEnabled(FALSE);
+        ctrl_ssao->setValue(FALSE);
+    }
+
+    // disabled deferred shadows
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
+    {
+        ctrl_shadows->setEnabled(FALSE);
+        ctrl_shadows->setValue(0);
+        shadows_text->setEnabled(FALSE);
+    }
+
+    // disabled reflections
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
+    {
+        ctrl_reflections->setEnabled(FALSE);
+        ctrl_reflections->setValue(FALSE);
+        reflections_text->setEnabled(FALSE);
+    }
+
+    // disabled av
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP"))
+    {
+        ctrl_avatar_vp->setEnabled(FALSE);
+        ctrl_avatar_vp->setValue(FALSE);
+
+        ctrl_avatar_cloth->setEnabled(FALSE);
+        ctrl_avatar_cloth->setValue(FALSE);
+
+        //deferred needs AvatarVP, disable deferred
+        ctrl_shadows->setEnabled(FALSE);
+        ctrl_shadows->setValue(0);
+        shadows_text->setEnabled(FALSE);
+
+        ctrl_ssao->setEnabled(FALSE);
+        ctrl_ssao->setValue(FALSE);
+
+        ctrl_dof->setEnabled(FALSE);
+        ctrl_dof->setValue(FALSE);
+
+        ctrl_deferred->setEnabled(FALSE);
+        ctrl_deferred->setValue(FALSE);
+    }
+
+    // disabled cloth
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
+    {
+        ctrl_avatar_cloth->setEnabled(FALSE);
+        ctrl_avatar_cloth->setValue(FALSE);
+    }
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
+{
+    LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
+    LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
+
+    // Reflections
+    BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
+    ctrl_reflections->setEnabled(reflections);
+    reflections_text->setEnabled(reflections);
+
+    // Transparent Water
+    LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
+
+    // Bump & Shiny	
+    LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
+    bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
+    bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
+
+    // Avatar Mode
+    // Enable Avatar Shaders
+    LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
+    // Avatar Render Mode
+    LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
+
+    bool avatar_vp_enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarVP");
+    if (LLViewerShaderMgr::sInitialized)
+    {
+        S32 max_avatar_shader = LLViewerShaderMgr::instance()->mMaxAvatarShaderLevel;
+        avatar_vp_enabled = (max_avatar_shader > 0) ? TRUE : FALSE;
+    }
+
+    ctrl_avatar_vp->setEnabled(avatar_vp_enabled);
+
+    if (gSavedSettings.getBOOL("RenderAvatarVP") == FALSE)
+    {
+        ctrl_avatar_cloth->setEnabled(FALSE);
+    } 
+    else
+    {
+        ctrl_avatar_cloth->setEnabled(TRUE);
+    }
+
+    // Vertex Shaders, Global Shader Enable
+    // SL-12594 Basic shaders are always enabled. DJH TODO clean up now-orphaned state handling code
+    LLSliderCtrl* terrain_detail = getChild<LLSliderCtrl>("TerrainDetail");   // can be linked with control var
+    LLTextBox* terrain_text = getChild<LLTextBox>("TerrainDetailText");
+
+    terrain_detail->setEnabled(FALSE);
+    terrain_text->setEnabled(FALSE);
+
+    // WindLight
+    LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
+    LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
+    LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
+    ctrl_wind_light->setEnabled(TRUE);
+    sky->setEnabled(TRUE);
+    sky_text->setEnabled(TRUE);
+
+    //Deferred/SSAO/Shadows
+    LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+
+    BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+        ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
+        ((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
+        gGLManager.mHasFramebufferObject &&
+        gSavedSettings.getBOOL("RenderAvatarVP") &&
+        (ctrl_wind_light->get()) ? TRUE : FALSE;
+
+    ctrl_deferred->setEnabled(enabled);
+
+    LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
+    LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
+    LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
+    LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText");
+
+    // note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
+    enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
+
+    ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
+
+    ctrl_ssao->setEnabled(enabled);
+    ctrl_dof->setEnabled(enabled);
+
+    enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail");
+
+    ctrl_shadow->setEnabled(enabled);
+    shadow_text->setEnabled(enabled);
+
+    // Hardware settings
+    F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
+    S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
+    S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
+    getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value());
+    getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
+
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
+        !gGLManager.mHasVertexBufferObject)
+    {
+        getChildView("vbo")->setEnabled(FALSE);
+    }
+
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
+        !gGLManager.mHasVertexBufferObject)
+    {
+        getChildView("texture compression")->setEnabled(FALSE);
+    }
+
+    // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance
+    LLUICtrl* gamma_ctrl = getChild<LLUICtrl>("gamma");
+    gamma_ctrl->setEnabled(!gPipeline.canUseWindLightShaders());
+    getChildView("(brightness, lower is brighter)")->setEnabled(!gPipeline.canUseWindLightShaders());
+    getChildView("fog")->setEnabled(!gPipeline.canUseWindLightShaders());
+    getChildView("antialiasing restart")->setVisible(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"));
+
+    // now turn off any features that are unavailable
+    disableUnavailableSettings();
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::onBtnOK(const LLSD& userdata)
+{
+    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {
+        instance->onBtnOK(userdata);
+    }
+}
+
+void LLFloaterPreferenceGraphicsAdvanced::onBtnCancel(const LLSD& userdata)
+{
+    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {
+        instance->onBtnCancel(userdata);
+    }
+}
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
new file mode 100644
index 0000000000..3e9046eba9
--- /dev/null
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
@@ -0,0 +1,63 @@
+/** 
+ * @file llfloaterpreferencesgraphicsadvanced.h
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LLFLOATERPREFERENCEGRAPHICSADVANCED_H
+#define LLFLOATERPREFERENCEGRAPHICSADVANCED_H
+
+#include "llcontrol.h"
+#include "llfloater.h"
+
+class LLSliderCtrl;
+class LLTextBox;
+
+class LLFloaterPreferenceGraphicsAdvanced : public LLFloater
+{
+public: 
+    LLFloaterPreferenceGraphicsAdvanced(const LLSD& key);
+    ~LLFloaterPreferenceGraphicsAdvanced();
+    /*virtual*/ BOOL postBuild();
+    void onOpen(const LLSD& key);
+    void onClickCloseBtn(bool app_quitting);
+    void disableUnavailableSettings();
+    void refreshEnabledGraphics();
+    void refreshEnabledState();
+    void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
+    void updateMaxNonImpostors();
+    void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
+    void updateMaxComplexity();
+    void setMaxComplexityText(U32 value, LLTextBox* text_box);
+    void refresh();
+    // callback for when client modifies a render option
+    void onRenderOptionEnable();
+    void onAdvancedAtmosphericsEnable();
+    LOG_CLASS(LLFloaterPreferenceGraphicsAdvanced);
+
+protected:	
+    void		onBtnOK(const LLSD& userdata);
+    void		onBtnCancel(const LLSD& userdata);
+};
+
+#endif //LLFLOATERPREFERENCEGRAPHICSADVANCED_H
+
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index eabdb67188..731a7e8ace 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -106,6 +106,7 @@
 #include "llfloaterperms.h"
 #include "llfloaterpostprocess.h"
 #include "llfloaterpreference.h"
+#include "llfloaterpreferencesgraphicsadvanced.h"
 #include "llfloaterpreferenceviewadvanced.h"
 #include "llfloaterpreviewtrash.h"
 #include "llfloaterproperties.h"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
index ade5f99451..d71b5334cd 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
@@ -83,9 +83,6 @@
     show_text="false"
     top_pad="10"
     width="300">
-    <slider.commit_callback
-      function="Pref.UpdateIndirectMaxComplexity"
-      parameter="IndirectMaxComlexityText" />
   </slider>
   <text
     type="string"
-- 
cgit v1.2.3


From bc609f964b13141301aca9d29b9ceb5f9a541bf9 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 17 Jun 2021 20:37:06 +0300
Subject: SL-15297 WIP Implement performance floater - updated UI

---
 indra/newview/llavatarrendernotifier.cpp           |  16 +-
 indra/newview/llavatarrendernotifier.h             |  26 +
 indra/newview/llfloaterperformance.cpp             | 135 +++-
 indra/newview/llfloaterperformance.h               |  11 +-
 indra/newview/llvoavatar.cpp                       |  33 +-
 indra/newview/llvoavatar.h                         |   3 +-
 .../skins/default/textures/icons/green_dot.png     | Bin 18614 -> 0 bytes
 indra/newview/skins/default/textures/textures.xml  |   2 -
 .../skins/default/xui/en/floater_performance.xml   | 730 ++++++++++-----------
 .../xui/en/panel_performance_complexity.xml        |  92 +++
 .../default/xui/en/panel_performance_huds.xml      |  20 +-
 .../default/xui/en/panel_performance_nearby.xml    |  25 +-
 .../xui/en/panel_performance_preferences.xml       |   4 +-
 .../default/xui/en/panel_performance_scripts.xml   |  82 ---
 .../xui/en/panel_performance_troubleshooting.xml   |   4 +-
 15 files changed, 661 insertions(+), 522 deletions(-)
 delete mode 100644 indra/newview/skins/default/textures/icons/green_dot.png
 create mode 100644 indra/newview/skins/default/xui/en/panel_performance_complexity.xml
 delete mode 100644 indra/newview/skins/default/xui/en/panel_performance_scripts.xml

(limited to 'indra/newview')

diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp
index 4fd57c7341..8b09f7903d 100644
--- a/indra/newview/llavatarrendernotifier.cpp
+++ b/indra/newview/llavatarrendernotifier.cpp
@@ -235,6 +235,12 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity)
     // save the value for use in following messages
     mLatestAgentComplexity = agentComplexity;
 
+    static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
+    if (!show_my_complexity_changes)
+    {
+        return;
+    }
+
     if (!isAgentAvatarValid() || !gAgentWearables.areWearablesLoaded())
     {
         // data not ready, nothing to show.
@@ -282,7 +288,8 @@ static const char* e_hud_messages[] =
 };
 
 LLHUDRenderNotifier::LLHUDRenderNotifier() :
-mReportedHUDWarning(WARN_NONE)
+mReportedHUDWarning(WARN_NONE),
+mHUDsCount(0)
 {
 }
 
@@ -299,7 +306,14 @@ void LLHUDRenderNotifier::updateNotificationHUD(hud_complexity_list_t complexity
     }
 
     mHUDComplexityList = complexity;
+    mHUDsCount = mHUDComplexityList.size();
 
+    static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
+    if (!show_my_complexity_changes)
+    {
+        return;
+    }
+        
     // TODO:
     // Find a way to show message with list of issues, but without making it too large
     // and intrusive.
diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h
index 3fd7a32d84..37130bfcf6 100644
--- a/indra/newview/llavatarrendernotifier.h
+++ b/indra/newview/llavatarrendernotifier.h
@@ -63,6 +63,25 @@ struct LLHUDComplexity
 
 typedef std::list<LLHUDComplexity> hud_complexity_list_t;
 
+struct LLObjectComplexity
+{
+    LLObjectComplexity()
+    {
+        reset();
+    }
+    void reset()
+    {
+        objectId = LLUUID::null;
+        objectName = "";
+        objectCost = 0;
+    }
+    LLUUID objectId;
+    std::string objectName;
+    U32 objectCost;
+};
+
+typedef std::list<LLObjectComplexity> object_complexity_list_t;
+
 // Class to notify user about drastic changes in agent's render weights or if other agents
 // reported that user's agent is too 'heavy' for their settings
 class LLAvatarRenderNotifier : public LLSingleton<LLAvatarRenderNotifier>
@@ -77,6 +96,9 @@ public:
     void updateNotificationState();
 	void updateNotificationAgent(U32 agentComplexity);
 
+    void setObjectComplexityList(object_complexity_list_t object_list) { mObjectComplexityList = object_list; }
+    object_complexity_list_t getObjectComplexityList() { return mObjectComplexityList; }
+
 private:
 
 	LLNotificationPtr mNotificationPtr;
@@ -109,6 +131,8 @@ private:
     // Used to detect changes in voavatar's rezzed status.
     // If value decreases - there were changes in outfit.
     S32 mLastOutfitRezStatus;
+
+    object_complexity_list_t mObjectComplexityList;
 };
 
 // Class to notify user about heavy set of HUD
@@ -122,6 +146,7 @@ public:
     bool isNotificationVisible();
 
     hud_complexity_list_t getHUDComplexityList() { return mHUDComplexityList; }
+    S32 getHUDsCount() { return mHUDsCount; }
 
 private:
     enum EWarnLevel
@@ -144,6 +169,7 @@ private:
     LLHUDComplexity mLatestHUDComplexity;
     LLFrameTimer mHUDPopUpDelayTimer;
     hud_complexity_list_t mHUDComplexityList;
+    S32 mHUDsCount;
 };
 
 #endif /* ! defined(LL_llavatarrendernotifier_H) */
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index a44c3a262d..c96d3dac5e 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -37,17 +37,22 @@
 #include "lltextbox.h"
 #include "lltrans.h"
 #include "llvoavatar.h"
+#include "llvoavatarself.h" 
+
+const F32 REFRESH_INTERVAL = 1.0f;
+const S32 COMPLEXITY_THRESHOLD_1 = 100000;
 
 
 LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
-    : LLFloater(key)
+:   LLFloater(key),
+    mUpdateTimer(new LLTimer())
 {
-
 }
 
 LLFloaterPerformance::~LLFloaterPerformance()
 {
     mComplexityChangedSignal.disconnect();
+    delete mUpdateTimer;
 }
 
 BOOL LLFloaterPerformance::postBuild()
@@ -55,32 +60,34 @@ BOOL LLFloaterPerformance::postBuild()
     mMainPanel = getChild<LLPanel>("panel_performance_main");
     mTroubleshootingPanel = getChild<LLPanel>("panel_performance_troubleshooting");
     mNearbyPanel = getChild<LLPanel>("panel_performance_nearby");
-    mScriptsPanel = getChild<LLPanel>("panel_performance_scripts");
-    mPreferencesPanel = getChild<LLPanel>("panel_performance_preferences");
+    mComplexityPanel = getChild<LLPanel>("panel_performance_complexity");
+    mSettingsPanel = getChild<LLPanel>("panel_performance_preferences");
     mHUDsPanel = getChild<LLPanel>("panel_performance_huds");
 
     getChild<LLPanel>("troubleshooting_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mTroubleshootingPanel));
     getChild<LLPanel>("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel));
-    getChild<LLPanel>("scripts_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mScriptsPanel));
-    getChild<LLPanel>("preferences_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mPreferencesPanel));
+    getChild<LLPanel>("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel));
+    getChild<LLPanel>("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel));
     getChild<LLPanel>("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel));
 
     initBackBtn(mTroubleshootingPanel);
     initBackBtn(mNearbyPanel);
-    initBackBtn(mScriptsPanel);
-    initBackBtn(mPreferencesPanel);
+    initBackBtn(mComplexityPanel);
+    initBackBtn(mSettingsPanel);
     initBackBtn(mHUDsPanel);
 
-
-    mHUDsPanel->getChild<LLButton>("refresh_list_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::populateHUDList, this));
- 
     mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");
     mHUDList->setNameListType(LLNameListCtrl::SPECIAL);
     mHUDList->setHoverIconName("StopReload_Off");
     mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
 
-    mPreferencesPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
-    mPreferencesPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickRecommended, this));
+    mObjectList = mComplexityPanel->getChild<LLNameListCtrl>("obj_list");
+    mObjectList->setNameListType(LLNameListCtrl::SPECIAL);
+    mObjectList->setHoverIconName("StopReload_Off");
+    mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
+
+    mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
+    mSettingsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickRecommended, this));
 
     mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
     mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
@@ -89,6 +96,8 @@ BOOL LLFloaterPerformance::postBuild()
     mComplexityChangedSignal = gSavedSettings.getControl("IndirectMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this));
     mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxComplexity, this));
 
+    LLAvatarComplexityControls::setIndirectMaxArc();
+
     return TRUE;
 }
 
@@ -107,13 +116,43 @@ void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
     }
 }
 
+void LLFloaterPerformance::draw()
+{
+    if (mUpdateTimer->hasExpired())
+    {
+        getChild<LLTextBox>("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS)));
+        if (mMainPanel->getVisible())
+        {
+            mMainPanel->getChild<LLTextBox>("huds_value")->setValue(LLHUDRenderNotifier::getInstance()->getHUDsCount());
+            mMainPanel->getChild<LLTextBox>("complexity_value")->setValue((S32)gAgentAvatarp->getVisualComplexity());
+            updateNearbyComplexityDesc();
+        }
+        else if (mHUDsPanel->getVisible())
+        {
+            populateHUDList();
+        }
+        else if (mNearbyPanel->getVisible())
+        {
+            populateNearbyList();
+            updateNearbyComplexityDesc();
+        }
+        else if (mComplexityPanel->getVisible())
+        {
+            populateObjectList();
+        }
+
+        mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL);
+    }
+    LLFloater::draw();
+}
+
 void LLFloaterPerformance::showMainPanel()
 {
     mTroubleshootingPanel->setVisible(FALSE);
     mNearbyPanel->setVisible(FALSE);
-    mScriptsPanel->setVisible(FALSE);
+    mComplexityPanel->setVisible(FALSE);
     mHUDsPanel->setVisible(FALSE);
-    mPreferencesPanel->setVisible(FALSE);
+    mSettingsPanel->setVisible(FALSE);
     mMainPanel->setVisible(TRUE);
 }
 
@@ -165,16 +204,55 @@ void LLFloaterPerformance::populateHUDList()
     mHUDsPanel->getChild<LLTextBox>("huds_value")->setValue(std::to_string(complexity_list.size()));
 }
 
+void LLFloaterPerformance::populateObjectList()
+{
+    mObjectList->clearRows();
+    mObjectList->updateColumns(true);
+
+    object_complexity_list_t complexity_list = LLAvatarRenderNotifier::getInstance()->getObjectComplexityList();
+
+    object_complexity_list_t::iterator iter = complexity_list.begin();
+    object_complexity_list_t::iterator end = complexity_list.end();
+
+    for (; iter != end; ++iter)
+    {
+        LLObjectComplexity object_complexity = *iter;        
+
+        LLSD item;
+        item["special_id"] = object_complexity.objectId;
+        item["target"] = LLNameListCtrl::SPECIAL;
+        LLSD& row = item["columns"];
+        row[0]["column"] = "complex_visual";
+        row[0]["type"] = "text";
+        row[0]["value"] = "*";
+
+        row[1]["column"] = "complex_value";
+        row[1]["type"] = "text";
+        row[1]["value"] = std::to_string(object_complexity.objectCost);
+        row[1]["font"]["name"] = "SANSSERIF";
+
+        row[2]["column"] = "name";
+        row[2]["type"] = "text";
+        row[2]["value"] = object_complexity.objectName;
+        row[2]["font"]["name"] = "SANSSERIF";
+
+        mObjectList->addElement(item);
+    }
+    mObjectList->sortByColumnIndex(1, FALSE);
+}
+
 void LLFloaterPerformance::populateNearbyList()
 {
     mNearbyList->clearRows();
     mNearbyList->updateColumns(true);
 
+    S32 avatars = 0;
+
     std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
     while (char_iter != LLCharacter::sInstances.end())
     {
         LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
-        if (avatar && !avatar->isDead() && !avatar->isControlAvatar())
+        if (avatar && !avatar->isDead() && !avatar->isControlAvatar() && !avatar->isSelf())
         {
             avatar->calculateUpdateRenderComplexity(); 
 
@@ -204,17 +282,38 @@ void LLFloaterPerformance::populateNearbyList()
                     name_text->setColor(LLUIColorTable::instance().getColor("ConversationFriendColor"));
                 }
             }
+            avatars++;
         }
         char_iter++;
     }
-    mNearbyList->sortByColumnIndex(1, FALSE);
+    mNearbyList->sortByColumnIndex(1, FALSE); 
+}
 
+void LLFloaterPerformance::updateNearbyComplexityDesc()
+{
+    S32 max_complexity = 0;
+    std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
+    while (char_iter != LLCharacter::sInstances.end())
+    {
+        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
+        if (avatar && !avatar->isDead() && !avatar->isControlAvatar() && !avatar->isSelf())
+        {
+            max_complexity = llmax(max_complexity, (S32)avatar->getVisualComplexity());
+        }
+        char_iter++;
+    }
+    std::string desc = getString(max_complexity > COMPLEXITY_THRESHOLD_1 ? "very_high" : "medium");
+   
+    if (mMainPanel->getVisible())
+    {
+        mMainPanel->getChild<LLTextBox>("avatars_nearby_value")->setValue(desc);
+    }
+    mNearbyPanel->getChild<LLTextBox>("av_nearby_value")->setValue(desc);
 }
 
 void LLFloaterPerformance::detachItem(const LLUUID& item_id)
 {
     LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
-    mHUDList->removeNameItem(item_id);
 }
 
 void LLFloaterPerformance::onClickRecommended()
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 0cba07f21e..1facfe9225 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -37,6 +37,7 @@ public:
     virtual ~LLFloaterPerformance();
 
     /*virtual*/ BOOL postBuild();
+    /*virtual*/ void draw();
 
     void showSelectedPanel(LLPanel* selected_panel);
     void showMainPanel();
@@ -46,6 +47,7 @@ public:
 private:
     void initBackBtn(LLPanel* panel);
     void populateHUDList();
+    void populateObjectList();
     void populateNearbyList();
 
     void onClickAdvanced();
@@ -55,15 +57,20 @@ private:
     void updateMaxComplexity();
     void updateComplexityText();
 
+    void updateNearbyComplexityDesc();
+
     LLPanel* mMainPanel;
     LLPanel* mTroubleshootingPanel;
     LLPanel* mNearbyPanel;
-    LLPanel* mScriptsPanel;
+    LLPanel* mComplexityPanel;
     LLPanel* mHUDsPanel;
-    LLPanel* mPreferencesPanel;
+    LLPanel* mSettingsPanel;
     LLNameListCtrl* mHUDList;
+    LLNameListCtrl* mObjectList;
     LLNameListCtrl* mNearbyList;
 
+    LLTimer* mUpdateTimer;
+
     boost::signals2::connection	mComplexityChangedSignal;
 };
 
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index f69b9b3861..ab7e5f7f8a 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -10533,7 +10533,8 @@ void LLVOAvatar::accountRenderComplexityForObject(
     const F32 max_attachment_complexity,
     LLVOVolume::texture_cost_t& textures,
     U32& cost,
-    hud_complexity_list_t& hud_complexity_list)
+    hud_complexity_list_t& hud_complexity_list,
+    object_complexity_list_t& object_complexity_list)
 {
     if (attached_object && !attached_object->isHUDAttachment())
 		{
@@ -10552,12 +10553,12 @@ void LLVOAvatar::accountRenderComplexityForObject(
                             F32 attachment_volume_cost = 0;
                             F32 attachment_texture_cost = 0;
                             F32 attachment_children_cost = 0;
-                const F32 animated_object_attachment_surcharge = 1000;
+                            const F32 animated_object_attachment_surcharge = 1000;
 
-                if (attached_object->isAnimatedObject())
-                {
-                    attachment_volume_cost += animated_object_attachment_surcharge;
-                }
+                            if (attached_object->isAnimatedObject())
+                            {
+                                attachment_volume_cost += animated_object_attachment_surcharge;
+                            }
 							attachment_volume_cost += volume->getRenderCost(textures);
 
 							const_child_list_t children = volume->getChildren();
@@ -10590,6 +10591,15 @@ void LLVOAvatar::accountRenderComplexityForObject(
                                                    << LL_ENDL;
                             // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
                             cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
+
+                            if (isSelf())
+                            {
+                                LLObjectComplexity object_complexity;
+                                object_complexity.objectName = attached_object->getAttachmentItemName();
+                                object_complexity.objectId = attached_object->getAttachmentItemID();
+                                object_complexity.objectCost = attachment_total_cost;
+                                object_complexity_list.push_back(object_complexity);
+                            }
 						}
 					}
 				}
@@ -10676,6 +10686,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 		U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
 		LLVOVolume::texture_cost_t textures;
 		hud_complexity_list_t hud_complexity_list;
+        object_complexity_list_t object_complexity_list;
 
 		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 		{
@@ -10706,7 +10717,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
             if (volp && !volp->isAttachment())
             {
                 accountRenderComplexityForObject(volp, max_attachment_complexity,
-                                                 textures, cost, hud_complexity_list);
+                                                 textures, cost, hud_complexity_list, object_complexity_list);
             }
         }
 
@@ -10722,7 +10733,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 			{
                 const LLViewerObject* attached_object = attachment_iter->get();
                 accountRenderComplexityForObject(attached_object, max_attachment_complexity,
-                                                 textures, cost, hud_complexity_list);
+                                                 textures, cost, hud_complexity_list, object_complexity_list);
 			}
 		}
 
@@ -10782,13 +10793,13 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 		mVisualComplexity = cost;
 		mVisualComplexityStale = false;
 
-        static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
-
-        if (isSelf() && show_my_complexity_changes)
+        if (isSelf())
         {
             // Avatar complexity
             LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity);
 
+            LLAvatarRenderNotifier::getInstance()->setObjectComplexityList(object_complexity_list);
+
             // HUD complexity
             LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);
         }
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 74ef589ca4..f83f9d4eaf 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -299,7 +299,8 @@ public:
                                                      const F32 max_attachment_complexity,
                                                      LLVOVolume::texture_cost_t& textures,
                                                      U32& cost,
-                                                     hud_complexity_list_t& hud_complexity_list);
+                                                     hud_complexity_list_t& hud_complexity_list,
+                                                     object_complexity_list_t& object_complexity_list);
 	void			calculateUpdateRenderComplexity();
 	static const U32 VISUAL_COMPLEXITY_UNKNOWN;
 	void			updateVisualComplexity();
diff --git a/indra/newview/skins/default/textures/icons/green_dot.png b/indra/newview/skins/default/textures/icons/green_dot.png
deleted file mode 100644
index 02c07810c2..0000000000
Binary files a/indra/newview/skins/default/textures/icons/green_dot.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 51bb91cbf9..a875c4e848 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -234,8 +234,6 @@ with the same filename but different name
   <texture name="Generic_Person" file_name="icons/Generic_Person.png" preload="false" />
   <texture name="Generic_Person_Large" file_name="icons/Generic_Person_Large.png" preload="false" />
 
-  <texture name="Green_dot" file_name="icons/green_dot.png" preload="false" />
-
   <texture name="Hand" file_name="icons/hand.png" preload="false" />
   
   <texture name="Help_Press" file_name="navbar/Help_Press.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index 42269ba34a..09af364266 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -1,409 +1,387 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- height="550"
+ height="590"
  layout="topleft"
  name="performance"
  save_rect="true"
  title="IMPROVE GRAPHICS SPEED"
  width="580">
+  <string
+     name="very_high"
+     value="very high"/>
+  <string
+     name="medium"
+     value="medium"/>
   <panel
    bevel_style="none"
    follows="left|top"
-   height="490"
+   height="540"
    width="580"
-   name="panel_performance_main"
+   name="panel_top"
    visible="true"
    layout="topleft"
    left="0"   
    top="0">
-    <text
+    <panel
+     bg_alpha_color="black"
+     background_visible="true"
+     background_opaque="false"
+     border="false"
+     bevel_style="none"
      follows="left|top"
-     font="SansSerifHuge"
-     text_color="White"
-     height="20"
+     height="40"
+     width="560"
+     name="fps_subpanel"
      layout="topleft"
      left="10"
-     name="fps_lbl"
-     top="17"
-     width="130">
-        Current FPS
-    </text>
-    <text
-     follows="left|top"
-     font="SansSerifHugeBold"
-     text_color="White"
-     height="20"
-     layout="topleft"
-     left_pad="5"
-     name="fps_value"
-     width="100">
-        75.2
-    </text>
-  
-    <icon
-     height="16"
-     width="16"
-     image_name="Green_dot"
-     mouse_opaque="true"
-     name="icon_arrow4"
-     follows="right|top"
-     top="16"
-     right="-154"/>
-    <icon
-     height="16"
-     width="16"
-     image_name="Green_dot"
-     mouse_opaque="true"
-     name="icon_arrow4"
-     follows="right|top"
-     top_pad="9"/>
-    <icon
-     height="16"
-     width="16"
-     image_name="Green_dot"
-     mouse_opaque="true"
-     name="icon_arrow4"
-     follows="right|top"
-     top_pad="8"/>
- 
-    <text
-     follows="right|top"
-     font="SansSerif"
-     height="20"
-     layout="topleft"
-     top="17"
-     right="-90"
-     name="client_lbl"
-     width="60">
-        Client:
-    </text>
-    <text
-     follows="right|top"
-     font="SansSerif"
-     height="20"
-     layout="topleft"
-     top_pad="5"
-     name="client_lbl"
-     width="60">
-        Network:
-    </text>
-    <text
-     follows="right|top"
-     font="SansSerif"
-     height="20"
-     layout="topleft"
-     top_pad="5"
-     name="client_lbl"
-     width="60">
-        Server:
-    </text>
-    <text
-     follows="right|top"
-     font="SansSerif"
-     height="20"
-     layout="topleft"
-     right="-15"
-     name="client_value"
-     top="17"
-     width="45">
-        Normal
-    </text>
-    <text
-     follows="right|top"
-     font="SansSerif"
-     height="20"
-     layout="topleft"
-     name="network_value"
-     top_pad="5"
-     width="45">
-        Normal
-    </text>
-    <text
-     follows="right|top"
-     font="SansSerif"
-     height="20"
-     layout="topleft"
-     name="server_value"
-     top_pad="5"
-     width="45">
-        Normal
-    </text> 
-  <panel
-   bg_alpha_color="PerformanceFloaterGray"
-   background_visible="true"
-   background_opaque="false"
-   border="true"
-   bevel_style="none"
-   follows="left|top"
-   height="60"
-   width="560"
-   name="troubleshooting_subpanel"
-   layout="topleft"
-   left="10"
-   top="102">
-    <text
-     follows="left|top"
-     font="SansSerifLarge"
-     text_color="White"
-     height="20"
-     layout="topleft"
-     left="10"
-     name="troubleshooting_lbl"
-     top="12"
-     width="395">
-        General troubleshooting
-    </text>
-    <text
-     follows="left|top"
-     font="SansSerif"
-     text_color="White"
-     height="20"
-     layout="topleft"
-     left="10"
-     name="troubleshooting_info"
-     top_pad="5"
-     width="395">
-        Choose among common problems and see what you can do.
-    </text>
-    <icon
-     height="16"
-     width="16"
-     image_name="Arrow_Right_Off"
-     mouse_opaque="true"
-     name="icon_arrow1"
-     follows="right|top"
-     top="24"
-     right="-20"/>
+     top="5">
+      <text
+       follows="left|top"
+       font="SansSerifHuge"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="20"
+       top="8"
+       name="fps_value"
+       width="40">
+          75
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left_pad="0"
+       top="14"
+       name="fps_lbl"
+       width="450">
+          FPS -- 60 or more for the best experience
+      </text>    
+    </panel>
   </panel>
   <panel
-   bg_alpha_color="PerformanceFloaterGray"
-   background_visible="true"
-   background_opaque="false"
-   border="true"
    bevel_style="none"
    follows="left|top"
-   height="60"
-   width="560"
-   name="nearby_subpanel"
-   layout="topleft"
-   top_pad="20">
-    <text
-     follows="left|top"
-     font="SansSerifLarge"
-     text_color="White"
-     height="20"
-     layout="topleft"
-     left="10"
-     name="avatars_nearby_lbl"
-     top="12"
-     width="115">
-        Avatars nearby:
-    </text>
-    <text
-     follows="left|top"
-     font="SansSerifLarge"
-     text_color="PerformanceMid"
-     height="20"
-     layout="topleft"
-     left_pad="3"
-     name="avatars_nearby_value"
-     width="100">
-        42 (very high)
-    </text>
-    <text
-     follows="left|top"
-     font="SansSerif"
-     text_color="White"
-     height="20"
-     layout="topleft"
-     left="10"
-     name="avatars_nearby_info"
-     top_pad="5"
-     width="395">
-        Click to review avatars and choose a complexity limit.
-    </text>
-    <icon
-     height="16"
-     width="16"
-     image_name="Arrow_Right_Off"
-     mouse_opaque="true"
-     name="icon_arrow2"
-     follows="right|top"
-     top="24"
-     right="-20"/>
-  </panel>
-  <panel
-   bg_alpha_color="PerformanceFloaterGray"
-   background_visible="true"
-   background_opaque="false"
-   border="true"
-   bevel_style="none"
-   follows="left|top"
-   height="60"
-   width="560"
-   name="preferences_subpanel"
-   layout="topleft"
-   top_pad="20">
-    <text
-     follows="left|top"
-     font="SansSerifLarge"
-     text_color="White"
-     height="20"
-     layout="topleft"
-     left="10"
-     name="complexity_lbl"
-     top="12"
-     width="110">
-        This location is
-    </text>
-    <text
-     follows="left|top"
-     font="SansSerifLarge"
-     text_color="PerformanceMid"
-     height="20"
-     layout="topleft"
-     left_pad="3"
-     name="complexity_value"
-     width="100">
-        very complex
-    </text>
-    <text
-     follows="left|top"
-     font="SansSerif"
-     text_color="White"
-     height="20"
-     layout="topleft"
-     left="10"
-     name="complexity_info"
-     top_pad="5"
-     width="395">
-        Try changing graphics quality or draw distance.
-    </text>
-    <icon
-     height="16"
-     width="16"
-     image_name="Arrow_Right_Off"
-     mouse_opaque="true"
-     name="icon_arrow3"
-     follows="right|top"
-     top="24"
-     right="-20"/>
-  </panel>
-  <panel
-   bg_alpha_color="PerformanceFloaterGray"
-   background_visible="true"
-   background_opaque="false"
-   border="true"
-   bevel_style="none"
-   follows="left|top"
-   height="60"
-   width="560"
-   name="scripts_subpanel"
+   height="540"
+   width="580"
+   name="panel_performance_main"
+   visible="true"
    layout="topleft"
-   top_pad="20">
-    <text
+   left="0"   
+   top="60">
+    <panel
+     bg_alpha_color="PerformanceFloaterGray"
+     background_visible="true"
+     background_opaque="false"
+     border="true"
+     bevel_style="none"
      follows="left|top"
-     font="SansSerifLarge"
-     text_color="White"
-     height="20"
+     height="60"
+     width="560"
+     name="presets_subpanel"
      layout="topleft"
      left="10"
-     name="scripts_lbl"
-     top="12"
-     width="88">
-        Your avatar:
-    </text>
-    <text
+     top="5">
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="presets_lbl"
+       top="12"
+       width="395">
+          Quick settings for common situations
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerif"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="presets_desc"
+       top_pad="5"
+       width="395">
+          Choose settings for parties, exploration, photography, and more.
+      </text>
+      <icon
+       height="16"
+       width="16"
+       image_name="Arrow_Right_Off"
+       mouse_opaque="true"
+       name="icon_arrow1"
+       follows="right|top"
+       top="24"
+       right="-20"/>
+    </panel>
+    <panel
+     bg_alpha_color="PerformanceFloaterGray"
+     background_visible="true"
+     background_opaque="false"
+     border="true"
+     bevel_style="none"
      follows="left|top"
-     font="SansSerifLarge"
-     text_color="PerformanceMid"
-     height="20"
+     height="60"
+     width="560"
+     name="settings_subpanel"
      layout="topleft"
-     left_pad="2"
-     name="scripts_value"
-     width="100">
-        12 scripts
-    </text>
-    <text
+     top_pad="20">
+        <text
+         follows="left|top"
+         font="SansSerifLarge"
+         text_color="White"
+         height="20"
+         layout="topleft"
+         left="10"
+         name="settings_lbl"
+         top="12"
+         width="180">
+          Individual settings
+        </text>
+        <text
+         follows="left|top"
+         font="SansSerif"
+         text_color="White"
+         height="20"
+         layout="topleft"
+         left="10"
+         name="settings_desc"
+         top_pad="5"
+         width="395">
+          More control over quality, visibility distance, and enhancements.
+        </text>
+        <icon
+         height="16"
+         width="16"
+         image_name="Arrow_Right_Off"
+         mouse_opaque="true"
+         name="icon_arrow3"
+         follows="right|top"
+         top="24"
+         right="-20"/>
+      </panel>
+    <panel
+     bg_alpha_color="PerformanceFloaterGray"
+     background_visible="true"
+     background_opaque="false"
+     border="true"
+     bevel_style="none"
      follows="left|top"
-     font="SansSerif"
-     text_color="White"
-     height="20"
+     height="60"
+     width="560"
+     name="nearby_subpanel"
      layout="topleft"
-     left="10"
-     name="scripts_info"
-     top_pad="5"
-     width="395">
-        Removing high-impact attachments may improve graphics speed.
-    </text>
-    <icon
-     height="16"
-     width="16"
-     image_name="Arrow_Right_Off"
-     mouse_opaque="true"
-     name="icon_arrow4"
-     follows="right|top"
-     top="24"
-     right="-20"/>
-  </panel>
-  <panel
-   bg_alpha_color="PerformanceFloaterGray"
-   background_visible="true"
-   background_opaque="false"
-   border="true"
-   bevel_style="none"
-   follows="left|top"
-   height="60"
-   width="560"
-   name="huds_subpanel"
-   layout="topleft"
-   top_pad="20">
-    <text
+     top_pad="20">
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="avatars_nearby_lbl"
+       top="12"
+       width="205">
+          Nearby avatar complexity is
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="PerformanceMid"
+       height="20"
+       layout="topleft"
+       left_pad="5"
+       name="avatars_nearby_value"
+       width="100">
+          very high
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerif"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="avatars_nearby_desc"
+       top_pad="5"
+       width="395">
+          Choose which avatars are not displayed in detail, to increase FPS.
+      </text>
+      <icon
+       height="16"
+       width="16"
+       image_name="Arrow_Right_Off"
+       mouse_opaque="true"
+       name="icon_arrow2"
+       follows="right|top"
+       top="24"
+       right="-20"/>
+    </panel>
+    <panel
+     bg_alpha_color="PerformanceFloaterGray"
+     background_visible="true"
+     background_opaque="false"
+     border="true"
+     bevel_style="none"
      follows="left|top"
-     font="SansSerifLarge"
-     text_color="White"
-     height="20"
+     height="60"
+     width="560"
+     name="complexity_subpanel"
      layout="topleft"
-     left="10"
-     name="huds_lbl"
-     top="12"
-     width="80">
-        Your HUDs:
-    </text>
-    <text
+     top_pad="20">
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="complexity_lbl"
+       top="12"
+       width="180">
+          Your avatar complexity is
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="PerformanceMid"
+       height="20"
+       layout="topleft"
+       left_pad="5"
+       name="complexity_value"
+       width="100">
+          275
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerif"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="complexity_info"
+       top_pad="5"
+       width="455">
+          Reduce the complexity of your avatar if you aren't satisfied with current FPS.
+      </text>
+      <icon
+       height="16"
+       width="16"
+       image_name="Arrow_Right_Off"
+       mouse_opaque="true"
+       name="icon_arrow4"
+       follows="right|top"
+       top="24"
+       right="-20"/>
+    </panel>
+    <panel
+     bg_alpha_color="PerformanceFloaterGray"
+     background_visible="true"
+     background_opaque="false"
+     border="true"
+     bevel_style="none"
      follows="left|top"
-     font="SansSerifLarge"
-     text_color="PerformanceMid"
-     height="20"
+     height="60"
+     width="560"
+     name="huds_subpanel"
      layout="topleft"
-     left_pad="3"
-     name="huds_value"
-     width="100">
-        7
-    </text>
-    <text
+     top_pad="20">
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="huds_lbl"
+       top="12"
+       width="135">
+          Your current HUDs:
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="PerformanceMid"
+       height="20"
+       layout="topleft"
+       left_pad="5"
+       name="huds_value"
+       width="100">
+          7
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerif"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="huds_desc"
+       top_pad="5"
+       width="395">
+          Removing HUDs you are not using can improve speed.
+      </text>
+      <icon
+       height="16"
+       width="16"
+       image_name="Arrow_Right_Off"
+       mouse_opaque="true"
+       name="icon_arrow4"
+       follows="right|top"
+       top="24"
+       right="-20"/>
+    </panel>
+    <panel
+     bg_alpha_color="PerformanceFloaterGray"
+     background_visible="true"
+     background_opaque="false"
+     border="true"
+     bevel_style="none"
      follows="left|top"
-     font="SansSerif"
-     text_color="White"
-     height="20"
+     height="60"
+     width="560"
+     name="troubleshooting_subpanel"
      layout="topleft"
-     left="10"
-     name="huds_info"
-     top_pad="5"
-     width="395">
-        Removing HUDs you are not using can improve graphics speed.
-    </text>
-    <icon
-     height="16"
-     width="16"
-     image_name="Arrow_Right_Off"
-     mouse_opaque="true"
-     name="icon_arrow4"
-     follows="right|top"
-     top="24"
-     right="-20"/>
+     top_pad="20">
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="troubleshooting_lbl"
+       top="12"
+       width="395">
+          General troubleshooting
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerif"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="troubleshooting_desc"
+       top_pad="5"
+       width="395">
+          Choose among common problems and see what you can do.
+      </text>
+      <icon
+       height="16"
+       width="16"
+       image_name="Arrow_Right_Off"
+       mouse_opaque="true"
+       name="icon_arrow1"
+       follows="right|top"
+       top="24"
+       right="-20"/>
+    </panel>
   </panel>
- </panel>
   <panel
     filename="panel_performance_troubleshooting.xml"
     follows="all"
@@ -411,7 +389,7 @@
     left="0"
     name="panel_performance_troubleshooting"
     visible="false"
-    top="0" />
+    top="55" />
   <panel
     filename="panel_performance_nearby.xml"
     follows="all"
@@ -419,15 +397,15 @@
     left="0"
     name="panel_performance_nearby"
     visible="false"
-    top="0" />
+    top="55" />
   <panel
-    filename="panel_performance_scripts.xml"
+    filename="panel_performance_complexity.xml"
     follows="all"
     layout="topleft"
     left="0"
-    name="panel_performance_scripts"
+    name="panel_performance_complexity"
     visible="false"
-    top="0" />
+    top="55" />
   <panel
     filename="panel_performance_preferences.xml"
     follows="all"
@@ -435,7 +413,7 @@
     left="0"
     name="panel_performance_preferences"
     visible="false"
-    top="0" />
+    top="55" />
   <panel
     filename="panel_performance_huds.xml"
     follows="all"
@@ -443,5 +421,5 @@
     left="0"
     name="panel_performance_huds"
     visible="false"
-    top="0" />
+    top="55" />
 </floater>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
new file mode 100644
index 0000000000..8d4512c4f7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="left|top"
+ height="490"
+ width="580"
+ name="panel_performance_complexity"
+ layout="topleft"
+ left="0"
+ top="0">
+  <button
+    height="16"
+    width="16"
+    layout="topleft"
+    mouse_opaque="true"
+    follows="left|top"
+    name="back_btn"
+    top="7"
+    image_selected="Arrow_Left_Off"
+    image_pressed="Arrow_Left_Off"
+    image_unselected="Arrow_Left_Off"
+    left="15"
+    is_toggle="true">
+  </button>
+  <text
+   follows="left|top"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   top="10"
+   name="back_lbl"
+   width="40">
+    Back
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="white"
+   height="20"
+   layout="topleft"
+   left="20"
+   top_pad="10"
+   name="attachments_title"
+   width="195">
+    My avatar complexity 
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   left="20"
+   name="attachments_desc1"
+   width="580">
+    Complex attachments require more time and memory to display.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="3"
+   left="20"
+   name="attachments_desc2"
+   width="580">
+    While you are in this location, removing the most complex ones may increase speed.
+  </text>
+  <name_list
+    column_padding="0"
+    draw_stripes="true"
+    height="220"
+    follows="left|top"
+    layout="topleft"
+    name="obj_list"
+    top_pad="10"
+    width="540">
+      <name_list.columns
+       label=""
+       name="complex_visual"
+       width="90" />
+      <name_list.columns
+       label=""
+       name="complex_value"
+       width="40" />
+      <name_list.columns
+       label=""
+       name="name"/>
+  </name_list>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_huds.xml b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
index c881fadbe8..96bdf2412f 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_huds.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
@@ -15,7 +15,7 @@
     mouse_opaque="true"
     follows="left|top"
     name="back_btn"
-    top="10"
+    top="7"
     image_selected="Arrow_Left_Off"
     image_pressed="Arrow_Left_Off"
     image_unselected="Arrow_Left_Off"
@@ -27,7 +27,7 @@
    height="20"
    layout="topleft"
    left_pad="3"
-   top="13"
+   top="10"
    name="back_lbl"
    width="40">
     Back
@@ -35,14 +35,14 @@
   <text
    follows="left|top"
    font="SansSerifLarge"
-   text_color="PerformanceMid"
+   text_color="White"
    height="20"
    layout="topleft"
    left="20"
    top_pad="10"
    name="huds_title"
-   width="120">
-    HUDs displayed: 
+   width="135">
+    Your current HUDs: 
   </text>
   <text
    follows="left|top"
@@ -65,7 +65,7 @@
    left="20"
    name="huds_desc1"
    width="540">
-    If there are any you don't need, detaching them may improve graphics speed.
+    Detaching HUDs you aren't using us always a good idea, but especially in a complex location.
   </text>
   <text
    follows="left|top"
@@ -100,13 +100,5 @@
          label=""
          name="name"/>
   </name_list>
-  <button
-   follows="left|top"
-   height="19"
-   label="Refresh List"
-   layout="topleft"
-   name="refresh_list_btn"
-   top_pad="20"
-   width="100" />
 </panel>
 
diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
index d71b5334cd..28ffbd5c2e 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
@@ -15,7 +15,7 @@
     mouse_opaque="true"
     follows="left|top"
     name="back_btn"
-    top="10"
+    top="7"
     image_selected="Arrow_Left_Off"
     image_pressed="Arrow_Left_Off"
     image_unselected="Arrow_Left_Off"
@@ -27,7 +27,7 @@
    height="20"
    layout="topleft"
    left_pad="3"
-   top="13"
+   top="10"
    name="back_lbl"
    width="40">
     Back
@@ -35,14 +35,14 @@
   <text
    follows="left|top"
    font="SansSerifLarge"
-   text_color="PerformanceMid"
+   text_color="White"
    height="20"
    layout="topleft"
    left="20"
    top_pad="10"
    name="av_nearby_title"
-   width="215">
-    Avatars within draw distance:
+   width="205">
+    Nearby avatar complexity is
   </text>
   <text
    follows="left|top"
@@ -53,7 +53,7 @@
    left_pad="3"
    name="av_nearby_value"
    width="150">
-    42 (very high)
+    very high
   </text>
   <text
    follows="left|top"
@@ -65,7 +65,7 @@
    top_pad="5"
    name="av_nearby_desc"
    width="580">
-    Some avatars nearby are slow to display. Choosing complexity limit may help graphics speed.
+    Some avatars nearby are slow to display. Choosing a complexity limit may help graphics speed.
   </text>
   <slider
     control_name="IndirectMaxComplexity"
@@ -74,7 +74,8 @@
     height="16"
     initial_value="101"
     increment="1"
-    label="Avatar Maximum Complexity:"
+    label="Maximum avatar complexity"
+    text_color="White"
     label_width="165"
     layout="topleft"
     min_val="1"
@@ -82,6 +83,7 @@
     name="IndirectMaxComplexity"
     show_text="false"
     top_pad="10"
+    left="40"
     width="300">
   </slider>
   <text
@@ -92,7 +94,7 @@
     layout="topleft"
     top_delta="0"
     left_delta="304"
-    text_readonly_color="LabelDisabledColor"
+    text_color="White"
     name="IndirectMaxComplexityText"
     width="65">
     0
@@ -116,7 +118,7 @@
         <name_list.columns
          label=""
          name="complex_value"
-         width="40" />
+         width="50" />
         <name_list.columns
          label=""
          name="name"/>
@@ -131,7 +133,7 @@
    top_pad="10"
    name="av_nearby_desc2"
    width="580">
-     You can also right-click on an avatar to control display.
+     You can also right-click on an avatar in-world to control display.
   </text>
   <button
     height="23"
@@ -147,6 +149,7 @@
     height="16"
     initial_value="true"
     label="Always display friends"
+    label_text.text_color="White"
     layout="topleft"
     name="display_friends"
     top_pad="3"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index 81605b35a2..aaa27061e3 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -15,7 +15,7 @@
     mouse_opaque="true"
     follows="left|top"
     name="back_btn"
-    top="10"
+    top="7"
     image_selected="Arrow_Left_Off"
     image_pressed="Arrow_Left_Off"
     image_unselected="Arrow_Left_Off"
@@ -27,7 +27,7 @@
    height="20"
    layout="topleft"
    left_pad="3"
-   top="13"
+   top="10"
    name="back_lbl"
    width="40">
     Back
diff --git a/indra/newview/skins/default/xui/en/panel_performance_scripts.xml b/indra/newview/skins/default/xui/en/panel_performance_scripts.xml
deleted file mode 100644
index e6dc4a217d..0000000000
--- a/indra/newview/skins/default/xui/en/panel_performance_scripts.xml
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- bevel_style="none"
- follows="left|top"
- height="490"
- width="580"
- name="panel_performance_scripts"
- layout="topleft"
- left="0"
- top="0">
-  <button
-    height="16"
-    width="16"
-    layout="topleft"
-    mouse_opaque="true"
-    follows="left|top"
-    name="back_btn"
-    top="10"
-    image_selected="Arrow_Left_Off"
-    image_pressed="Arrow_Left_Off"
-    image_unselected="Arrow_Left_Off"
-    left="15"
-    is_toggle="true">
-  </button>
-  <text
-   follows="left|top"
-   height="20"
-   layout="topleft"
-   left_pad="3"
-   top="13"
-   name="back_lbl"
-   width="40">
-    Back
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLarge"
-   text_color="PerformanceMid"
-   height="20"
-   layout="topleft"
-   left="20"
-   top_pad="10"
-   name="attachments_title"
-   width="195">
-    Avatar attachment scripts: 
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLargeBold"
-   text_color="PerformanceMid"
-   height="20"
-   layout="topleft"
-   left_pad="5"
-   name="attachments_value"
-   width="70">
-    12
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="5"
-   left="20"
-   name="attachments_desc1"
-   width="580">
-    These attachments contain scripts (embedded apps) that use memory.
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="3"
-   left="20"
-   name="attachments_desc2"
-   width="580">
-    If there are any you don't need, detaching them may improve graphics speed.
-  </text>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml b/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml
index d942580880..0a14eeb1c0 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml
@@ -15,7 +15,7 @@
     mouse_opaque="true"
     follows="left|top"
     name="back_btn"
-    top="10"
+    top="7"
     image_selected="Arrow_Left_Off"
     image_pressed="Arrow_Left_Off"
     image_unselected="Arrow_Left_Off"
@@ -27,7 +27,7 @@
    height="20"
    layout="topleft"
    left_pad="3"
-   top="13"
+   top="10"
    name="back_lbl"
    width="40">
     Back
-- 
cgit v1.2.3


From 3fe7715197c1e9a4ae781201df7a9ec24354f15e Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 18 Jun 2021 18:36:15 +0300
Subject: SL-15297 WIP Implement performance floater - Quick and Individual
 settings panels

---
 indra/newview/llfloaterperformance.cpp             |  45 +++-
 indra/newview/llfloaterperformance.h               |   3 +-
 .../skins/default/xui/en/floater_performance.xml   |  10 +-
 .../default/xui/en/panel_performance_nearby.xml    |   2 +-
 .../xui/en/panel_performance_preferences.xml       | 255 ++++++++++++++++-----
 .../default/xui/en/panel_performance_presets.xml   | 223 ++++++++++++++++++
 6 files changed, 461 insertions(+), 77 deletions(-)
 create mode 100644 indra/newview/skins/default/xui/en/panel_performance_presets.xml

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index c96d3dac5e..424ca04b1f 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -63,18 +63,21 @@ BOOL LLFloaterPerformance::postBuild()
     mComplexityPanel = getChild<LLPanel>("panel_performance_complexity");
     mSettingsPanel = getChild<LLPanel>("panel_performance_preferences");
     mHUDsPanel = getChild<LLPanel>("panel_performance_huds");
+    mPresetsPanel = getChild<LLPanel>("panel_performance_presets");
 
     getChild<LLPanel>("troubleshooting_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mTroubleshootingPanel));
     getChild<LLPanel>("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel));
     getChild<LLPanel>("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel));
     getChild<LLPanel>("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel));
     getChild<LLPanel>("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel));
+    getChild<LLPanel>("presets_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mPresetsPanel));
 
     initBackBtn(mTroubleshootingPanel);
     initBackBtn(mNearbyPanel);
     initBackBtn(mComplexityPanel);
     initBackBtn(mSettingsPanel);
     initBackBtn(mHUDsPanel);
+    initBackBtn(mPresetsPanel);
 
     mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");
     mHUDList->setNameListType(LLNameListCtrl::SPECIAL);
@@ -87,11 +90,13 @@ BOOL LLFloaterPerformance::postBuild()
     mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
 
     mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
-    mSettingsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickRecommended, this));
 
     mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
     mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
 
+    mPresetsPanel->getChild<LLTextBox>("avatars_nearby_link")->setURLClickedCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel));
+    mPresetsPanel->getChild<LLTextBox>("settings_link")->setURLClickedCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel));
+
     updateComplexityText();
     mComplexityChangedSignal = gSavedSettings.getControl("IndirectMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this));
     mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxComplexity, this));
@@ -103,8 +108,9 @@ BOOL LLFloaterPerformance::postBuild()
 
 void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
 {
-    selected_panel->setVisible(TRUE);
+    hidePanels();
     mMainPanel->setVisible(FALSE);
+    selected_panel->setVisible(TRUE);
 
     if (mHUDsPanel == selected_panel)
     {
@@ -147,13 +153,19 @@ void LLFloaterPerformance::draw()
 }
 
 void LLFloaterPerformance::showMainPanel()
+{
+    hidePanels();
+    mMainPanel->setVisible(TRUE);
+}
+
+void LLFloaterPerformance::hidePanels()
 {
     mTroubleshootingPanel->setVisible(FALSE);
     mNearbyPanel->setVisible(FALSE);
     mComplexityPanel->setVisible(FALSE);
     mHUDsPanel->setVisible(FALSE);
     mSettingsPanel->setVisible(FALSE);
-    mMainPanel->setVisible(TRUE);
+    mPresetsPanel->setVisible(FALSE);
 }
 
 void LLFloaterPerformance::initBackBtn(LLPanel* panel)
@@ -247,6 +259,7 @@ void LLFloaterPerformance::populateNearbyList()
     mNearbyList->updateColumns(true);
 
     S32 avatars = 0;
+    static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
 
     std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
     while (char_iter != LLCharacter::sInstances.end())
@@ -274,12 +287,21 @@ void LLFloaterPerformance::populateNearbyList()
             row[2]["font"]["name"] = "SANSSERIF";
 
             LLScrollListItem* av_item = mNearbyList->addElement(item);
-            if(av_item && LLAvatarActions::isFriend(avatar->getID()))
+            if(av_item)
             {
                 LLScrollListText* name_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(2));
                 if (name_text)
                 {
-                    name_text->setColor(LLUIColorTable::instance().getColor("ConversationFriendColor"));
+                    std::string color = "white";
+                    if (avatar->getVisualComplexity() > max_render_cost)
+                    {
+                        color = "LabelDisabledColor";
+                    }
+                    else if (LLAvatarActions::isFriend(avatar->getID()))
+                    {
+                        color = "ConversationFriendColor";
+                    }
+                    name_text->setColor(LLUIColorTable::instance().getColor(color));
                 }
             }
             avatars++;
@@ -291,6 +313,7 @@ void LLFloaterPerformance::populateNearbyList()
 
 void LLFloaterPerformance::updateNearbyComplexityDesc()
 {
+    static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); 
     S32 max_complexity = 0;
     std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
     while (char_iter != LLCharacter::sInstances.end())
@@ -302,7 +325,7 @@ void LLFloaterPerformance::updateNearbyComplexityDesc()
         }
         char_iter++;
     }
-    std::string desc = getString(max_complexity > COMPLEXITY_THRESHOLD_1 ? "very_high" : "medium");
+    std::string desc = getString(max_complexity > llmin((S32)max_render_cost, COMPLEXITY_THRESHOLD_1) ? "very_high" : "medium");
    
     if (mMainPanel->getVisible())
     {
@@ -316,13 +339,13 @@ void LLFloaterPerformance::detachItem(const LLUUID& item_id)
     LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
 }
 
-void LLFloaterPerformance::onClickRecommended()
-{
-    LLFeatureManager::getInstance()->applyRecommendedSettings();
-}
-
 void LLFloaterPerformance::onClickAdvanced()
 {
+    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {
+        instance->saveSettings();
+    }
     LLFloaterReg::showInstance("prefs_graphics_advanced");
 }
 
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 1facfe9225..7aec7c3f6c 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -41,6 +41,7 @@ public:
 
     void showSelectedPanel(LLPanel* selected_panel);
     void showMainPanel();
+    void hidePanels();
 
     void detachItem(const LLUUID& item_id);
 
@@ -51,7 +52,6 @@ private:
     void populateNearbyList();
 
     void onClickAdvanced();
-    void onClickRecommended();
     void onClickExceptions();
 
     void updateMaxComplexity();
@@ -65,6 +65,7 @@ private:
     LLPanel* mComplexityPanel;
     LLPanel* mHUDsPanel;
     LLPanel* mSettingsPanel;
+    LLPanel* mPresetsPanel;
     LLNameListCtrl* mHUDList;
     LLNameListCtrl* mObjectList;
     LLNameListCtrl* mNearbyList;
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index 09af364266..e415ac5be0 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -194,7 +194,7 @@
        text_color="PerformanceMid"
        height="20"
        layout="topleft"
-       left_pad="5"
+       left_pad="2"
        name="avatars_nearby_value"
        width="100">
           very high
@@ -382,6 +382,14 @@
        right="-20"/>
     </panel>
   </panel>
+  <panel
+    filename="panel_performance_presets.xml"
+    follows="all"
+    layout="topleft"
+    left="0"
+    name="panel_performance_presets"
+    visible="false"
+    top="55" />
   <panel
     filename="panel_performance_troubleshooting.xml"
     follows="all"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
index 28ffbd5c2e..9d91e86b7a 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
@@ -46,7 +46,7 @@
   </text>
   <text
    follows="left|top"
-   font="SansSerifLargeBold"
+   font="SansSerifLarge"
    text_color="PerformanceMid"
    height="20"
    layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index aaa27061e3..ec1b624f13 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="490"
+ height="510"
  width="580"
  name="panel_performance_preferences"
  layout="topleft"
@@ -35,37 +35,33 @@
   <text
    follows="left|top"
    font="SansSerifLarge"
-   text_color="PerformanceMid"
+   text_color="white"
    height="20"
    layout="topleft"
    left="20"
    top_pad="10"
-   name="preferences_title"
+   name="settings_title"
    width="300">
-    This location is very complex
+    Individual settings
   </text>
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="border1"
+    top_pad="8"
+    width="540"/>
   <text
    follows="left|top"
    font="SansSerifSmall"
    text_color="White"
    height="18"
    layout="topleft"
-   top_pad="5"
-   name="preferences_desc"
-   width="580">
-    While you are here, you may want to reduce graphics quality or draw distance.
-  </text>
-
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="35"
+   top_pad="20"
    name="quality_lbl"
    width="100">
     Graphics quality
+shortcuts
   </text>
   <text
    follows="left|top"
@@ -111,43 +107,31 @@
    text_color="White"
    height="18"
    layout="topleft"
-   top_pad="40"
-   left="20"
-   name="enhancements_lbl"
-   width="100">
-    Enhancements
+   top_pad="15"
+   left="160"
+   name="quality_desc"
+   width="380">
+    Choosing a shortcut will reset all manual changes you have made.
   </text>
-  <check_box
-    control_name="WindLightUseAtmosShaders"
-    height="16"
-    initial_value="true"
-    label="Atmospheric shaders"
+  <view_border
+    bevel_style="in"
+    height="0"
     layout="topleft"
-    name="atmospheric_shaders"
-    left_pad="37"
-    width="280">
-  </check_box>
-  <check_box
-    control_name="RenderDeferred"
-    height="16"
-    initial_value="true"
-    label="Advanced Lighting Model"
-    layout="topleft"
-    name="advanced_lighting_model"
-    top_delta="24"
-    width="256">
-  </check_box>
+    name="border2"
+    top_pad="15"
+    left="20"
+    width="540"/>
   <text
    follows="left|top"
    font="SansSerifSmall"
    text_color="White"
    height="18"
    layout="topleft"
-   top_pad="40"
+   top_pad="20"
    left="20"
    name="distance_lbl"
    width="100">
-    Draw distance
+    Visibility distance
   </text>
   <text
    follows="left|top"
@@ -205,11 +189,11 @@
    text_color="White"
    height="18"
    layout="topleft"
-   top_pad="20"
+   top_pad="15"
    left="160"
    name="distance_desc1"
-   width="100">
-    Regions are 256 m x 256 m.
+   width="350">
+    To zoom out and see long distances, increase the distance.
   </text>
   <text
    follows="left|top"
@@ -220,38 +204,183 @@
    top_pad="5"
    left="160"
    name="distance_desc2"
-   width="400">
-    To zoom out and see long distances, increase the draw distance.
+   width="350">
+    If you are indoors, decrease the distance to improve speed.
   </text>
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="border3"
+    top_pad="15"
+    left="20"
+    width="540"/>
   <text
    follows="left|top"
    font="SansSerifSmall"
    text_color="White"
    height="18"
    layout="topleft"
-   top_pad="5"
+   top_pad="20"
+   left="20"
+   name="enhancements_lbl"
+   width="100">
+    Enhancements
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_delta="0"
    left="160"
-   name="distance_desc3"
-   width="400">
-    If you are socializing in a small area, decrease the draw distance.
+   name="enhancements_desc"
+   width="350">
+    Each enhancement improves realism but can reduce speed.
   </text>
-  <button
-    follows="top|left"
-    height="23"
-    label="Reset to recommended settings"
+  <check_box
+    control_name="WindLightUseAtmosShaders"
+    height="16"
+    initial_value="true"
+    label="Atmospheric shaders"
+    layout="topleft"
+    name="atmospheric_shaders"
+    top_pad="5"
+    left="157"
+    width="280">
+  </check_box>
+  <check_box
+    control_name="RenderDeferred"
+    height="16"
+    initial_value="true"
+    label="Advanced Lighting"
+    layout="topleft"
+    name="advanced_lighting_model"
+    top_delta="24"
+    width="280">
+  </check_box>
+  <check_box
+    control_name="RenderTransparentWater"
+    height="16"
+    initial_value="true"
+    label="Transparent Water"
+    layout="topleft"
+    name="TransparentWater"
+    top_delta="24"
+    width="280">
+  </check_box>
+  <text
+    type="string"
+    length="1"
+    follows="left|top"
+    height="16"
+    layout="topleft"
+    name="ReflectionsText"
+    text_readonly_color="LabelDisabledColor"
+    top_pad="16"
+    left="160"
+    width="128">
+    Water Reflections:
+  </text>
+  <combo_box
+    control_name="RenderReflectionDetail"
+    height="18"
+    layout="topleft"
+    left_delta="150"
+    top_delta="0"
+    name="Reflections"
+    width="150">
+    <combo_box.item
+      label="None; opaque"
+      name="0"
+      value="-2"/>
+    <combo_box.item
+      label="None; transparent"
+      name="0"
+      value="-1"/>
+    <combo_box.item
+      label="Minimal"
+      name="0"
+      value="0"/>
+    <combo_box.item
+      label="Terrain and trees"
+      name="1"
+      value="1"/>
+    <combo_box.item
+      label="All static objects"
+      name="2"
+      value="2"/>
+    <combo_box.item
+      label="All avatars and objects"
+      name="3"
+      value="3"/>
+    <combo_box.item
+      label="Everything"
+      name="4"
+      value="4"/>
+  </combo_box>
+  <text
+    type="string"
+    length="1"
+    follows="left|top"
+    height="16"
     layout="topleft"
+    left="160"
+    name="RenderShadowDetailText"
+    text_readonly_color="LabelDisabledColor"
+    top_pad="10"
+    width="128">
+    Shadows:
+  </text>
+  <combo_box
+   control_name="RenderShadowDetail"
+   height="18"
+   layout="topleft"
+   left_delta="150"
+   top_delta="0"
+   name="ShadowDetail"
+   width="150">
+    <combo_box.item
+      label="None"
+      name="0"
+      value="0"/>
+    <combo_box.item
+      label="Sun/Moon"
+      name="1"
+      value="1"/>
+    <combo_box.item
+      label="Sun/Moon + Projectors"
+      name="2"
+      value="2"/>
+  </combo_box>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   top_pad="8"
+   left="160"
+   skip_link_underline="true"
+   name="settings_help"
+   width="350">
+    [secondlife:/// What do these settings mean?]
+  </text>
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="border3"
+    top_pad="10"
     left="20"
-    name="defaults_btn"
-    top_delta="50"
-    width="210">
-  </button>
+    width="540"/>
   <button
     follows="top|left"
     height="23"
-    label="Advanced Settings..."
+    label="Open Advanced Settings"
     layout="topleft"
-    left_pad="10"
+    left="160"
     name="advanced_btn"
-    top_delta="0"
+    top_pad="12"
     width="200"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_presets.xml b/indra/newview/skins/default/xui/en/panel_performance_presets.xml
new file mode 100644
index 0000000000..51516020a2
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_performance_presets.xml
@@ -0,0 +1,223 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="left|top"
+ height="490"
+ width="580"
+ name="panel_performance_presets"
+ layout="topleft"
+ left="0"
+ top="0">
+  <button
+    height="16"
+    width="16"
+    layout="topleft"
+    mouse_opaque="true"
+    follows="left|top"
+    name="back_btn"
+    top="7"
+    image_selected="Arrow_Left_Off"
+    image_pressed="Arrow_Left_Off"
+    image_unselected="Arrow_Left_Off"
+    left="15"
+    is_toggle="true">
+  </button>
+  <text
+   follows="left|top"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   top="10"
+   name="back_lbl"
+   width="40">
+    Back
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="White"
+   height="20"
+   layout="topleft"
+   left="20"
+   top_pad="10"
+   name="presets_title"
+   width="300">
+    Quick settings
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   name="presets_desc"
+   width="580">
+    Note: Quick settings will reset all manual changes you have made.
+  </text>
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="top_border"
+    top_pad="12"
+    width="540"/>
+  <button
+    follows="top|left"
+    height="23"
+    label="Social"
+    label_color="White"
+    layout="topleft"
+    name="social"
+    top_pad="14"
+    width="130">
+  </button>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="14"
+   name="social_desc1"
+   width="580">
+    Tuned for many avatars in a room.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="5"
+   name="social_desc2"
+   width="180">
+    Nearby avatar complexity is high.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   left_pad="5"
+   name="avatars_nearby_link"
+   skip_link_underline="true"
+   width="200">
+    [secondlife:/// Choose avatars to show and hide]
+  </text>
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="social_border"
+    left="20"
+    top_pad="12"
+    width="540"/>
+  <button
+    follows="top|left"
+    height="23"
+    label="Outdoors"
+    label_color="White"
+    layout="topleft"
+    name="outdoors"
+    top_pad="14"
+    width="130">
+  </button>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="14"
+   name="outdoors_desc"
+   width="580">
+    Fewer avatars, higher visibility distance.
+  </text>
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="outdoors_border"
+    top_pad="12"
+    width="540"/>
+  <button
+    follows="top|left"
+    height="23"
+    label="Maximum distance"
+    label_color="White"
+    layout="topleft"
+    name="max_distance"
+    top_pad="14"
+    width="130">
+  </button>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="14"
+   name="max_distance_desc"
+   width="580">
+    Good for zooming your camera far out and viewing large land areas.
+  </text>
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="max_distance_border"
+    top_pad="12"
+    width="540"/>
+  <button
+    follows="top|left"
+    height="23"
+    label="Photography"
+    label_color="White"
+    layout="topleft"
+    name="photography"
+    top_pad="14"
+    width="130">
+  </button>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="14"
+   name="photography_desc"
+   width="580">
+    Maximum quality, minimum visibility distance.
+  </text>
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="photography_border"
+    top_pad="12"
+    width="540"/>
+    <text
+     follows="left|top"
+     font="SansSerifSmall"
+     text_color="White"
+     height="18"
+     layout="topleft"
+     top_pad="14"
+     name="settings_desc"
+     width="110">
+    For more control, try
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   left_pad="3"
+   name="settings_link"
+   skip_link_underline="true"
+   width="200">
+    [secondlife:/// Idividual Settings]
+  </text>
+
+</panel>
-- 
cgit v1.2.3


From f33605f8b113f1fed84564c7618630acd5c9427a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 24 Jun 2021 16:17:04 +0300
Subject: SL-15297 WIP Implement performance floater - implement complexity
 bars

---
 indra/newview/llfloaterperformance.cpp             | 118 ++++++++++++++++-----
 indra/newview/llfloaterperformance.h               |   4 +
 .../skins/default/xui/en/floater_performance.xml   |   3 +
 3 files changed, 101 insertions(+), 24 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 424ca04b1f..beeebcb202 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -26,13 +26,15 @@
 #include "llviewerprecompiledheaders.h"
 #include "llfloaterperformance.h"
 
+#include "llagent.h"
+#include "llagentcamera.h"
 #include "llappearancemgr.h"
 #include "llavataractions.h"
 #include "llavatarrendernotifier.h"
 #include "llfeaturemanager.h"
+#include "llfloaterpreference.h" // LLAvatarComplexityControls
 #include "llfloaterreg.h"
 #include "llnamelistctrl.h"
-#include "llfloaterpreference.h" // LLAvatarComplexityControls
 #include "llsliderctrl.h"
 #include "lltextbox.h"
 #include "lltrans.h"
@@ -40,12 +42,16 @@
 #include "llvoavatarself.h" 
 
 const F32 REFRESH_INTERVAL = 1.0f;
-const S32 COMPLEXITY_THRESHOLD_1 = 100000;
-
+const S32 COMPLEXITY_THRESHOLD_HIGH = 100000;
+const S32 COMPLEXITY_THRESHOLD_MEDIUM = 30000;
+const S32 BAR_LEFT_PAD = 2;
+const S32 BAR_RIGHT_PAD = 5;
+const S32 BAR_BOTTOM_PAD = 9;
 
 LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
 :   LLFloater(key),
-    mUpdateTimer(new LLTimer())
+    mUpdateTimer(new LLTimer()),
+    mNearbyMaxComplexity(0)
 {
 }
 
@@ -120,6 +126,10 @@ void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
     {
         populateNearbyList();
     }
+    else if (mComplexityPanel == selected_panel)
+    {
+        populateObjectList();
+    }
 }
 
 void LLFloaterPerformance::draw()
@@ -179,6 +189,7 @@ void LLFloaterPerformance::initBackBtn(LLPanel* panel)
 
 void LLFloaterPerformance::populateHUDList()
 {
+    S32 prev_pos = mHUDList->getScrollPos();
     mHUDList->clearRows();
     mHUDList->updateColumns(true);
 
@@ -186,8 +197,14 @@ void LLFloaterPerformance::populateHUDList()
 
     hud_complexity_list_t::iterator iter = complexity_list.begin();
     hud_complexity_list_t::iterator end = complexity_list.end();
-   
+
+    U32 max_complexity = 0;
     for (; iter != end; ++iter)
+    {
+        max_complexity = llmax(max_complexity, (*iter).objectsCost);
+    }
+   
+    for (iter = complexity_list.begin(); iter != end; ++iter)
     {
         LLHUDComplexity hud_object_complexity = *iter;        
 
@@ -196,8 +213,12 @@ void LLFloaterPerformance::populateHUDList()
         item["target"] = LLNameListCtrl::SPECIAL;
         LLSD& row = item["columns"];
         row[0]["column"] = "complex_visual";
-        row[0]["type"] = "text";
-        row[0]["value"] = "*";
+        row[0]["type"] = "image";
+        LLSD& value = row[0]["value"];
+        value["ratio"] = (F32)hud_object_complexity.objectsCost / max_complexity;
+        value["bottom"] = BAR_BOTTOM_PAD;
+        value["left_pad"] = BAR_LEFT_PAD;
+        value["right_pad"] = BAR_RIGHT_PAD;
 
         row[1]["column"] = "complex_value";
         row[1]["type"] = "text";
@@ -212,12 +233,14 @@ void LLFloaterPerformance::populateHUDList()
         mHUDList->addElement(item);
     }
     mHUDList->sortByColumnIndex(1, FALSE);
+    mHUDList->setScrollPos(prev_pos);
 
     mHUDsPanel->getChild<LLTextBox>("huds_value")->setValue(std::to_string(complexity_list.size()));
 }
 
 void LLFloaterPerformance::populateObjectList()
 {
+    S32 prev_pos = mObjectList->getScrollPos();
     mObjectList->clearRows();
     mObjectList->updateColumns(true);
 
@@ -226,7 +249,13 @@ void LLFloaterPerformance::populateObjectList()
     object_complexity_list_t::iterator iter = complexity_list.begin();
     object_complexity_list_t::iterator end = complexity_list.end();
 
+    U32 max_complexity = 0;
     for (; iter != end; ++iter)
+    {
+        max_complexity = llmax(max_complexity, (*iter).objectCost);
+    }
+
+    for (iter = complexity_list.begin(); iter != end; ++iter)
     {
         LLObjectComplexity object_complexity = *iter;        
 
@@ -235,8 +264,12 @@ void LLFloaterPerformance::populateObjectList()
         item["target"] = LLNameListCtrl::SPECIAL;
         LLSD& row = item["columns"];
         row[0]["column"] = "complex_visual";
-        row[0]["type"] = "text";
-        row[0]["value"] = "*";
+        row[0]["type"] = "image";
+        LLSD& value = row[0]["value"];
+        value["ratio"] = (F32)object_complexity.objectCost / max_complexity;
+        value["bottom"] = BAR_BOTTOM_PAD;
+        value["left_pad"] = BAR_LEFT_PAD;
+        value["right_pad"] = BAR_RIGHT_PAD;
 
         row[1]["column"] = "complex_value";
         row[1]["type"] = "text";
@@ -251,30 +284,35 @@ void LLFloaterPerformance::populateObjectList()
         mObjectList->addElement(item);
     }
     mObjectList->sortByColumnIndex(1, FALSE);
+    mObjectList->setScrollPos(prev_pos);
 }
 
 void LLFloaterPerformance::populateNearbyList()
 {
+    S32 prev_pos = mNearbyList->getScrollPos();
     mNearbyList->clearRows();
     mNearbyList->updateColumns(true);
 
-    S32 avatars = 0;
     static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
+    std::vector<LLCharacter*> valid_nearby_avs;
+    getNearbyAvatars(valid_nearby_avs);
 
-    std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
-    while (char_iter != LLCharacter::sInstances.end())
+    std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
+    while (char_iter != valid_nearby_avs.end())
     {
         LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
-        if (avatar && !avatar->isDead() && !avatar->isControlAvatar() && !avatar->isSelf())
+        if (avatar)
         {
-            avatar->calculateUpdateRenderComplexity(); 
-
             LLSD item;
             item["id"] = avatar->getID();
             LLSD& row = item["columns"];
             row[0]["column"] = "complex_visual";
-            row[0]["type"] = "text";
-            row[0]["value"] = "*";
+            row[0]["type"] = "image";
+            LLSD& value = row[0]["value"];
+            value["ratio"] = (F32)avatar->getVisualComplexity() / mNearbyMaxComplexity;
+            value["bottom"] = BAR_BOTTOM_PAD;
+            value["left_pad"] = BAR_LEFT_PAD;
+            value["right_pad"] = BAR_RIGHT_PAD;
 
             row[1]["column"] = "complex_value";
             row[1]["type"] = "text";
@@ -296,6 +334,11 @@ void LLFloaterPerformance::populateNearbyList()
                     if (avatar->getVisualComplexity() > max_render_cost)
                     {
                         color = "LabelDisabledColor";
+                        LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0));
+                        if (bar)
+                        {
+                            bar->setColor(LLUIColorTable::instance().getColor(color));
+                        }
                     }
                     else if (LLAvatarActions::isFriend(avatar->getID()))
                     {
@@ -304,28 +347,55 @@ void LLFloaterPerformance::populateNearbyList()
                     name_text->setColor(LLUIColorTable::instance().getColor(color));
                 }
             }
-            avatars++;
         }
         char_iter++;
     }
-    mNearbyList->sortByColumnIndex(1, FALSE); 
+    mNearbyList->sortByColumnIndex(1, FALSE);
+    mNearbyList->setScrollPos(prev_pos);
 }
 
-void LLFloaterPerformance::updateNearbyComplexityDesc()
+void LLFloaterPerformance::getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs)
 {
-    static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); 
-    S32 max_complexity = 0;
+    static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
+    F32 radius = render_far_clip * render_far_clip;
     std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
     while (char_iter != LLCharacter::sInstances.end())
     {
         LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
         if (avatar && !avatar->isDead() && !avatar->isControlAvatar() && !avatar->isSelf())
         {
-            max_complexity = llmax(max_complexity, (S32)avatar->getVisualComplexity());
+            if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
+                (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius))
+            {
+                char_iter++;
+                continue;
+            }
+            avatar->calculateUpdateRenderComplexity();
+            mNearbyMaxComplexity = llmax(mNearbyMaxComplexity, (S32)avatar->getVisualComplexity());
+            valid_nearby_avs.push_back(*char_iter);
         }
         char_iter++;
     }
-    std::string desc = getString(max_complexity > llmin((S32)max_render_cost, COMPLEXITY_THRESHOLD_1) ? "very_high" : "medium");
+}
+
+void LLFloaterPerformance::updateNearbyComplexityDesc()
+{
+    std::string desc = getString("low");
+
+    static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
+    if (mMainPanel->getVisible())
+    {
+        std::vector<LLCharacter*> valid_nearby_avs;
+        getNearbyAvatars(valid_nearby_avs);
+    }
+    if (mNearbyMaxComplexity > COMPLEXITY_THRESHOLD_HIGH)
+    {
+        desc = getString("very_high");
+    }
+    else if (mNearbyMaxComplexity > COMPLEXITY_THRESHOLD_MEDIUM)
+    {
+        desc = getString("medium");
+    }
    
     if (mMainPanel->getVisible())
     {
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 7aec7c3f6c..ea15873b95 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -28,6 +28,7 @@
 
 #include "llfloater.h"
 
+class LLCharacter;
 class LLNameListCtrl;
 
 class LLFloaterPerformance : public LLFloater
@@ -57,6 +58,7 @@ private:
     void updateMaxComplexity();
     void updateComplexityText();
 
+    void getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs);
     void updateNearbyComplexityDesc();
 
     LLPanel* mMainPanel;
@@ -72,6 +74,8 @@ private:
 
     LLTimer* mUpdateTimer;
 
+    S32 mNearbyMaxComplexity;
+
     boost::signals2::connection	mComplexityChangedSignal;
 };
 
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index e415ac5be0..4cd3c7a603 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -12,6 +12,9 @@
   <string
      name="medium"
      value="medium"/>
+  <string
+    name="low"
+    value="low"/>
   <panel
    bevel_style="none"
    follows="left|top"
-- 
cgit v1.2.3


From 74c6580e5c3507ef72590a3543e2b0b2ee9c13a3 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 25 Jun 2021 20:05:07 +0300
Subject: SL-15297 WIP restore selection after updating the list & don't show
 avatars in the list as disabled when complexity is not limited

---
 indra/newview/llfloaterperformance.cpp             | 14 +++++++----
 indra/newview/llnamelistctrl.cpp                   | 28 ++++++++++++++++++++++
 indra/newview/llnamelistctrl.h                     |  3 +++
 indra/newview/skins/default/colors.xml             |  5 +---
 .../default/xui/en/floater_add_payment_method.xml  |  2 +-
 .../skins/default/xui/en/floater_performance.xml   | 12 +++++-----
 6 files changed, 49 insertions(+), 15 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index beeebcb202..b8adf7fedc 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -190,6 +190,7 @@ void LLFloaterPerformance::initBackBtn(LLPanel* panel)
 void LLFloaterPerformance::populateHUDList()
 {
     S32 prev_pos = mHUDList->getScrollPos();
+    LLUUID prev_selected_id = mHUDList->getSelectedSpecialId();
     mHUDList->clearRows();
     mHUDList->updateColumns(true);
 
@@ -213,7 +214,7 @@ void LLFloaterPerformance::populateHUDList()
         item["target"] = LLNameListCtrl::SPECIAL;
         LLSD& row = item["columns"];
         row[0]["column"] = "complex_visual";
-        row[0]["type"] = "image";
+        row[0]["type"] = "bar";
         LLSD& value = row[0]["value"];
         value["ratio"] = (F32)hud_object_complexity.objectsCost / max_complexity;
         value["bottom"] = BAR_BOTTOM_PAD;
@@ -234,6 +235,7 @@ void LLFloaterPerformance::populateHUDList()
     }
     mHUDList->sortByColumnIndex(1, FALSE);
     mHUDList->setScrollPos(prev_pos);
+    mHUDList->selectItemBySpecialId(prev_selected_id);
 
     mHUDsPanel->getChild<LLTextBox>("huds_value")->setValue(std::to_string(complexity_list.size()));
 }
@@ -241,6 +243,7 @@ void LLFloaterPerformance::populateHUDList()
 void LLFloaterPerformance::populateObjectList()
 {
     S32 prev_pos = mObjectList->getScrollPos();
+    LLUUID prev_selected_id = mObjectList->getSelectedSpecialId();
     mObjectList->clearRows();
     mObjectList->updateColumns(true);
 
@@ -264,7 +267,7 @@ void LLFloaterPerformance::populateObjectList()
         item["target"] = LLNameListCtrl::SPECIAL;
         LLSD& row = item["columns"];
         row[0]["column"] = "complex_visual";
-        row[0]["type"] = "image";
+        row[0]["type"] = "bar";
         LLSD& value = row[0]["value"];
         value["ratio"] = (F32)object_complexity.objectCost / max_complexity;
         value["bottom"] = BAR_BOTTOM_PAD;
@@ -285,11 +288,13 @@ void LLFloaterPerformance::populateObjectList()
     }
     mObjectList->sortByColumnIndex(1, FALSE);
     mObjectList->setScrollPos(prev_pos);
+    mObjectList->selectItemBySpecialId(prev_selected_id);
 }
 
 void LLFloaterPerformance::populateNearbyList()
 {
     S32 prev_pos = mNearbyList->getScrollPos();
+    LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem();
     mNearbyList->clearRows();
     mNearbyList->updateColumns(true);
 
@@ -307,7 +312,7 @@ void LLFloaterPerformance::populateNearbyList()
             item["id"] = avatar->getID();
             LLSD& row = item["columns"];
             row[0]["column"] = "complex_visual";
-            row[0]["type"] = "image";
+            row[0]["type"] = "bar";
             LLSD& value = row[0]["value"];
             value["ratio"] = (F32)avatar->getVisualComplexity() / mNearbyMaxComplexity;
             value["bottom"] = BAR_BOTTOM_PAD;
@@ -331,7 +336,7 @@ void LLFloaterPerformance::populateNearbyList()
                 if (name_text)
                 {
                     std::string color = "white";
-                    if (avatar->getVisualComplexity() > max_render_cost)
+                    if ((max_render_cost != 0) && (avatar->getVisualComplexity() > max_render_cost))
                     {
                         color = "LabelDisabledColor";
                         LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0));
@@ -352,6 +357,7 @@ void LLFloaterPerformance::populateNearbyList()
     }
     mNearbyList->sortByColumnIndex(1, FALSE);
     mNearbyList->setScrollPos(prev_pos);
+    mNearbyList->selectByID(prev_selected_id);
 }
 
 void LLFloaterPerformance::getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs)
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index e1bf9b1a17..92805e03f0 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -464,6 +464,34 @@ LLScrollListItem* LLNameListCtrl::getNameItemByAgentId(const LLUUID& agent_id)
 	return NULL;
 }
 
+void LLNameListCtrl::selectItemBySpecialId(const LLUUID& special_id)
+{
+    if (special_id.isNull())
+    {
+        return;
+    }
+
+    for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++)
+    {
+        LLNameListItem* item = dynamic_cast<LLNameListItem*>(*it);
+        if (item && item->getSpecialID() == special_id)
+        {
+            item->setSelected(TRUE);
+            break;
+        }
+    }
+}
+
+LLUUID LLNameListCtrl::getSelectedSpecialId()
+{
+    LLNameListItem* item = dynamic_cast<LLNameListItem*>(getFirstSelected());
+    if(item)
+    {
+        return item->getSpecialID();
+    }
+    return LLUUID();
+}
+
 void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
 									   const LLAvatarName& av_name,
 									   std::string suffix,
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 1a31b1cc10..d7e991c94d 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -162,6 +162,9 @@ public:
 
 	LLScrollListItem* getNameItemByAgentId(const LLUUID& agent_id);
 
+    void selectItemBySpecialId(const LLUUID& special_id);
+    LLUUID getSelectedSpecialId();
+
 	// LLView interface
 	/*virtual*/ BOOL	handleDragAndDrop(S32 x, S32 y, MASK mask,
 									  BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 9fcb6edca4..e8d3c12d39 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -967,10 +967,7 @@
     name="OutfitGalleryItemUnselected"
     value="0.4 0.4 0.4 1" />
   <color
-    name="AddPaymentPanel"
-    value="0.27 0.27 0.27 1" />
-  <color
-    name="PerformanceFloaterGray"
+    name="PanelGray"
     value="0.27 0.27 0.27 1" />
   <color
     name="PerformanceMid"
diff --git a/indra/newview/skins/default/xui/en/floater_add_payment_method.xml b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml
index 1f980564d4..ac88263aa1 100644
--- a/indra/newview/skins/default/xui/en/floater_add_payment_method.xml
+++ b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml
@@ -19,7 +19,7 @@
   </floater.string>
   <panel
    background_opaque="false"
-   bg_alpha_color="AddPaymentPanel"
+   bg_alpha_color="PanelGray"
    border_visible="false"
    background_visible="true"
    label="wrapper_panel"
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index 4cd3c7a603..039421d589 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -75,7 +75,7 @@
    left="0"   
    top="60">
     <panel
-     bg_alpha_color="PerformanceFloaterGray"
+     bg_alpha_color="PanelGray"
      background_visible="true"
      background_opaque="false"
      border="true"
@@ -122,7 +122,7 @@
        right="-20"/>
     </panel>
     <panel
-     bg_alpha_color="PerformanceFloaterGray"
+     bg_alpha_color="PanelGray"
      background_visible="true"
      background_opaque="false"
      border="true"
@@ -168,7 +168,7 @@
          right="-20"/>
       </panel>
     <panel
-     bg_alpha_color="PerformanceFloaterGray"
+     bg_alpha_color="PanelGray"
      background_visible="true"
      background_opaque="false"
      border="true"
@@ -225,7 +225,7 @@
        right="-20"/>
     </panel>
     <panel
-     bg_alpha_color="PerformanceFloaterGray"
+     bg_alpha_color="PanelGray"
      background_visible="true"
      background_opaque="false"
      border="true"
@@ -282,7 +282,7 @@
        right="-20"/>
     </panel>
     <panel
-     bg_alpha_color="PerformanceFloaterGray"
+     bg_alpha_color="PanelGray"
      background_visible="true"
      background_opaque="false"
      border="true"
@@ -339,7 +339,7 @@
        right="-20"/>
     </panel>
     <panel
-     bg_alpha_color="PerformanceFloaterGray"
+     bg_alpha_color="PanelGray"
      background_visible="true"
      background_opaque="false"
      border="true"
-- 
cgit v1.2.3


From 54ffa6a23d093af8932f8978d3c1a420153f7997 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 29 Jun 2021 18:34:18 +0300
Subject: SL-15297 WIP update Individual settings panel & correctly show avatar
 state in the list

---
 indra/newview/llfloaterperformance.cpp             |   8 +-
 .../xui/en/panel_performance_preferences.xml       | 144 ++++++++++++++++++---
 2 files changed, 131 insertions(+), 21 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index b8adf7fedc..16afeb6e52 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -306,7 +306,7 @@ void LLFloaterPerformance::populateNearbyList()
     while (char_iter != valid_nearby_avs.end())
     {
         LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
-        if (avatar)
+        if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))
         {
             LLSD item;
             item["id"] = avatar->getID();
@@ -336,7 +336,7 @@ void LLFloaterPerformance::populateNearbyList()
                 if (name_text)
                 {
                     std::string color = "white";
-                    if ((max_render_cost != 0) && (avatar->getVisualComplexity() > max_render_cost))
+                    if (LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance())
                     {
                         color = "LabelDisabledColor";
                         LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0));
@@ -345,9 +345,9 @@ void LLFloaterPerformance::populateNearbyList()
                             bar->setColor(LLUIColorTable::instance().getColor(color));
                         }
                     }
-                    else if (LLAvatarActions::isFriend(avatar->getID()))
+                    else if (LLVOAvatar::AOA_NORMAL == avatar->getOverallAppearance())
                     {
-                        color = "ConversationFriendColor";
+                        color =  LLAvatarActions::isFriend(avatar->getID()) ? "ConversationFriendColor" : "white";
                     }
                     name_text->setColor(LLUIColorTable::instance().getColor(color));
                 }
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index ec1b624f13..b5cc2a29ed 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="510"
+ height="520"
  width="580"
  name="panel_performance_preferences"
  layout="topleft"
@@ -57,7 +57,7 @@
    text_color="White"
    height="18"
    layout="topleft"
-   top_pad="20"
+   top_pad="30"
    name="quality_lbl"
    width="100">
     Graphics quality
@@ -74,21 +74,60 @@ shortcuts
    width="40">
     Fastest
   </text>
-  <slider
-    control_name="RenderQualityPerformance"
-    decimal_digits="0"
-    follows="left|top"
-    height="16"
-    increment="1"
-    initial_value="0"
-    layout="topleft"
-    left_pad="5"
-    max_val="6"
-    name="graphics_quality"
-    show_text="false"
-    top_delta="-1"
-    width="275">
-  </slider>
+  <radio_group
+   control_name="RenderQualityPerformance"
+   follows="top|left"
+   draw_border="false"
+   height="25"
+   layout="topleft"
+   left_pad="5"
+   name="graphics_quality"
+   top_delta="0"
+   width="243">
+    <radio_item
+     height="16"
+     layout="topleft"
+     left="3"
+     name="0"
+     top="0"
+     width="7" />
+    <radio_item
+     height="16"
+     layout="topleft"
+     left_pad="30"
+     name="1"
+     width="7" />
+    <radio_item
+     height="16"
+     layout="topleft"
+     left_pad="30"
+     name="2"
+     width="7" />
+    <radio_item
+     height="16"
+     layout="topleft"
+     left_pad="30"
+     name="3"
+     width="7" />
+    <radio_item
+     height="16"
+     layout="topleft"
+     left_pad="30"
+     name="4"
+     width="7" />
+    <radio_item
+     height="16"
+     layout="topleft"
+     left_pad="30"
+     name="5"
+     width="7" />
+    <radio_item
+     height="16"
+     layout="topleft"
+     left_pad="30"
+     name="6"
+     width="7" />
+  </radio_group>
   <text
    follows="left|top"
    font="SansSerifSmall"
@@ -383,4 +422,75 @@ shortcuts
     name="advanced_btn"
     top_pad="12"
     width="200"/>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   top="78"
+   left="213"
+   name="1_lbl"
+   width="7">
+    1
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   left_pad="31"
+   name="2_lbl"
+   width="7">
+    2
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   left_pad="30"
+   name="3_lbl"
+   width="7">
+    3
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   left_pad="30"
+   name="4_lbl"
+   width="7">
+    4
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   left_pad="30"
+   name="5_lbl"
+   width="7">
+    5
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   left_pad="30"
+   name="6_lbl"
+   width="7">
+      6
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   left_pad="30"
+   name="7_lbl"
+   width="7">
+    7
+  </text>
 </panel>
-- 
cgit v1.2.3


From 77aac9579170369a11f0884e16bd730f8cbb8bdb Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 14 Jul 2021 14:49:43 +0300
Subject: SL-15297 performance floater ui update

---
 indra/newview/llfloateravatarrendersettings.cpp    |  37 +---
 indra/newview/llfloateravatarrendersettings.h      |   4 -
 indra/newview/llfloaterperformance.cpp             | 178 +++++++++++-----
 indra/newview/llfloaterperformance.h               |  12 +-
 .../xui/en/floater_avatar_render_settings.xml      |  66 +++---
 .../skins/default/xui/en/floater_performance.xml   | 217 ++++----------------
 .../xui/en/menu_avatar_rendering_settings.xml      |  25 +--
 .../xui/en/menu_avatar_rendering_settings_add.xml  |   4 +-
 .../xui/en/panel_performance_complexity.xml        |   6 +-
 .../default/xui/en/panel_performance_huds.xml      |  17 +-
 .../default/xui/en/panel_performance_nearby.xml    |  18 +-
 .../xui/en/panel_performance_preferences.xml       | 186 +++++++++++------
 .../default/xui/en/panel_performance_presets.xml   | 223 ---------------------
 .../xui/en/panel_performance_troubleshooting.xml   | 190 ------------------
 14 files changed, 372 insertions(+), 811 deletions(-)
 delete mode 100644 indra/newview/skins/default/xui/en/panel_performance_presets.xml
 delete mode 100644 indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml

(limited to 'indra/newview')

diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp
index b8f854feb3..7d098e6c88 100644
--- a/indra/newview/llfloateravatarrendersettings.cpp
+++ b/indra/newview/llfloateravatarrendersettings.cpp
@@ -89,7 +89,6 @@ BOOL LLFloaterAvatarRenderSettings::postBuild()
     LLFloater::postBuild();
     mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list");
     mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3));
-    getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2));
 
 	return TRUE;
 }
@@ -133,37 +132,13 @@ void LLFloaterAvatarRenderSettings::updateList()
     {
         item_params.value = iter->first;
         LLAvatarNameCache::get(iter->first, &av_name);
-        if(!isHiddenRow(av_name.getCompleteName()))
-        {
-            item_params.columns.add().value(av_name.getCompleteName()).column("name");
-            std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
-            item_params.columns.add().value(setting).column("setting");
-            std::string timestamp = createTimestamp(LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first));
-            item_params.columns.add().value(timestamp).column("timestamp");
-            mAvatarSettingsList->addNameItemRow(item_params);
-        }
+        item_params.columns.add().value(av_name.getCompleteName()).column("name");
+        std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
+        item_params.columns.add().value(setting).column("setting");
+        mAvatarSettingsList->addNameItemRow(item_params);
     }
 }
 
-void LLFloaterAvatarRenderSettings::onFilterEdit(const std::string& search_string)
-{
-    std::string filter_upper = search_string;
-    LLStringUtil::toUpper(filter_upper);
-    if (mNameFilter != filter_upper)
-    {
-        mNameFilter = filter_upper;
-        mNeedsUpdate = true;
-    }
-}
-
-bool LLFloaterAvatarRenderSettings::isHiddenRow(const std::string& av_name)
-{
-    if (mNameFilter.empty()) return false;
-    std::string upper_name = av_name;
-    LLStringUtil::toUpper(upper_name);
-    return std::string::npos == upper_name.find(mNameFilter);
-}
-
 static LLVOAvatar* find_avatar(const LLUUID& id)
 {
     LLViewerObject *obj = gObjectList.findObject(id);
@@ -214,6 +189,10 @@ bool LLFloaterAvatarRenderSettings::isActionChecked(const LLSD& userdata, const
     {
         return (visual_setting == S32(LLVOAvatar::AV_RENDER_NORMALLY));
     }
+    else if ("non_default" == command_name)
+    {
+        return (visual_setting != S32(LLVOAvatar::AV_RENDER_NORMALLY));
+    }
     else if ("never" == command_name)
     {
         return (visual_setting == S32(LLVOAvatar::AV_DO_NOT_RENDER));
diff --git a/indra/newview/llfloateravatarrendersettings.h b/indra/newview/llfloateravatarrendersettings.h
index 00ee074f17..2e0a844afd 100644
--- a/indra/newview/llfloateravatarrendersettings.h
+++ b/indra/newview/llfloateravatarrendersettings.h
@@ -48,7 +48,6 @@ public:
     void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
 
     void updateList();
-    void onFilterEdit(const std::string& search_string);
     void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
     bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
     void onClickAdd(const LLSD& userdata);
@@ -59,15 +58,12 @@ public:
     static void setNeedsUpdate();
 
 private:
-    bool isHiddenRow(const std::string& av_name);
     void callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting);
     void removePicker();
 
     bool mNeedsUpdate;
     LLListContextMenu* mContextMenu;
     LLNameListCtrl* mAvatarSettingsList;
-
-    std::string mNameFilter;
 };
 
 
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 16afeb6e52..a2fb8c130d 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -31,6 +31,7 @@
 #include "llappearancemgr.h"
 #include "llavataractions.h"
 #include "llavatarrendernotifier.h"
+#include "llcheckboxctrl.h"
 #include "llfeaturemanager.h"
 #include "llfloaterpreference.h" // LLAvatarComplexityControls
 #include "llfloaterreg.h"
@@ -38,52 +39,69 @@
 #include "llsliderctrl.h"
 #include "lltextbox.h"
 #include "lltrans.h"
+#include "llviewerobjectlist.h"
 #include "llvoavatar.h"
 #include "llvoavatarself.h" 
+#include "pipeline.h"
 
 const F32 REFRESH_INTERVAL = 1.0f;
-const S32 COMPLEXITY_THRESHOLD_HIGH = 100000;
-const S32 COMPLEXITY_THRESHOLD_MEDIUM = 30000;
 const S32 BAR_LEFT_PAD = 2;
 const S32 BAR_RIGHT_PAD = 5;
 const S32 BAR_BOTTOM_PAD = 9;
 
+class LLExceptionsContextMenu : public LLListContextMenu
+{
+public:
+    LLExceptionsContextMenu(LLFloaterPerformance* floater_settings)
+        :   mFloaterPerformance(floater_settings)
+    {}
+protected:
+    LLContextMenu* createMenu()
+    {
+        LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+        LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+        registrar.add("Settings.SetRendering", boost::bind(&LLFloaterPerformance::onCustomAction, mFloaterPerformance, _2, mUUIDs.front()));
+        enable_registrar.add("Settings.IsSelected", boost::bind(&LLFloaterPerformance::isActionChecked, mFloaterPerformance, _2, mUUIDs.front()));
+        LLContextMenu* menu = createFromFile("menu_avatar_rendering_settings.xml");
+
+        return menu;
+    }
+
+    LLFloaterPerformance* mFloaterPerformance;
+};
+
 LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
 :   LLFloater(key),
     mUpdateTimer(new LLTimer()),
     mNearbyMaxComplexity(0)
 {
+    mContextMenu = new LLExceptionsContextMenu(this);
 }
 
 LLFloaterPerformance::~LLFloaterPerformance()
 {
     mComplexityChangedSignal.disconnect();
+    delete mContextMenu;
     delete mUpdateTimer;
 }
 
 BOOL LLFloaterPerformance::postBuild()
 {
     mMainPanel = getChild<LLPanel>("panel_performance_main");
-    mTroubleshootingPanel = getChild<LLPanel>("panel_performance_troubleshooting");
     mNearbyPanel = getChild<LLPanel>("panel_performance_nearby");
     mComplexityPanel = getChild<LLPanel>("panel_performance_complexity");
     mSettingsPanel = getChild<LLPanel>("panel_performance_preferences");
     mHUDsPanel = getChild<LLPanel>("panel_performance_huds");
-    mPresetsPanel = getChild<LLPanel>("panel_performance_presets");
 
-    getChild<LLPanel>("troubleshooting_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mTroubleshootingPanel));
     getChild<LLPanel>("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel));
     getChild<LLPanel>("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel));
     getChild<LLPanel>("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel));
     getChild<LLPanel>("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel));
-    getChild<LLPanel>("presets_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mPresetsPanel));
 
-    initBackBtn(mTroubleshootingPanel);
     initBackBtn(mNearbyPanel);
     initBackBtn(mComplexityPanel);
     initBackBtn(mSettingsPanel);
     initBackBtn(mHUDsPanel);
-    initBackBtn(mPresetsPanel);
 
     mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");
     mHUDList->setNameListType(LLNameListCtrl::SPECIAL);
@@ -96,12 +114,12 @@ BOOL LLFloaterPerformance::postBuild()
     mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
 
     mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
+    mSettingsPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this));
+    mSettingsPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR));
 
     mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
     mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
-
-    mPresetsPanel->getChild<LLTextBox>("avatars_nearby_link")->setURLClickedCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel));
-    mPresetsPanel->getChild<LLTextBox>("settings_link")->setURLClickedCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel));
+    mNearbyList->setRightMouseDownCallback(boost::bind(&LLFloaterPerformance::onAvatarListRightClick, this, _1, _2, _3));
 
     updateComplexityText();
     mComplexityChangedSignal = gSavedSettings.getControl("IndirectMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this));
@@ -134,28 +152,27 @@ void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
 
 void LLFloaterPerformance::draw()
 {
+    const S32 NUM_PERIODS = 50;
+
     if (mUpdateTimer->hasExpired())
     {
-        getChild<LLTextBox>("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS)));
-        if (mMainPanel->getVisible())
-        {
-            mMainPanel->getChild<LLTextBox>("huds_value")->setValue(LLHUDRenderNotifier::getInstance()->getHUDsCount());
-            mMainPanel->getChild<LLTextBox>("complexity_value")->setValue((S32)gAgentAvatarp->getVisualComplexity());
-            updateNearbyComplexityDesc();
-        }
-        else if (mHUDsPanel->getVisible())
+        getChild<LLTextBox>("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS, NUM_PERIODS)));
+        if (mHUDsPanel->getVisible())
         {
             populateHUDList();
         }
         else if (mNearbyPanel->getVisible())
         {
             populateNearbyList();
-            updateNearbyComplexityDesc();
         }
         else if (mComplexityPanel->getVisible())
         {
             populateObjectList();
         }
+        else if (mSettingsPanel->getVisible())
+        {
+            mSettingsPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR));
+        }
 
         mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL);
     }
@@ -170,12 +187,10 @@ void LLFloaterPerformance::showMainPanel()
 
 void LLFloaterPerformance::hidePanels()
 {
-    mTroubleshootingPanel->setVisible(FALSE);
     mNearbyPanel->setVisible(FALSE);
     mComplexityPanel->setVisible(FALSE);
     mHUDsPanel->setVisible(FALSE);
     mSettingsPanel->setVisible(FALSE);
-    mPresetsPanel->setVisible(FALSE);
 }
 
 void LLFloaterPerformance::initBackBtn(LLPanel* panel)
@@ -236,8 +251,6 @@ void LLFloaterPerformance::populateHUDList()
     mHUDList->sortByColumnIndex(1, FALSE);
     mHUDList->setScrollPos(prev_pos);
     mHUDList->selectItemBySpecialId(prev_selected_id);
-
-    mHUDsPanel->getChild<LLTextBox>("huds_value")->setValue(std::to_string(complexity_list.size()));
 }
 
 void LLFloaterPerformance::populateObjectList()
@@ -384,32 +397,6 @@ void LLFloaterPerformance::getNearbyAvatars(std::vector<LLCharacter*> &valid_nea
     }
 }
 
-void LLFloaterPerformance::updateNearbyComplexityDesc()
-{
-    std::string desc = getString("low");
-
-    static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
-    if (mMainPanel->getVisible())
-    {
-        std::vector<LLCharacter*> valid_nearby_avs;
-        getNearbyAvatars(valid_nearby_avs);
-    }
-    if (mNearbyMaxComplexity > COMPLEXITY_THRESHOLD_HIGH)
-    {
-        desc = getString("very_high");
-    }
-    else if (mNearbyMaxComplexity > COMPLEXITY_THRESHOLD_MEDIUM)
-    {
-        desc = getString("medium");
-    }
-   
-    if (mMainPanel->getVisible())
-    {
-        mMainPanel->getChild<LLTextBox>("avatars_nearby_value")->setValue(desc);
-    }
-    mNearbyPanel->getChild<LLTextBox>("av_nearby_value")->setValue(desc);
-}
-
 void LLFloaterPerformance::detachItem(const LLUUID& item_id)
 {
     LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
@@ -425,6 +412,11 @@ void LLFloaterPerformance::onClickAdvanced()
     LLFloaterReg::showInstance("prefs_graphics_advanced");
 }
 
+void LLFloaterPerformance::onClickHideAvatars()
+{
+    LLPipeline::toggleRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR);
+}
+
 void LLFloaterPerformance::onClickExceptions()
 {
     LLFloaterReg::showInstance("avatar_render_settings");
@@ -443,4 +435,90 @@ void LLFloaterPerformance::updateComplexityText()
         mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText", true));
 }
 
+static LLVOAvatar* find_avatar(const LLUUID& id)
+{
+    LLViewerObject *obj = gObjectList.findObject(id);
+    while (obj && obj->isAttachment())
+    {
+        obj = (LLViewerObject *)obj->getParent();
+    }
+
+    if (obj && obj->isAvatar())
+    {
+        return (LLVOAvatar*)obj;
+    }
+    else
+    {
+        return NULL;
+    }
+}
+
+void LLFloaterPerformance::onCustomAction(const LLSD& userdata, const LLUUID& av_id)
+{
+    const std::string command_name = userdata.asString();
+
+    S32 new_setting = 0;
+    if ("default" == command_name)
+    {
+        new_setting = S32(LLVOAvatar::AV_RENDER_NORMALLY);
+    }
+    else if ("never" == command_name)
+    {
+        new_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER);
+    }
+    else if ("always" == command_name)
+    {
+        new_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER);
+    }
+
+    LLVOAvatar *avatarp = find_avatar(av_id);
+    if (avatarp)
+    {
+        avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting));
+    }
+    else
+    {
+        LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting);
+    }
+}
+
+
+bool LLFloaterPerformance::isActionChecked(const LLSD& userdata, const LLUUID& av_id)
+{
+    const std::string command_name = userdata.asString();
+
+    S32 visual_setting = LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(av_id);
+    if ("default" == command_name)
+    {
+        return (visual_setting == S32(LLVOAvatar::AV_RENDER_NORMALLY));
+    }
+    else if ("non_default" == command_name)
+    {
+        return (visual_setting != S32(LLVOAvatar::AV_RENDER_NORMALLY));
+    }
+    else if ("never" == command_name)
+    {
+        return (visual_setting == S32(LLVOAvatar::AV_DO_NOT_RENDER));
+    }
+    else if ("always" == command_name)
+    {
+        return (visual_setting == S32(LLVOAvatar::AV_ALWAYS_RENDER));
+    }
+    return false;
+}
+
+void LLFloaterPerformance::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
+{
+    LLNameListCtrl* list = dynamic_cast<LLNameListCtrl*>(ctrl);
+    if (!list) return;
+    list->selectItemAt(x, y, MASK_NONE);
+    uuid_vec_t selected_uuids;
+
+    if(list->getCurrentID().notNull())
+    {
+        selected_uuids.push_back(list->getCurrentID());
+        mContextMenu->show(ctrl, selected_uuids, x, y);
+    }
+}
+
 // EOF
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index ea15873b95..58f9447d4c 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -27,6 +27,7 @@
 #define LL_LLFLOATERPERFORMANCE_H
 
 #include "llfloater.h"
+#include "lllistcontextmenu.h"
 
 class LLCharacter;
 class LLNameListCtrl;
@@ -46,6 +47,11 @@ public:
 
     void detachItem(const LLUUID& item_id);
 
+    void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
+
+    void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
+    bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
+
 private:
     void initBackBtn(LLPanel* panel);
     void populateHUDList();
@@ -53,25 +59,25 @@ private:
     void populateNearbyList();
 
     void onClickAdvanced();
+    void onClickHideAvatars();
     void onClickExceptions();
 
     void updateMaxComplexity();
     void updateComplexityText();
 
     void getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs);
-    void updateNearbyComplexityDesc();
 
     LLPanel* mMainPanel;
-    LLPanel* mTroubleshootingPanel;
     LLPanel* mNearbyPanel;
     LLPanel* mComplexityPanel;
     LLPanel* mHUDsPanel;
     LLPanel* mSettingsPanel;
-    LLPanel* mPresetsPanel;
     LLNameListCtrl* mHUDList;
     LLNameListCtrl* mObjectList;
     LLNameListCtrl* mNearbyList;
 
+    LLListContextMenu* mContextMenu;
+
     LLTimer* mUpdateTimer;
 
     S32 mNearbyMaxComplexity;
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
index e088d4d2a1..d222dca98b 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
@@ -10,7 +10,7 @@
  save_rect="true"
  single_instance="true"
  reuse_instance="true"
- title="AVATAR RENDER SETTINGS"
+ title="AVATAR DISPLAY EXCEPTIONS"
  width="300">
     <string
      name="av_never_render"
@@ -18,53 +18,45 @@
     <string
      name="av_always_render"
      value="Always"/>
-    <filter_editor
-     follows="left|top|right"
-     height="23"
-     layout="topleft"
-     left="8"
-     right="-47"
-     label="Filter People"
-     max_length_chars="300"
-     name="people_filter_input"
-     text_color="Black"
-     text_pad_left="10"
-     top="4" />
-    <menu_button
-     follows="top|right"
-     height="25"
-     image_hover_unselected="Toolbar_Middle_Over"
-     image_overlay="AddItem_Off"
-     image_selected="Toolbar_Middle_Selected"
-     image_unselected="Toolbar_Middle_Off"
-     layout="topleft"
-     left_pad="7"
-     menu_filename="menu_avatar_rendering_settings_add.xml"
-     menu_position="bottomleft"
-     name="plus_btn"
-     tool_tip="Actions on selected person"
-     top="3"
-     width="31" />
     <name_list
-     bottom="-8"
+     bottom="-33"
      draw_heading="true"
      follows="all"
      left="8"
      multi_select="false"
      name="render_settings_list"
      right="-8"
-     top="32">
+     top="0">
         <name_list.columns
          label="Name"
          name="name"
-         relative_width="0.5" />
+         relative_width="0.65" />
         <name_list.columns
-         label="Render setting"
+         label="Full detail"
          name="setting"
-         relative_width="0.25" />
-        <name_list.columns
-         label="Date added"
-         name="timestamp"
-         relative_width="0.25" />
+         relative_width="0.35" />
      </name_list>
+    <panel
+     bg_alpha_color="ScrollBgWriteableColor"
+     background_visible="true"
+     background_opaque="false"
+     bevel_style="none"
+     follows="bottom|left|right"
+     name="add_subpanel"
+     layout="topleft"
+     height="28"
+     top_pad="0">
+     <menu_button
+       follows="bottom|left"
+       height="25"
+       label="Add someone..."
+       layout="topleft"
+       menu_filename="menu_avatar_rendering_settings_add.xml"
+       menu_position="bottomleft"
+       name="plus_btn"
+       tool_tip="Actions on selected person"
+       top="1"
+       left="8"
+       width="120" />
+     </panel>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index 039421d589..210b2f8792 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -1,20 +1,11 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- height="590"
+ height="692"
  layout="topleft"
  name="performance"
  save_rect="true"
  title="IMPROVE GRAPHICS SPEED"
  width="580">
-  <string
-     name="very_high"
-     value="very high"/>
-  <string
-     name="medium"
-     value="medium"/>
-  <string
-    name="low"
-    value="low"/>
   <panel
    bevel_style="none"
    follows="left|top"
@@ -57,70 +48,44 @@
        height="20"
        layout="topleft"
        left_pad="0"
-       top="14"
+       top="13"
        name="fps_lbl"
        width="450">
-          FPS -- 60 or more for the best experience
-      </text>    
-    </panel>
-  </panel>
-  <panel
-   bevel_style="none"
-   follows="left|top"
-   height="540"
-   width="580"
-   name="panel_performance_main"
-   visible="true"
-   layout="topleft"
-   left="0"   
-   top="60">
-    <panel
-     bg_alpha_color="PanelGray"
-     background_visible="true"
-     background_opaque="false"
-     border="true"
-     bevel_style="none"
-     follows="left|top"
-     height="60"
-     width="560"
-     name="presets_subpanel"
-     layout="topleft"
-     left="10"
-     top="5">
+          frames per second
+      </text>
       <text
        follows="left|top"
-       font="SansSerifLarge"
        text_color="White"
        height="20"
        layout="topleft"
-       left="10"
-       name="presets_lbl"
-       top="12"
-       width="395">
-          Quick settings for common situations
+       left="395"
+       top="7"
+       name="fps_desc1_lbl"
+       width="150">
+        Allow 5-10 seconds for
       </text>
       <text
        follows="left|top"
-       font="SansSerif"
        text_color="White"
        height="20"
        layout="topleft"
-       left="10"
-       name="presets_desc"
-       top_pad="5"
-       width="395">
-          Choose settings for parties, exploration, photography, and more.
+       top_pad="-3"
+       name="fps_desc2_lbl"
+       width="150">
+        changes to take full effect.
       </text>
-      <icon
-       height="16"
-       width="16"
-       image_name="Arrow_Right_Off"
-       mouse_opaque="true"
-       name="icon_arrow1"
-       follows="right|top"
-       top="24"
-       right="-20"/>
     </panel>
+  </panel>
+  <panel
+   bevel_style="none"
+   follows="left|top"
+   height="540"
+   width="580"
+   name="panel_performance_main"
+   visible="true"
+   layout="topleft"
+   left="0"   
+   top="60">    
     <panel
      bg_alpha_color="PanelGray"
      background_visible="true"
@@ -128,11 +93,12 @@
      border="true"
      bevel_style="none"
      follows="left|top"
-     height="60"
+     height="70"
      width="560"
      name="settings_subpanel"
      layout="topleft"
-     top_pad="20">
+     left="10"
+     top="5">
         <text
          follows="left|top"
          font="SansSerifLarge"
@@ -143,7 +109,7 @@
          name="settings_lbl"
          top="12"
          width="180">
-          Individual settings
+          Graphics settings
         </text>
         <text
          follows="left|top"
@@ -153,9 +119,9 @@
          layout="topleft"
          left="10"
          name="settings_desc"
-         top_pad="5"
+         top_pad="10"
          width="395">
-          More control over quality, visibility distance, and enhancements.
+          Choose settings for distance, water, lighting and more.
         </text>
         <icon
          height="16"
@@ -164,7 +130,7 @@
          mouse_opaque="true"
          name="icon_arrow3"
          follows="right|top"
-         top="24"
+         top="29"
          right="-20"/>
       </panel>
     <panel
@@ -174,7 +140,7 @@
      border="true"
      bevel_style="none"
      follows="left|top"
-     height="60"
+     height="70"
      width="560"
      name="nearby_subpanel"
      layout="topleft"
@@ -189,18 +155,7 @@
        name="avatars_nearby_lbl"
        top="12"
        width="205">
-          Nearby avatar complexity is
-      </text>
-      <text
-       follows="left|top"
-       font="SansSerifLarge"
-       text_color="PerformanceMid"
-       height="20"
-       layout="topleft"
-       left_pad="2"
-       name="avatars_nearby_value"
-       width="100">
-          very high
+          Avatars nearby
       </text>
       <text
        follows="left|top"
@@ -210,9 +165,9 @@
        layout="topleft"
        left="10"
        name="avatars_nearby_desc"
-       top_pad="5"
+       top_pad="10"
        width="395">
-          Choose which avatars are not displayed in detail, to increase FPS.
+          Manage which nearby avatars are fully displayed.
       </text>
       <icon
        height="16"
@@ -221,7 +176,7 @@
        mouse_opaque="true"
        name="icon_arrow2"
        follows="right|top"
-       top="24"
+       top="29"
        right="-20"/>
     </panel>
     <panel
@@ -231,7 +186,7 @@
      border="true"
      bevel_style="none"
      follows="left|top"
-     height="60"
+     height="70"
      width="560"
      name="complexity_subpanel"
      layout="topleft"
@@ -246,18 +201,7 @@
        name="complexity_lbl"
        top="12"
        width="180">
-          Your avatar complexity is
-      </text>
-      <text
-       follows="left|top"
-       font="SansSerifLarge"
-       text_color="PerformanceMid"
-       height="20"
-       layout="topleft"
-       left_pad="5"
-       name="complexity_value"
-       width="100">
-          275
+          Your avatar complexity
       </text>
       <text
        follows="left|top"
@@ -267,7 +211,7 @@
        layout="topleft"
        left="10"
        name="complexity_info"
-       top_pad="5"
+       top_pad="10"
        width="455">
           Reduce the complexity of your avatar if you aren't satisfied with current FPS.
       </text>
@@ -278,7 +222,7 @@
        mouse_opaque="true"
        name="icon_arrow4"
        follows="right|top"
-       top="24"
+       top="29"
        right="-20"/>
     </panel>
     <panel
@@ -288,7 +232,7 @@
      border="true"
      bevel_style="none"
      follows="left|top"
-     height="60"
+     height="70"
      width="560"
      name="huds_subpanel"
      layout="topleft"
@@ -303,18 +247,7 @@
        name="huds_lbl"
        top="12"
        width="135">
-          Your current HUDs:
-      </text>
-      <text
-       follows="left|top"
-       font="SansSerifLarge"
-       text_color="PerformanceMid"
-       height="20"
-       layout="topleft"
-       left_pad="5"
-       name="huds_value"
-       width="100">
-          7
+          Your active HUDs
       </text>
       <text
        follows="left|top"
@@ -324,7 +257,7 @@
        layout="topleft"
        left="10"
        name="huds_desc"
-       top_pad="5"
+       top_pad="10"
        width="395">
           Removing HUDs you are not using can improve speed.
       </text>
@@ -335,72 +268,10 @@
        mouse_opaque="true"
        name="icon_arrow4"
        follows="right|top"
-       top="24"
-       right="-20"/>
-    </panel>
-    <panel
-     bg_alpha_color="PanelGray"
-     background_visible="true"
-     background_opaque="false"
-     border="true"
-     bevel_style="none"
-     follows="left|top"
-     height="60"
-     width="560"
-     name="troubleshooting_subpanel"
-     layout="topleft"
-     top_pad="20">
-      <text
-       follows="left|top"
-       font="SansSerifLarge"
-       text_color="White"
-       height="20"
-       layout="topleft"
-       left="10"
-       name="troubleshooting_lbl"
-       top="12"
-       width="395">
-          General troubleshooting
-      </text>
-      <text
-       follows="left|top"
-       font="SansSerif"
-       text_color="White"
-       height="20"
-       layout="topleft"
-       left="10"
-       name="troubleshooting_desc"
-       top_pad="5"
-       width="395">
-          Choose among common problems and see what you can do.
-      </text>
-      <icon
-       height="16"
-       width="16"
-       image_name="Arrow_Right_Off"
-       mouse_opaque="true"
-       name="icon_arrow1"
-       follows="right|top"
-       top="24"
+       top="29"
        right="-20"/>
     </panel>
   </panel>
-  <panel
-    filename="panel_performance_presets.xml"
-    follows="all"
-    layout="topleft"
-    left="0"
-    name="panel_performance_presets"
-    visible="false"
-    top="55" />
-  <panel
-    filename="panel_performance_troubleshooting.xml"
-    follows="all"
-    layout="topleft"
-    left="0"
-    name="panel_performance_troubleshooting"
-    visible="false"
-    top="55" />
   <panel
     filename="panel_performance_nearby.xml"
     follows="all"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml
index 5163cd3115..1a18483418 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml
@@ -3,24 +3,25 @@
  layout="topleft"
  name="Settings">
     <menu_item_check
-     label="Default"
-     layout="topleft"
-     name="default">
-        <on_click function="Settings.SetRendering" parameter="default"/>
-	<on_check function="Settings.IsSelected" parameter="default" />  
-    </menu_item_check>
-    <menu_item_check
-     label="Always render"
+     label="Always full detail"
      layout="topleft"
      name="always_render">
         <on_click function="Settings.SetRendering" parameter="always"/>
-	<on_check function="Settings.IsSelected" parameter="always" />  
+        <on_check function="Settings.IsSelected" parameter="always" />  
     </menu_item_check>
     <menu_item_check
-     label="Never render"
+     label="Never full detail"
      layout="topleft"
      name="never_render">
         <on_click function="Settings.SetRendering" parameter="never"/>
-	<on_check function="Settings.IsSelected" parameter="never" />  
-    </menu_item_check>  
+        <on_check function="Settings.IsSelected" parameter="never" />
+    </menu_item_check>
+    <menu_item_check
+     label="Remove from exceptions"
+     layout="topleft"
+     name="default">
+        <on_click function="Settings.SetRendering" parameter="default"/>
+        <on_check function="Settings.IsSelected" parameter="default" />
+        <on_visible function="Settings.IsSelected" parameter="non_default" />
+  </menu_item_check>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml
index c64b24ed70..6e09eb5981 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml
@@ -4,13 +4,13 @@
      left="0" bottom="0" visible="false"
      mouse_opaque="false">
   <menu_item_call
-   label="Always Render a Resident..."
+   label="Always full detail..."
    name="add_avatar_always_render">
       <on_click
        function="Settings.AddNewEntry" parameter="always"/>
   </menu_item_call>
   <menu_item_call
-   label="Never Render a Resident..."
+   label="Never full detail..."
    name="add_avatar_never_render">
       <on_click
        function="Settings.AddNewEntry"  parameter="never"/>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
index 8d4512c4f7..b2f65f9488 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
@@ -42,7 +42,7 @@
    top_pad="10"
    name="attachments_title"
    width="195">
-    My avatar complexity 
+    Your avatar complexity 
   </text>
   <text
    follows="left|top"
@@ -54,7 +54,7 @@
    left="20"
    name="attachments_desc1"
    width="580">
-    Complex attachments require more time and memory to display.
+    If your avatar is very complex, some other people may not see you in full detail and
   </text>
   <text
    follows="left|top"
@@ -66,7 +66,7 @@
    left="20"
    name="attachments_desc2"
    width="580">
-    While you are in this location, removing the most complex ones may increase speed.
+    your own graphics speed may be reduced.
   </text>
   <name_list
     column_padding="0"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_huds.xml b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
index 96bdf2412f..7dcadc557b 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_huds.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
@@ -42,18 +42,7 @@
    top_pad="10"
    name="huds_title"
    width="135">
-    Your current HUDs: 
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLargeBold"
-   text_color="PerformanceMid"
-   height="20"
-   layout="topleft"
-   left_pad="3"
-   name="huds_value"
-   width="70">
-    7
+    Your active HUDs
   </text>
   <text
    follows="left|top"
@@ -65,7 +54,7 @@
    left="20"
    name="huds_desc1"
    width="540">
-    Detaching HUDs you aren't using us always a good idea, but especially in a complex location.
+    Detaching HUDs you aren't using saves memory and can make Second Life run faster.
   </text>
   <text
    follows="left|top"
@@ -77,7 +66,7 @@
    left="20"
    name="huds_desc2"
    width="540">
-    Note: Using a HUD's minimize button does not save memory. 
+    Note: Using a HUD's minimize button does not detach it. 
   </text>
   <name_list
     column_padding="0"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
index 9d91e86b7a..4cc7ffda40 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
@@ -42,18 +42,7 @@
    top_pad="10"
    name="av_nearby_title"
    width="205">
-    Nearby avatar complexity is
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLarge"
-   text_color="PerformanceMid"
-   height="20"
-   layout="topleft"
-   left_pad="3"
-   name="av_nearby_value"
-   width="150">
-    very high
+    Avatars nearby
   </text>
   <text
    follows="left|top"
@@ -65,7 +54,7 @@
    top_pad="5"
    name="av_nearby_desc"
    width="580">
-    Some avatars nearby are slow to display. Choosing a complexity limit may help graphics speed.
+    Avatars more complex than your chosen limit will be shown in silhouette.
   </text>
   <slider
     control_name="IndirectMaxComplexity"
@@ -83,7 +72,6 @@
     name="IndirectMaxComplexity"
     show_text="false"
     top_pad="10"
-    left="40"
     width="300">
   </slider>
   <text
@@ -148,7 +136,7 @@
     control_name="AlwaysRenderFriends"
     height="16"
     initial_value="true"
-    label="Always display friends"
+    label="Always display friends in full detail"
     label_text.text_color="White"
     layout="topleft"
     name="display_friends"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index b5cc2a29ed..fb62e7beb3 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="520"
+ height="630"
  width="580"
  name="panel_performance_preferences"
  layout="topleft"
@@ -42,7 +42,7 @@
    top_pad="10"
    name="settings_title"
    width="300">
-    Individual settings
+    Graphics settings
   </text>
   <view_border
     bevel_style="in"
@@ -60,8 +60,7 @@
    top_pad="30"
    name="quality_lbl"
    width="100">
-    Graphics quality
-shortcuts
+    Shortcuts
   </text>
   <text
    follows="left|top"
@@ -232,19 +231,7 @@ shortcuts
    left="160"
    name="distance_desc1"
    width="350">
-    To zoom out and see long distances, increase the distance.
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="5"
-   left="160"
-   name="distance_desc2"
-   width="350">
-    If you are indoors, decrease the distance to improve speed.
+    To see more land when you zoom out, increase the distance.
   </text>
   <view_border
     bevel_style="in"
@@ -262,9 +249,9 @@ shortcuts
    layout="topleft"
    top_pad="20"
    left="20"
-   name="enhancements_lbl"
+   name="environment_lbl"
    width="100">
-    Enhancements
+    Environment
   </text>
   <text
    follows="left|top"
@@ -298,7 +285,73 @@ shortcuts
     name="advanced_lighting_model"
     top_delta="24"
     width="280">
-  </check_box>
+  </check_box>  
+  <text
+    type="string"
+    length="1"
+    follows="left|top"
+    height="16"
+    layout="topleft"
+    left="160"
+    name="RenderShadowDetailText"
+    text_readonly_color="LabelDisabledColor"
+    top_pad="10"
+    width="128">
+    Shadows:
+  </text>
+  <combo_box
+   control_name="RenderShadowDetail"
+   height="18"
+   layout="topleft"
+   left_delta="150"
+   top_delta="0"
+   name="ShadowDetail"
+   width="150">
+    <combo_box.item
+      label="None"
+      name="0"
+      value="0"/>
+    <combo_box.item
+      label="Sun/Moon"
+      name="1"
+      value="1"/>
+    <combo_box.item
+      label="Sun/Moon + Projectors"
+      name="2"
+      value="2"/>
+  </combo_box>
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="border3"
+    top_pad="15"
+    left="20"
+    width="540"/>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="20"
+   left="20"
+   name="water_lbl"
+   width="100">
+    Water
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_delta="0"
+   left="160"
+   name="water_desc"
+   width="350">
+    Reducing or turning off water effects can greatly improve frame rate.
+  </text>
   <check_box
     control_name="RenderTransparentWater"
     height="16"
@@ -307,6 +360,7 @@ shortcuts
     layout="topleft"
     name="TransparentWater"
     top_delta="24"
+    left="157"
     width="280">
   </check_box>
   <text
@@ -359,57 +413,77 @@ shortcuts
       name="4"
       value="4"/>
   </combo_box>
-  <text
-    type="string"
-    length="1"
-    follows="left|top"
-    height="16"
+  <view_border
+    bevel_style="in"
+    height="0"
     layout="topleft"
-    left="160"
-    name="RenderShadowDetailText"
-    text_readonly_color="LabelDisabledColor"
-    top_pad="10"
-    width="128">
-    Shadows:
-  </text>
-  <combo_box
-   control_name="RenderShadowDetail"
+    name="border4"
+    top_pad="15"
+    left="20"
+    width="540"/>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
    height="18"
    layout="topleft"
-   left_delta="150"
-   top_delta="0"
-   name="ShadowDetail"
-   width="150">
-    <combo_box.item
-      label="None"
-      name="0"
-      value="0"/>
-    <combo_box.item
-      label="Sun/Moon"
-      name="1"
-      value="1"/>
-    <combo_box.item
-      label="Sun/Moon + Projectors"
-      name="2"
-      value="2"/>
-  </combo_box>
+   top_pad="20"
+   left="20"
+   name="photo_lbl"
+   width="100">
+    Photography
+  </text>
   <text
    follows="left|top"
    font="SansSerifSmall"
+   text_color="White"
    height="18"
    layout="topleft"
-   top_pad="8"
+   top_delta="0"
    left="160"
-   skip_link_underline="true"
-   name="settings_help"
+   name="photo_desc"
    width="350">
-    [secondlife:/// What do these settings mean?]
+    Maximum detail is good for photos, but can slow frame rate.
+  </text>
+  <spinner
+   control_name="RenderVolumeLODFactor"
+   follows="left|top"
+   height="23"
+   increment="0.125"
+   label="Distance detail:"
+   label_width="95"
+   layout="topleft"
+   max_val="4"
+   min_val="0"
+   name="render_volume_lod"
+   top_pad="10"
+   width="150" />
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   height="18"
+   layout="topleft"
+   top_delta="3"
+   left_pad="10"
+   name="photo_desc"
+   width="180">
+      (Enter value between 0.0 and 4.0)
   </text>
+  <check_box
+    height="16"
+    initial_value="true"
+    label="Hide avatars completely (good for landscape photos)"
+    layout="topleft"
+    name="hide_avatars"
+    top_delta="29"
+    left="157"
+    width="280">
+  </check_box>
   <view_border
     bevel_style="in"
     height="0"
     layout="topleft"
-    name="border3"
+    name="border5"
     top_pad="10"
     left="20"
     width="540"/>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_presets.xml b/indra/newview/skins/default/xui/en/panel_performance_presets.xml
deleted file mode 100644
index 51516020a2..0000000000
--- a/indra/newview/skins/default/xui/en/panel_performance_presets.xml
+++ /dev/null
@@ -1,223 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- bevel_style="none"
- follows="left|top"
- height="490"
- width="580"
- name="panel_performance_presets"
- layout="topleft"
- left="0"
- top="0">
-  <button
-    height="16"
-    width="16"
-    layout="topleft"
-    mouse_opaque="true"
-    follows="left|top"
-    name="back_btn"
-    top="7"
-    image_selected="Arrow_Left_Off"
-    image_pressed="Arrow_Left_Off"
-    image_unselected="Arrow_Left_Off"
-    left="15"
-    is_toggle="true">
-  </button>
-  <text
-   follows="left|top"
-   height="20"
-   layout="topleft"
-   left_pad="3"
-   top="10"
-   name="back_lbl"
-   width="40">
-    Back
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLarge"
-   text_color="White"
-   height="20"
-   layout="topleft"
-   left="20"
-   top_pad="10"
-   name="presets_title"
-   width="300">
-    Quick settings
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="5"
-   name="presets_desc"
-   width="580">
-    Note: Quick settings will reset all manual changes you have made.
-  </text>
-  <view_border
-    bevel_style="in"
-    height="0"
-    layout="topleft"
-    name="top_border"
-    top_pad="12"
-    width="540"/>
-  <button
-    follows="top|left"
-    height="23"
-    label="Social"
-    label_color="White"
-    layout="topleft"
-    name="social"
-    top_pad="14"
-    width="130">
-  </button>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="14"
-   name="social_desc1"
-   width="580">
-    Tuned for many avatars in a room.
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="5"
-   name="social_desc2"
-   width="180">
-    Nearby avatar complexity is high.
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   height="18"
-   layout="topleft"
-   left_pad="5"
-   name="avatars_nearby_link"
-   skip_link_underline="true"
-   width="200">
-    [secondlife:/// Choose avatars to show and hide]
-  </text>
-  <view_border
-    bevel_style="in"
-    height="0"
-    layout="topleft"
-    name="social_border"
-    left="20"
-    top_pad="12"
-    width="540"/>
-  <button
-    follows="top|left"
-    height="23"
-    label="Outdoors"
-    label_color="White"
-    layout="topleft"
-    name="outdoors"
-    top_pad="14"
-    width="130">
-  </button>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="14"
-   name="outdoors_desc"
-   width="580">
-    Fewer avatars, higher visibility distance.
-  </text>
-  <view_border
-    bevel_style="in"
-    height="0"
-    layout="topleft"
-    name="outdoors_border"
-    top_pad="12"
-    width="540"/>
-  <button
-    follows="top|left"
-    height="23"
-    label="Maximum distance"
-    label_color="White"
-    layout="topleft"
-    name="max_distance"
-    top_pad="14"
-    width="130">
-  </button>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="14"
-   name="max_distance_desc"
-   width="580">
-    Good for zooming your camera far out and viewing large land areas.
-  </text>
-  <view_border
-    bevel_style="in"
-    height="0"
-    layout="topleft"
-    name="max_distance_border"
-    top_pad="12"
-    width="540"/>
-  <button
-    follows="top|left"
-    height="23"
-    label="Photography"
-    label_color="White"
-    layout="topleft"
-    name="photography"
-    top_pad="14"
-    width="130">
-  </button>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="14"
-   name="photography_desc"
-   width="580">
-    Maximum quality, minimum visibility distance.
-  </text>
-  <view_border
-    bevel_style="in"
-    height="0"
-    layout="topleft"
-    name="photography_border"
-    top_pad="12"
-    width="540"/>
-    <text
-     follows="left|top"
-     font="SansSerifSmall"
-     text_color="White"
-     height="18"
-     layout="topleft"
-     top_pad="14"
-     name="settings_desc"
-     width="110">
-    For more control, try
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   height="18"
-   layout="topleft"
-   left_pad="3"
-   name="settings_link"
-   skip_link_underline="true"
-   width="200">
-    [secondlife:/// Idividual Settings]
-  </text>
-
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml b/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml
deleted file mode 100644
index 0a14eeb1c0..0000000000
--- a/indra/newview/skins/default/xui/en/panel_performance_troubleshooting.xml
+++ /dev/null
@@ -1,190 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- bevel_style="none"
- follows="left|top"
- height="490"
- width="580"
- name="panel_performance_troubleshooting"
- layout="topleft"
- left="0"
- top="0">
-  <button
-    height="16"
-    width="16"
-    layout="topleft"
-    mouse_opaque="true"
-    follows="left|top"
-    name="back_btn"
-    top="7"
-    image_selected="Arrow_Left_Off"
-    image_pressed="Arrow_Left_Off"
-    image_unselected="Arrow_Left_Off"
-    left="15"
-    is_toggle="true">
-  </button>
-  <text
-   follows="left|top"
-   height="20"
-   layout="topleft"
-   left_pad="3"
-   top="10"
-   name="back_lbl"
-   width="40">
-    Back
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLarge"
-   text_color="PerformanceMid"
-   height="20"
-   layout="topleft"
-   left="20"
-   top_pad="10"
-   name="troubleshooting_title"
-   width="300">
-    Fixes for common problems
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="5"
-   name="troubleshooting_desc"
-   width="580">
-    Some problems result from the complexity of the location where you are. All you can do is leave.
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLarge"
-   text_color="White"
-   height="20"
-   layout="topleft"
-   top_pad="30"
-   name="rubberbanding_title"
-   width="580">
-    Rubberbanding
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="5"
-   name="rubberbanding_desc"
-   width="580">
-    When you walk, your avatar may be pulled backward again and again.
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="3"
-   name="rubberbanding_fix"
-   width="580">
-    Fix: XXXXXXX
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLarge"
-   text_color="White"
-   height="20"
-   layout="topleft"
-   top_pad="25"
-   name="tex_thrashing_title"
-   width="580">
-    Texture thrashing
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="5"
-   name="tex_thrashing_desc"
-   width="580">
-    On objects near you, you may see their surfaces get blurry, then sharp, then blurry again.
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="3"
-   name="tex_thrashing_fix"
-   width="580">
-    Fix: XXXXXXX
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLarge"
-   text_color="White"
-   height="20"
-   layout="topleft"
-   top_pad="25"
-   name="av_moving_title"
-   width="580">
-    Avatars are not moving smoothly
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="5"
-   name="av_moving_desc"
-   width="580">
-    Lorem ipsum dolor sit amet.
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="3"
-   name="av_moving_fix"
-   width="580">
-    Fix: XXXXXXX
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifLarge"
-   text_color="White"
-   height="20"
-   layout="topleft"
-   top_pad="25"
-   name="av_moving_title"
-   width="580">
-    Will a better graphics card or new computer help?
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="5"
-   name="av_moving_desc"
-   width="580">
-    Lorem ipsum dolor sit amet.
-  </text>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="3"
-   name="av_moving_fix"
-   width="580">
-    Fix: XXXXXXX
-  </text>
-</panel>
-- 
cgit v1.2.3


From 84ae60a3b34d92930a74e9207bf39e6335e307a0 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 16 Jul 2021 16:32:12 +0300
Subject: SL-15581 Add the function to get median FPS

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

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index a2fb8c130d..879a8f8718 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -156,7 +156,7 @@ void LLFloaterPerformance::draw()
 
     if (mUpdateTimer->hasExpired())
     {
-        getChild<LLTextBox>("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS, NUM_PERIODS)));
+        getChild<LLTextBox>("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, NUM_PERIODS)));
         if (mHUDsPanel->getVisible())
         {
             populateHUDList();
-- 
cgit v1.2.3


From 928191f525cf8a02816718eefd9a65097d8ecb8b Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 19 Jul 2021 20:07:03 +0300
Subject: SL-15297 performance floater UI update #2

---
 indra/newview/llfloaterperformance.cpp             | 89 ++++++++++++++--------
 indra/newview/llfloaterpreference.cpp              |  9 ++-
 indra/newview/llfloaterpreference.h                |  4 +-
 indra/newview/llnamelistctrl.cpp                   |  2 +-
 indra/newview/llviewermenu.cpp                     |  2 +
 .../skins/default/xui/en/floater_performance.xml   | 42 +++++-----
 .../skins/default/xui/en/menu_attachment_other.xml | 28 +++----
 .../skins/default/xui/en/menu_avatar_other.xml     | 64 ++++++++--------
 indra/newview/skins/default/xui/en/menu_viewer.xml | 15 ++--
 .../xui/en/panel_performance_complexity.xml        | 20 ++++-
 .../default/xui/en/panel_performance_huds.xml      |  4 +-
 .../default/xui/en/panel_performance_nearby.xml    | 75 ++++++++++++++++--
 .../xui/en/panel_performance_preferences.xml       | 47 ++++--------
 indra/newview/skins/default/xui/en/strings.xml     |  2 +-
 14 files changed, 247 insertions(+), 156 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 879a8f8718..d7c0527b5c 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -114,10 +114,10 @@ BOOL LLFloaterPerformance::postBuild()
     mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
 
     mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
-    mSettingsPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this));
-    mSettingsPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR));
 
     mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
+    mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this));
+    mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR));
     mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
     mNearbyList->setRightMouseDownCallback(boost::bind(&LLFloaterPerformance::onAvatarListRightClick, this, _1, _2, _3));
 
@@ -164,15 +164,12 @@ void LLFloaterPerformance::draw()
         else if (mNearbyPanel->getVisible())
         {
             populateNearbyList();
+            mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR));
         }
         else if (mComplexityPanel->getVisible())
         {
             populateObjectList();
         }
-        else if (mSettingsPanel->getVisible())
-        {
-            mSettingsPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR));
-        }
 
         mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL);
     }
@@ -223,7 +220,7 @@ void LLFloaterPerformance::populateHUDList()
     for (iter = complexity_list.begin(); iter != end; ++iter)
     {
         LLHUDComplexity hud_object_complexity = *iter;        
-
+        S32 obj_cost_short = hud_object_complexity.objectsCost / 1000;
         LLSD item;
         item["special_id"] = hud_object_complexity.objectId;
         item["target"] = LLNameListCtrl::SPECIAL;
@@ -231,14 +228,14 @@ void LLFloaterPerformance::populateHUDList()
         row[0]["column"] = "complex_visual";
         row[0]["type"] = "bar";
         LLSD& value = row[0]["value"];
-        value["ratio"] = (F32)hud_object_complexity.objectsCost / max_complexity;
+        value["ratio"] = (F32)obj_cost_short / max_complexity * 1000;
         value["bottom"] = BAR_BOTTOM_PAD;
         value["left_pad"] = BAR_LEFT_PAD;
         value["right_pad"] = BAR_RIGHT_PAD;
 
         row[1]["column"] = "complex_value";
         row[1]["type"] = "text";
-        row[1]["value"] = std::to_string(hud_object_complexity.objectsCost);
+        row[1]["value"] = std::to_string(obj_cost_short);
         row[1]["font"]["name"] = "SANSSERIF";
  
         row[2]["column"] = "name";
@@ -246,7 +243,15 @@ void LLFloaterPerformance::populateHUDList()
         row[2]["value"] = hud_object_complexity.objectName;
         row[2]["font"]["name"] = "SANSSERIF";
 
-        mHUDList->addElement(item);
+        LLScrollListItem* obj = mHUDList->addElement(item);
+        if (obj)
+        {
+            LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
+            if (value_text)
+            {
+                value_text->setAlignment(LLFontGL::HCENTER);
+            }
+        }
     }
     mHUDList->sortByColumnIndex(1, FALSE);
     mHUDList->setScrollPos(prev_pos);
@@ -274,7 +279,7 @@ void LLFloaterPerformance::populateObjectList()
     for (iter = complexity_list.begin(); iter != end; ++iter)
     {
         LLObjectComplexity object_complexity = *iter;        
-
+        S32 obj_cost_short = object_complexity.objectCost / 1000;
         LLSD item;
         item["special_id"] = object_complexity.objectId;
         item["target"] = LLNameListCtrl::SPECIAL;
@@ -282,14 +287,14 @@ void LLFloaterPerformance::populateObjectList()
         row[0]["column"] = "complex_visual";
         row[0]["type"] = "bar";
         LLSD& value = row[0]["value"];
-        value["ratio"] = (F32)object_complexity.objectCost / max_complexity;
+        value["ratio"] = (F32)obj_cost_short / max_complexity * 1000;
         value["bottom"] = BAR_BOTTOM_PAD;
         value["left_pad"] = BAR_LEFT_PAD;
         value["right_pad"] = BAR_RIGHT_PAD;
 
         row[1]["column"] = "complex_value";
         row[1]["type"] = "text";
-        row[1]["value"] = std::to_string(object_complexity.objectCost);
+        row[1]["value"] = std::to_string(obj_cost_short);
         row[1]["font"]["name"] = "SANSSERIF";
 
         row[2]["column"] = "name";
@@ -297,7 +302,15 @@ void LLFloaterPerformance::populateObjectList()
         row[2]["value"] = object_complexity.objectName;
         row[2]["font"]["name"] = "SANSSERIF";
 
-        mObjectList->addElement(item);
+        LLScrollListItem* obj = mObjectList->addElement(item);
+        if (obj)
+        {
+            LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
+            if (value_text)
+            {
+                value_text->setAlignment(LLFontGL::HCENTER);
+            }
+        }
     }
     mObjectList->sortByColumnIndex(1, FALSE);
     mObjectList->setScrollPos(prev_pos);
@@ -321,20 +334,21 @@ void LLFloaterPerformance::populateNearbyList()
         LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
         if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))
         {
+            S32 complexity_short = avatar->getVisualComplexity() / 1000;
             LLSD item;
             item["id"] = avatar->getID();
             LLSD& row = item["columns"];
             row[0]["column"] = "complex_visual";
             row[0]["type"] = "bar";
             LLSD& value = row[0]["value"];
-            value["ratio"] = (F32)avatar->getVisualComplexity() / mNearbyMaxComplexity;
+            value["ratio"] = (F32)complexity_short / mNearbyMaxComplexity * 1000;
             value["bottom"] = BAR_BOTTOM_PAD;
             value["left_pad"] = BAR_LEFT_PAD;
             value["right_pad"] = BAR_RIGHT_PAD;
 
             row[1]["column"] = "complex_value";
             row[1]["type"] = "text";
-            row[1]["value"] = std::to_string( avatar->getVisualComplexity());
+            row[1]["value"] = std::to_string(complexity_short);
             row[1]["font"]["name"] = "SANSSERIF";
 
             row[2]["column"] = "name";
@@ -345,24 +359,36 @@ void LLFloaterPerformance::populateNearbyList()
             LLScrollListItem* av_item = mNearbyList->addElement(item);
             if(av_item)
             {
+                LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(1));
+                if (value_text)
+                {
+                    value_text->setAlignment(LLFontGL::HCENTER);
+                }
                 LLScrollListText* name_text = dynamic_cast<LLScrollListText*>(av_item->getColumn(2));
                 if (name_text)
                 {
-                    std::string color = "white";
-                    if (LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance())
+                    if (avatar->isSelf())
                     {
-                        color = "LabelDisabledColor";
-                        LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0));
-                        if (bar)
-                        {
-                            bar->setColor(LLUIColorTable::instance().getColor(color));
-                        }
+                        name_text->setColor(LLUIColorTable::instance().getColor("DrYellow"));
                     }
-                    else if (LLVOAvatar::AOA_NORMAL == avatar->getOverallAppearance())
+                    else
                     {
-                        color =  LLAvatarActions::isFriend(avatar->getID()) ? "ConversationFriendColor" : "white";
+                        std::string color = "white";
+                        if (LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance())
+                        {
+                            color = "LabelDisabledColor";
+                            LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0));
+                            if (bar)
+                            {
+                                bar->setColor(LLUIColorTable::instance().getColor(color));
+                            }
+                        }
+                        else if (LLVOAvatar::AOA_NORMAL == avatar->getOverallAppearance())
+                        {
+                            color = LLAvatarActions::isFriend(avatar->getID()) ? "ConversationFriendColor" : "white";
+                        }
+                        name_text->setColor(LLUIColorTable::instance().getColor(color));
                     }
-                    name_text->setColor(LLUIColorTable::instance().getColor(color));
                 }
             }
         }
@@ -376,12 +402,13 @@ void LLFloaterPerformance::populateNearbyList()
 void LLFloaterPerformance::getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs)
 {
     static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
+    mNearbyMaxComplexity = 0;
     F32 radius = render_far_clip * render_far_clip;
     std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
     while (char_iter != LLCharacter::sInstances.end())
     {
         LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
-        if (avatar && !avatar->isDead() && !avatar->isControlAvatar() && !avatar->isSelf())
+        if (avatar && !avatar->isDead() && !avatar->isControlAvatar())
         {
             if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
                 (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius))
@@ -426,13 +453,15 @@ void LLFloaterPerformance::updateMaxComplexity()
 {
     LLAvatarComplexityControls::updateMax(
         mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
-        mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText"));
+        mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText"), 
+        true);
 }
 
 void LLFloaterPerformance::updateComplexityText()
 {
     LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
-        mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText", true));
+        mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText", true), 
+        true);
 }
 
 static LLVOAvatar* find_avatar(const LLUUID& id)
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 1ab6621c4c..a0a0b3c874 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1455,7 +1455,7 @@ void LLFloaterPreference::refreshUI()
 	refresh();
 }
 
-void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* value_label)
+void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
 {
 	// Called when the IndirectMaxComplexity control changes
 	// Responsible for fixing the slider label (IndirectMaxComplexityText) and setting RenderAvatarMaxComplexity
@@ -1477,10 +1477,10 @@ void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* valu
 	}
 
 	gSavedSettings.setU32("RenderAvatarMaxComplexity", (U32)max_arc);
-	setText(max_arc, value_label);
+	setText(max_arc, value_label, short_val);
 }
 
-void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box)
+void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box, bool short_val)
 {
 	if (0 == value)
 	{
@@ -1488,7 +1488,8 @@ void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box)
 	}
 	else
 	{
-		text_box->setText(llformat("%d", value));
+        std::string text_value = short_val ? llformat("%d", value / 1000) : llformat("%d", value);
+        text_box->setText(text_value);
 	}
 }
 
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index f86104ed99..23d3f73d70 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -351,8 +351,8 @@ private:
 class LLAvatarComplexityControls
 {
   public: 
-	static void updateMax(LLSliderCtrl* slider, LLTextBox* value_label);
-	static void setText(U32 value, LLTextBox* text_box);
+	static void updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false);
+	static void setText(U32 value, LLTextBox* text_box, bool short_val = false);
 	static void setIndirectControls();
 	static void setIndirectMaxNonImpostors();
 	static void setIndirectMaxArc();
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 92805e03f0..c24c74393d 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -363,7 +363,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
 			else if (LLAvatarNameCache::get(id, &av_name))
 			{
 				if (mShortNames)
-					fullname = av_name.getDisplayName();
+					fullname = av_name.getDisplayName(true);
 				else
 					fullname = av_name.getCompleteName();
 			}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ad81cb07c1..fa2ada32b3 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3149,6 +3149,8 @@ class LLAvatarCheckImpostorMode : public view_listener_t
 				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
 			case 2:
 				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
+            case 4:
+                return (avatar->getVisualMuteSettings() != LLVOAvatar::AV_RENDER_NORMALLY);
 			default:
 				return false;
 		}
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index 210b2f8792..c47b8100c2 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- height="692"
+ height="592"
  layout="topleft"
  name="performance"
  save_rect="true"
@@ -47,7 +47,7 @@
        text_color="White"
        height="20"
        layout="topleft"
-       left_pad="0"
+       left_pad="3"
        top="13"
        name="fps_lbl"
        width="450">
@@ -93,7 +93,7 @@
      border="true"
      bevel_style="none"
      follows="left|top"
-     height="70"
+     height="50"
      width="560"
      name="settings_subpanel"
      layout="topleft"
@@ -107,7 +107,7 @@
          layout="topleft"
          left="10"
          name="settings_lbl"
-         top="12"
+         top="7"
          width="180">
           Graphics settings
         </text>
@@ -119,7 +119,7 @@
          layout="topleft"
          left="10"
          name="settings_desc"
-         top_pad="10"
+         top_pad="0"
          width="395">
           Choose settings for distance, water, lighting and more.
         </text>
@@ -130,7 +130,7 @@
          mouse_opaque="true"
          name="icon_arrow3"
          follows="right|top"
-         top="29"
+         top="19"
          right="-20"/>
       </panel>
     <panel
@@ -140,11 +140,11 @@
      border="true"
      bevel_style="none"
      follows="left|top"
-     height="70"
+     height="50"
      width="560"
      name="nearby_subpanel"
      layout="topleft"
-     top_pad="20">
+     top_pad="10">
       <text
        follows="left|top"
        font="SansSerifLarge"
@@ -153,7 +153,7 @@
        layout="topleft"
        left="10"
        name="avatars_nearby_lbl"
-       top="12"
+       top="7"
        width="205">
           Avatars nearby
       </text>
@@ -165,7 +165,7 @@
        layout="topleft"
        left="10"
        name="avatars_nearby_desc"
-       top_pad="10"
+       top_pad="0"
        width="395">
           Manage which nearby avatars are fully displayed.
       </text>
@@ -176,7 +176,7 @@
        mouse_opaque="true"
        name="icon_arrow2"
        follows="right|top"
-       top="29"
+       top="19"
        right="-20"/>
     </panel>
     <panel
@@ -186,11 +186,11 @@
      border="true"
      bevel_style="none"
      follows="left|top"
-     height="70"
+     height="50"
      width="560"
      name="complexity_subpanel"
      layout="topleft"
-     top_pad="20">
+     top_pad="10">
       <text
        follows="left|top"
        font="SansSerifLarge"
@@ -199,7 +199,7 @@
        layout="topleft"
        left="10"
        name="complexity_lbl"
-       top="12"
+       top="7"
        width="180">
           Your avatar complexity
       </text>
@@ -211,7 +211,7 @@
        layout="topleft"
        left="10"
        name="complexity_info"
-       top_pad="10"
+       top_pad="0"
        width="455">
           Reduce the complexity of your avatar if you aren't satisfied with current FPS.
       </text>
@@ -222,7 +222,7 @@
        mouse_opaque="true"
        name="icon_arrow4"
        follows="right|top"
-       top="29"
+       top="19"
        right="-20"/>
     </panel>
     <panel
@@ -232,11 +232,11 @@
      border="true"
      bevel_style="none"
      follows="left|top"
-     height="70"
+     height="50"
      width="560"
      name="huds_subpanel"
      layout="topleft"
-     top_pad="20">
+     top_pad="10">
       <text
        follows="left|top"
        font="SansSerifLarge"
@@ -245,7 +245,7 @@
        layout="topleft"
        left="10"
        name="huds_lbl"
-       top="12"
+       top="7"
        width="135">
           Your active HUDs
       </text>
@@ -257,7 +257,7 @@
        layout="topleft"
        left="10"
        name="huds_desc"
-       top_pad="10"
+       top_pad="0"
        width="395">
           Removing HUDs you are not using can improve speed.
       </text>
@@ -268,7 +268,7 @@
        mouse_opaque="true"
        name="icon_arrow4"
        follows="right|top"
-       top="29"
+       top="19"
        right="-20"/>
     </panel>
   </panel>
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index 7ad692038e..22006c287f 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -131,22 +131,12 @@
 
    <menu_item_separator />
       <context_menu
-       label="Render Avatar"
+       label="Display this avatar"
        layout="topleft"
-        name="Render Avatar">
-      <menu_item_check
-        name="RenderNormally"
-        label="Default">
-        <menu_item_check.on_check
-          function="Avatar.CheckImpostorMode"
-          parameter="0" />
-	    <menu_item_check.on_click
-	      function="Avatar.SetImpostorMode"
-	      parameter="0" />
-      </menu_item_check>
+       name="Render Avatar">
       <menu_item_check
         name="AlwaysRenderFully"
-        label="Always">
+        label="Always full detail">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
           parameter="2" />
@@ -156,7 +146,7 @@
       </menu_item_check>
       <menu_item_check
         name="DoNotRender"
-        label="Never">
+        label="Never full detail">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
           parameter="1" />
@@ -164,6 +154,16 @@
 	      function="Avatar.SetImpostorMode"
 	      parameter="1" />
       </menu_item_check>
+      <menu_item_call
+        name="RenderNormally"
+        label="Remove from exceptions">
+          <menu_item_call.on_visible
+            function="Avatar.CheckImpostorMode"
+            parameter="4" />
+          <menu_item_call.on_click
+            function="Avatar.SetImpostorMode"
+            parameter="0" />
+      </menu_item_call>
       <menu_item_separator />
       <menu_item_call
         label="Exceptions..."
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index acbb9b860d..665eb9a82f 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -122,39 +122,39 @@
    <menu_item_separator />
     
  <context_menu
-       label="Render Avatar"
+       label="Display this avatar"
        layout="topleft"
-        name="Render Avatar">
-      <menu_item_check
-        name="RenderNormally"
-        label="Default">
-        <menu_item_check.on_check
-          function="Avatar.CheckImpostorMode"
-          parameter="0" />
-	    <menu_item_check.on_click
-	      function="Avatar.SetImpostorMode"
-	      parameter="0" />
-      </menu_item_check>
-      <menu_item_check
-        name="AlwaysRenderFully"
-        label="Always">
-        <menu_item_check.on_check
-          function="Avatar.CheckImpostorMode"
-          parameter="2" />
-	    <menu_item_check.on_click
-	      function="Avatar.SetImpostorMode"
-	      parameter="2" />
-      </menu_item_check>
-      <menu_item_check
-        name="DoNotRender"
-        label="Never">
-        <menu_item_check.on_check
-          function="Avatar.CheckImpostorMode"
-          parameter="1" />
-	    <menu_item_check.on_click
-	      function="Avatar.SetImpostorMode"
-	      parameter="1" />
-      </menu_item_check>
+       name="Render Avatar">
+       <menu_item_check
+         name="AlwaysRenderFully"
+         label="Always full detail">
+         <menu_item_check.on_check
+           function="Avatar.CheckImpostorMode"
+           parameter="2" />
+         <menu_item_check.on_click
+           function="Avatar.SetImpostorMode"
+           parameter="2" />
+       </menu_item_check>
+       <menu_item_check
+         name="DoNotRender"
+         label="Never full detail">
+         <menu_item_check.on_check
+           function="Avatar.CheckImpostorMode"
+           parameter="1" />
+         <menu_item_check.on_click
+           function="Avatar.SetImpostorMode"
+           parameter="1" />
+       </menu_item_check>
+       <menu_item_call
+         name="RenderNormally"
+         label="Remove from exceptions">
+         <menu_item_call.on_visible
+           function="Avatar.CheckImpostorMode"
+           parameter="4" />
+         <menu_item_call.on_click
+           function="Avatar.SetImpostorMode"
+           parameter="0" />
+       </menu_item_call>
       <menu_item_separator />
       <menu_item_call
         label="Exceptions..."
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 177f995b12..b1adf97444 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -126,13 +126,6 @@
             <menu_item_call.on_click
              function="Floater.Toggle"
              parameter="preferences" />
-        </menu_item_call>
-        <menu_item_call
-          label="Performance..."
-          name="Performance">
-          <menu_item_call.on_click
-           function="Floater.Toggle"
-           parameter="performance" />
         </menu_item_call>
          <menu_item_call
          label="Toolbar buttons..."
@@ -860,7 +853,13 @@
                parameter="UseDebugMenus" />
           </menu_item_check>
         </menu>
-
+        <menu_item_call
+          label="Improve graphics speed..."
+          name="Performance">
+          <menu_item_call.on_click
+           function="Floater.Toggle"
+           parameter="performance" />
+        </menu_item_call>
         <menu_item_separator/>
     <!--    <menu_item_check
          label="Show Navigation Bar"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
index b2f65f9488..40159314f7 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="490"
+ height="530"
  width="580"
  name="panel_performance_complexity"
  layout="topleft"
@@ -54,7 +54,7 @@
    left="20"
    name="attachments_desc1"
    width="580">
-    If your avatar is very complex, some other people may not see you in full detail and
+    Attachments make your avatar more complex. If your avatar is very complex, some other 
   </text>
   <text
    follows="left|top"
@@ -66,12 +66,24 @@
    left="20"
    name="attachments_desc2"
    width="580">
-    your own graphics speed may be reduced.
+    people may not see you in full detail, and your graphics speed may be reduced. Removing
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="3"
+   left="20"
+   name="attachments_desc3"
+   width="580">
+    heavy attachments that you don’t need can help.
   </text>
   <name_list
     column_padding="0"
     draw_stripes="true"
-    height="220"
+    height="379"
     follows="left|top"
     layout="topleft"
     name="obj_list"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_huds.xml b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
index 7dcadc557b..eea6b79e30 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_huds.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="490"
+ height="530"
  width="580"
  name="panel_performance_huds"
  layout="topleft"
@@ -71,7 +71,7 @@
   <name_list
     column_padding="0"
     draw_stripes="true"
-    height="220"
+    height="400"
     follows="left|top"
     layout="topleft"
     name="hud_list"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
index 4cc7ffda40..e1aef13717 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="490"
+ height="530"
  width="580"
  name="panel_performance_nearby"
  layout="topleft"
@@ -54,7 +54,7 @@
    top_pad="5"
    name="av_nearby_desc"
    width="580">
-    Avatars more complex than your chosen limit will be shown in silhouette.
+    Hide the most complex avatars to boost speed.
   </text>
   <slider
     control_name="IndirectMaxComplexity"
@@ -63,7 +63,7 @@
     height="16"
     initial_value="101"
     increment="1"
-    label="Maximum avatar complexity"
+    label="Maximum complexity (K)"
     text_color="White"
     label_width="165"
     layout="topleft"
@@ -90,11 +90,12 @@
   <name_list
     column_padding="0"
     draw_stripes="true"
-    height="220"
+    height="280"
     left="20"
     follows="left|top"
     layout="topleft"
     sort_column="complex_value"
+    short_names="true"
     name="nearby_list"
     name_column="name"
     top_pad="10"
@@ -144,6 +145,70 @@
     left="18"
     width="256">
   </check_box>
-
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="border"
+    top_pad="15"
+    left="20"
+    width="540"/>
+  <check_box
+    height="16"
+    initial_value="true"
+    label="Hide avatars completely (good for landscape photos)"
+    layout="topleft"
+    name="hide_avatars"
+    top_delta="15"
+    left="18"
+    width="280">
+   </check_box>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="15"
+   layout="topleft"
+   left="20"
+   name="name_tags_textbox"
+   top_pad="10"
+   width="400">
+    Name tags:
+  </text>
+  <radio_group
+    control_name="AvatarNameTagMode"
+    height="20"
+    layout="topleft"
+    left="120"
+    top_delta="0"
+    name="name_tag_mode">
+    <radio_item
+     label="Off"
+     name="radio"
+     top_delta="20"
+     layout="topleft"
+     height="16"
+     left="0"
+     value="0"
+     width="75" />
+    <radio_item
+     label="On"
+     left_pad="0"
+     layout="topleft"
+     top_delta="0"
+     height="16"
+     name="radio2"
+     value="1"
+     width="75" />
+    <radio_item
+     label="Show briefly"
+     left_pad="0"
+     name="radio3"
+     height="16"
+     layout="topleft"
+     top_delta="0"
+     value="2"
+     width="160" />
+  </radio_group>
  
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index fb62e7beb3..221dfa0222 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="630"
+ height="530"
  width="580"
  name="panel_performance_preferences"
  layout="topleft"
@@ -44,11 +44,21 @@
    width="300">
     Graphics settings
   </text>
+  <button
+    follows="top|left"
+    height="23"
+    label="Open Advanced Settings"
+    layout="topleft"
+    left="360"
+    name="advanced_btn"
+    top_delta="0"
+    width="200"/>
   <view_border
     bevel_style="in"
     height="0"
     layout="topleft"
     name="border1"
+    left="20"
     top_pad="8"
     width="540"/>
   <text
@@ -156,7 +166,7 @@
     height="0"
     layout="topleft"
     name="border2"
-    top_pad="15"
+    top_pad="5"
     left="20"
     width="540"/>
   <text
@@ -238,7 +248,7 @@
     height="0"
     layout="topleft"
     name="border3"
-    top_pad="15"
+    top_pad="5"
     left="20"
     width="540"/>
   <text
@@ -325,7 +335,7 @@
     height="0"
     layout="topleft"
     name="border3"
-    top_pad="15"
+    top_pad="7"
     left="20"
     width="540"/>
   <text
@@ -418,7 +428,7 @@
     height="0"
     layout="topleft"
     name="border4"
-    top_pad="15"
+    top_pad="7"
     left="20"
     width="540"/>
   <text
@@ -469,33 +479,6 @@
    width="180">
       (Enter value between 0.0 and 4.0)
   </text>
-  <check_box
-    height="16"
-    initial_value="true"
-    label="Hide avatars completely (good for landscape photos)"
-    layout="topleft"
-    name="hide_avatars"
-    top_delta="29"
-    left="157"
-    width="280">
-  </check_box>
-  <view_border
-    bevel_style="in"
-    height="0"
-    layout="topleft"
-    name="border5"
-    top_pad="10"
-    left="20"
-    width="540"/>
-  <button
-    follows="top|left"
-    height="23"
-    label="Open Advanced Settings"
-    layout="topleft"
-    left="160"
-    name="advanced_btn"
-    top_pad="12"
-    width="200"/>
   <text
    follows="left|top"
    font="SansSerifSmall"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index d115e09d5b..db6fbfe362 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -4271,7 +4271,7 @@ Try enclosing path to the editor with double quotes.
   <string name="preset_combo_label">-Empty list-</string>
   <string name="Default">Default</string>
   <string name="none_paren_cap">(None)</string>
-  <string name="no_limit">No Limit</string>
+  <string name="no_limit">No limit</string>
   
   <string name="Mav_Details_MAV_FOUND_DEGENERATE_TRIANGLES">
       The physics shape contains triangles which are too small. Try simplifying the physics model.
-- 
cgit v1.2.3


From 130e915007d3b95412abf1dc069adfb87a5e372c Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 21 Jul 2021 18:10:25 +0300
Subject: SL-15297 toolbar button is added & changing quality via radio group
 is handled correctly now

---
 indra/newview/app_settings/commands.xml                |  10 ++++++++++
 indra/newview/llfloaterperformance.cpp                 |  17 ++++++++++++++---
 indra/newview/llfloaterperformance.h                   |   1 +
 indra/newview/skins/default/textures/textures.xml      |   1 +
 .../default/textures/toolbar_icons/performance.png     | Bin 0 -> 451 bytes
 indra/newview/skins/default/xui/en/strings.xml         |   2 ++
 6 files changed, 28 insertions(+), 3 deletions(-)
 create mode 100644 indra/newview/skins/default/textures/toolbar_icons/performance.png

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index d0480ca47e..b0629938a9 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -276,4 +276,14 @@
          is_running_function="Floater.IsOpen"
          is_running_parameters="my_environments"
            />
+  <command name="performance"
+         available_in_toybox="true"
+         icon="Command_Performance_Icon"
+         label_ref="Command_Performance_Label"
+         tooltip_ref="Command_Performance_Tooltip"
+         execute_function="Floater.ToggleOrBringToFront"
+         execute_parameters="performance"
+         is_running_function="Floater.IsOpen"
+         is_running_parameters="performance"
+           />
 </commands>
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index d7c0527b5c..dca19e0e28 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -36,6 +36,7 @@
 #include "llfloaterpreference.h" // LLAvatarComplexityControls
 #include "llfloaterreg.h"
 #include "llnamelistctrl.h"
+#include "llradiogroup.h"
 #include "llsliderctrl.h"
 #include "lltextbox.h"
 #include "lltrans.h"
@@ -114,6 +115,7 @@ BOOL LLFloaterPerformance::postBuild()
     mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
 
     mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
+    mSettingsPanel->getChild<LLRadioGroup>("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2));
 
     mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
     mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this));
@@ -220,7 +222,7 @@ void LLFloaterPerformance::populateHUDList()
     for (iter = complexity_list.begin(); iter != end; ++iter)
     {
         LLHUDComplexity hud_object_complexity = *iter;        
-        S32 obj_cost_short = hud_object_complexity.objectsCost / 1000;
+        S32 obj_cost_short = llmax((S32)hud_object_complexity.objectsCost / 1000, 1);
         LLSD item;
         item["special_id"] = hud_object_complexity.objectId;
         item["target"] = LLNameListCtrl::SPECIAL;
@@ -279,7 +281,7 @@ void LLFloaterPerformance::populateObjectList()
     for (iter = complexity_list.begin(); iter != end; ++iter)
     {
         LLObjectComplexity object_complexity = *iter;        
-        S32 obj_cost_short = object_complexity.objectCost / 1000;
+        S32 obj_cost_short = llmax((S32)object_complexity.objectCost / 1000, 1);
         LLSD item;
         item["special_id"] = object_complexity.objectId;
         item["target"] = LLNameListCtrl::SPECIAL;
@@ -334,7 +336,7 @@ void LLFloaterPerformance::populateNearbyList()
         LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
         if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))
         {
-            S32 complexity_short = avatar->getVisualComplexity() / 1000;
+            S32 complexity_short = llmax((S32)avatar->getVisualComplexity() / 1000, 1);;
             LLSD item;
             item["id"] = avatar->getID();
             LLSD& row = item["columns"];
@@ -439,6 +441,15 @@ void LLFloaterPerformance::onClickAdvanced()
     LLFloaterReg::showInstance("prefs_graphics_advanced");
 }
 
+void LLFloaterPerformance::onChangeQuality(const LLSD& data)
+{
+    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {
+        instance->onChangeQuality(data);
+    }
+}
+
 void LLFloaterPerformance::onClickHideAvatars()
 {
     LLPipeline::toggleRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR);
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 58f9447d4c..a5549685f6 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -59,6 +59,7 @@ private:
     void populateNearbyList();
 
     void onClickAdvanced();
+    void onChangeQuality(const LLSD& data);
     void onClickHideAvatars();
     void onClickExceptions();
 
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 03878d9fe7..cf5be9afa5 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -151,6 +151,7 @@ with the same filename but different name
   <texture name="Command_Move_Icon"         file_name="toolbar_icons/move.png"         preload="true" />
   <texture name="Command_Environments_Icon" file_name="toolbar_icons/environments.png" preload="true" />
   <texture name="Command_People_Icon"       file_name="toolbar_icons/people.png"       preload="true" />
+  <texture name="Command_Performance_Icon"  file_name="toolbar_icons/performance.png"  preload="true" />
   <texture name="Command_Picks_Icon"        file_name="toolbar_icons/picks.png"        preload="true" />
   <texture name="Command_Places_Icon"       file_name="toolbar_icons/places.png"       preload="true" />
   <texture name="Command_Preferences_Icon"  file_name="toolbar_icons/preferences.png"  preload="true" />
diff --git a/indra/newview/skins/default/textures/toolbar_icons/performance.png b/indra/newview/skins/default/textures/toolbar_icons/performance.png
new file mode 100644
index 0000000000..91baf849c8
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/performance.png differ
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index db6fbfe362..edf904226e 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -4143,6 +4143,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_MiniMap_Label">Mini-map</string>
   <string name="Command_Move_Label">Walk / run / fly</string>
   <string name="Command_People_Label">People</string>
+  <string name="Command_Performance_Label">Graphics speed</string>
   <string name="Command_Picks_Label">Picks</string>
   <string name="Command_Places_Label">Places</string>
   <string name="Command_Preferences_Label">Preferences</string>
@@ -4173,6 +4174,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_MiniMap_Tooltip">Show nearby people</string>
   <string name="Command_Move_Tooltip">Moving your avatar</string>
   <string name="Command_People_Tooltip">Friends, groups, and nearby people</string>
+  <string name="Command_Performance_Tooltip">Improve graphics speed</string>
   <string name="Command_Picks_Tooltip">Places to show as favorites in your profile</string>
   <string name="Command_Places_Tooltip">Places you've saved</string>
   <string name="Command_Preferences_Tooltip">Preferences</string>
-- 
cgit v1.2.3


From 2cc718d1b6d3ab7978b5f02c6d07391fe3cb8c3a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 22 Jul 2021 12:36:25 +0300
Subject: SL-15625 FIXED Low digit of fps sometimes does not display

---
 indra/newview/skins/default/xui/en/floater_performance.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index c47b8100c2..84ee9d3c00 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -38,8 +38,8 @@
        left="20"
        top="8"
        name="fps_value"
-       width="40">
-          75
+       width="42">
+          167
       </text>
       <text
        follows="left|top"
-- 
cgit v1.2.3


From f24682d8510f778cba11b057d561915cd0fe3905 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 23 Jul 2021 15:18:11 +0300
Subject: SL-15667 FIXED Complexity value is not updated in Advanced floater

---
 indra/newview/llfloaterperformance.cpp                 |  2 +-
 indra/newview/llfloaterpreference.cpp                  | 15 ++++++++-------
 indra/newview/llfloaterpreference.h                    |  3 +++
 indra/newview/llfloaterpreferencesgraphicsadvanced.cpp | 15 ++++++++-------
 indra/newview/llfloaterpreferencesgraphicsadvanced.h   |  4 +++-
 5 files changed, 23 insertions(+), 16 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index dca19e0e28..689205575b 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -124,7 +124,7 @@ BOOL LLFloaterPerformance::postBuild()
     mNearbyList->setRightMouseDownCallback(boost::bind(&LLFloaterPerformance::onAvatarListRightClick, this, _1, _2, _3));
 
     updateComplexityText();
-    mComplexityChangedSignal = gSavedSettings.getControl("IndirectMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this));
+    mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this));
     mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxComplexity, this));
 
     LLAvatarComplexityControls::setIndirectMaxArc();
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index a0a0b3c874..8342fecaa9 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -317,6 +317,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 
 	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
 
+    mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateComplexityText, this));
+
 	mCommitCallbackRegistrar.add("Pref.ClearLog",				boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
 	mCommitCallbackRegistrar.add("Pref.DeleteTranscripts",      boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
 	mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // <FS:ND/> Hook up for filtering
@@ -484,6 +486,7 @@ void LLFloaterPreference::onDoNotDisturbResponseChanged()
 LLFloaterPreference::~LLFloaterPreference()
 {
 	LLConversationLog::instance().removeObserver(this);
+    mComplexityChangedSignal.disconnect();
 }
 
 void LLFloaterPreference::draw()
@@ -1499,14 +1502,12 @@ void LLFloaterPreference::updateMaxComplexity()
     LLAvatarComplexityControls::updateMax(
         getChild<LLSliderCtrl>("IndirectMaxComplexity"),
         getChild<LLTextBox>("IndirectMaxComplexityText"));
+}
 
-    LLFloaterPreferenceGraphicsAdvanced* floater_graphics_advanced = LLFloaterReg::findTypedInstance<LLFloaterPreferenceGraphicsAdvanced>("prefs_graphics_advanced");
-    if (floater_graphics_advanced)
-    {
-        LLAvatarComplexityControls::updateMax(
-            floater_graphics_advanced->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
-            floater_graphics_advanced->getChild<LLTextBox>("IndirectMaxComplexityText"));
-    }
+void LLFloaterPreference::updateComplexityText()
+{
+    LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
+        getChild<LLTextBox>("IndirectMaxComplexityText", true));
 }
 
 bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 23d3f73d70..b3ecb17fd8 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -201,6 +201,7 @@ private:
 	void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
 	void updateDeleteTranscriptsButton();
 	void updateMaxComplexity();
+    void updateComplexityText();
 	static bool loadFromFilename(const std::string& filename, std::map<std::string, std::string> &label_map);
 
 	static std::string sSkin;
@@ -222,6 +223,8 @@ private:
 	LLSearchEditor *mFilterEdit;
 	std::unique_ptr< ll::prefs::SearchData > mSearchData;
 
+    boost::signals2::connection	mComplexityChangedSignal;
+
 	void onUpdateFilterTerm( bool force = false );
 	void collectSearchableItems();
 };
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index 404cdf5280..af5296117b 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -54,6 +54,7 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
 
 LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
 {
+    mComplexityChangedSignal.disconnect();
 }
 
 BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
@@ -73,6 +74,8 @@ BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
     use_HiDPI->setVisible(FALSE);
 #endif
 
+    mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this));
+
     return TRUE;
 }
 
@@ -150,14 +153,12 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity()
     LLAvatarComplexityControls::updateMax(
         getChild<LLSliderCtrl>("IndirectMaxComplexity"),
         getChild<LLTextBox>("IndirectMaxComplexityText"));
+}
 
-    LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
-    if (floater_preferences)
-    {
-        LLAvatarComplexityControls::updateMax(
-            floater_preferences->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
-            floater_preferences->getChild<LLTextBox>("IndirectMaxComplexityText"));
-    }
+void LLFloaterPreferenceGraphicsAdvanced::updateComplexityText()
+{
+    LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
+        getChild<LLTextBox>("IndirectMaxComplexityText", true));
 }
 
 void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
index 3e9046eba9..c5d21ba35b 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.h
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
@@ -47,7 +47,7 @@ public:
     void updateMaxNonImpostors();
     void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
     void updateMaxComplexity();
-    void setMaxComplexityText(U32 value, LLTextBox* text_box);
+    void updateComplexityText();
     void refresh();
     // callback for when client modifies a render option
     void onRenderOptionEnable();
@@ -57,6 +57,8 @@ public:
 protected:	
     void		onBtnOK(const LLSD& userdata);
     void		onBtnCancel(const LLSD& userdata);
+
+    boost::signals2::connection	mComplexityChangedSignal;
 };
 
 #endif //LLFLOATERPREFERENCEGRAPHICSADVANCED_H
-- 
cgit v1.2.3


From 5d73bbef002378f6367807b2a64061f403a840eb Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 2 Aug 2021 14:21:13 +0300
Subject: SL-15736 Show checkmark in the menu while Improve Graphics Speed
 floater is open

---
 indra/newview/skins/default/xui/en/menu_viewer.xml | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b1adf97444..9c27fb05db 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -853,13 +853,16 @@
                parameter="UseDebugMenus" />
           </menu_item_check>
         </menu>
-        <menu_item_call
+        <menu_item_check
           label="Improve graphics speed..."
           name="Performance">
-          <menu_item_call.on_click
+          <menu_item_check.on_click
            function="Floater.Toggle"
            parameter="performance" />
-        </menu_item_call>
+          <menu_item_check.on_check
+           function="Floater.Visible"
+           parameter="performance" />
+        </menu_item_check>
         <menu_item_separator/>
     <!--    <menu_item_check
          label="Show Navigation Bar"
-- 
cgit v1.2.3


From 7c0993ef9eafedbcb83ac9ced1ac1ef83bdd02f5 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 2 Aug 2021 14:38:44 +0300
Subject: SL-15737 remove context menu for self in "Avatars nearby" list

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

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 689205575b..e53154dd75 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -554,7 +554,7 @@ void LLFloaterPerformance::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
     list->selectItemAt(x, y, MASK_NONE);
     uuid_vec_t selected_uuids;
 
-    if(list->getCurrentID().notNull())
+    if((list->getCurrentID().notNull()) && (list->getCurrentID() != gAgentID))
     {
         selected_uuids.push_back(list->getCurrentID());
         mContextMenu->show(ctrl, selected_uuids, x, y);
-- 
cgit v1.2.3


From e7d00efbcbb1640d134b87baa4104f3147a795f4 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 2 Aug 2021 17:29:10 +0300
Subject: SL-15738 FIXED Nametags are visible after "Hide avatars completely"
 then name tags set to Off.

---
 indra/newview/llvoavatar.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 86322e8421..6579feb737 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2538,7 +2538,11 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
 	if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
 		&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")) && !isSelf())
 	{
-		return;
+        if (!mIsControlAvatar)
+        {
+            idleUpdateNameTag( mLastRootPos );
+        }
+        return;
 	}
 
     // Update should be happening max once per frame.
@@ -3148,11 +3152,9 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 	const F32 time_visible = mTimeVisible.getElapsedTimeF32();
 	const F32 NAME_SHOW_TIME = gSavedSettings.getF32("RenderNameShowTime");	// seconds
 	const F32 FADE_DURATION = gSavedSettings.getF32("RenderNameFadeDuration"); // seconds
-	BOOL visible_avatar = isVisible() || mNeedsAnimUpdate;
 	BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping);
 	BOOL render_name =	visible_chat ||
-		(visible_avatar &&
-		 ((sRenderName == RENDER_NAME_ALWAYS) ||
+		(((sRenderName == RENDER_NAME_ALWAYS) ||
 		  (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
 	// If it's your own avatar, don't draw in mouselook, and don't
 	// draw if we're specifically hiding our own name.
-- 
cgit v1.2.3


From 81170e9fc138232f94c12a3cdd9e7f10e35868dd Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 8 Sep 2021 15:32:10 +0300
Subject: SL-15954 FIXED  'Hide avatars completely' doesn't hide attached
 animeshes

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

(limited to 'indra/newview')

diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 687b13d2c8..eb0bd0de4e 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1526,7 +1526,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 	}
 
 	LLVOAvatar *attached_av = avatarp->getAttachedAvatar();
-	if (attached_av && LLVOAvatar::AOA_NORMAL != attached_av->getOverallAppearance())
+	if (attached_av && (LLVOAvatar::AOA_NORMAL != attached_av->getOverallAppearance() || !gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
 	{
 		// Animesh attachment of a jellydolled or invisible parent - don't show
 		return;
-- 
cgit v1.2.3


From f145d0dbe1d1f28c3e874b77b965e6e07066f39a Mon Sep 17 00:00:00 2001
From: Runitai Linden <davep@lindenlab.com>
Date: Fri, 21 Jan 2022 16:18:54 -0600
Subject: SL-16447 Adjust default graphics preferences based on modern memory
 bandwidth levels and bias settings based on CPU speed.

---
 indra/newview/app_settings/settings.xml | 22 ++++++++++++++++++++++
 indra/newview/llfeaturemanager.cpp      | 17 ++++++++++++-----
 indra/newview/llglsandbox.cpp           |  1 +
 3 files changed, 35 insertions(+), 5 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 0ccf74e923..60c415bc9e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8770,6 +8770,28 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+  <key>RenderClass0MemoryBandwidth</key>
+  <map>
+    <key>Comment</key>
+    <string>Memory bandwidth at which to default to Class 0 in gigabytes per second.  Used as basis for other classes.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>16.0</real>
+  </map>
+  <key>RenderCPUBasis</key>
+  <map>
+    <key>Comment</key>
+    <string>Reference CPU clockspeed to use to bias GPU class (in MHz).</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>3000.0</real>
+  </map>
   <key>RenderComplexityColorMin</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 3240f169b3..c3780e42c6 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -402,6 +402,7 @@ bool LLFeatureManager::loadGPUClass()
 {
 	if (!gSavedSettings.getBOOL("SkipBenchmark"))
 	{
+        F32 class0_gbps = gSavedSettings.getF32("RenderClass0MemoryBandwidth");
 		//get memory bandwidth from benchmark
 		F32 gbps;
 		try
@@ -418,6 +419,12 @@ bool LLFeatureManager::loadGPUClass()
 			LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL;
 		}
 	
+        // bias by CPU speed
+        F32 cpu_basis_mhz = gSavedSettings.getF32("RenderCPUBasis");
+        F32 cpu_mhz = (F32) gSysCPU.getMHz();
+        F32 cpu_bias = llclamp(cpu_mhz / cpu_basis_mhz, 0.5f, 1.f);
+        gbps *= cpu_bias;
+
 		if (gbps < 0.f)
 		{ //couldn't bench, use GLVersion
 	#if LL_DARWIN
@@ -460,23 +467,23 @@ bool LLFeatureManager::loadGPUClass()
 		{
 			mGPUClass = GPU_CLASS_1;
 		}
-		else if (gbps <= 5.f)
+		else if (gbps <= class0_gbps)
 		{
 			mGPUClass = GPU_CLASS_0;
 		}
-		else if (gbps <= 8.f)
+		else if (gbps <= class0_gbps*2.f)
 		{
 			mGPUClass = GPU_CLASS_1;
 		}
-		else if (gbps <= 16.f)
+		else if (gbps <= class0_gbps*4.f)
 		{
 			mGPUClass = GPU_CLASS_2;
 		}
-		else if (gbps <= 40.f)
+		else if (gbps <= class0_gbps*8.f)
 		{
 			mGPUClass = GPU_CLASS_3;
 		}
-		else if (gbps <= 80.f)
+		else if (gbps <= class0_gbps*16.f)
 		{
 			mGPUClass = GPU_CLASS_4;
 		}
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 175f1849cf..0c8e248538 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -984,6 +984,7 @@ private:
 
 //-----------------------------------------------------------------------------
 // gpu_benchmark()
+//  returns measured memory bandwidth of GPU in gigabytes per second
 //-----------------------------------------------------------------------------
 F32 gpu_benchmark()
 {
-- 
cgit v1.2.3


From 374a516d97af2255206374c001ba20c8069685b6 Mon Sep 17 00:00:00 2001
From: Runitai Linden <davep@lindenlab.com>
Date: Fri, 21 Jan 2022 16:43:49 -0600
Subject: SL-16683 Adjust max number of non-impostored avatars and mesh
 geometry detail based on graphics settings preset.

---
 indra/newview/featuretable.txt     | 14 ++++++++++----
 indra/newview/featuretable_mac.txt | 14 ++++++++++----
 2 files changed, 20 insertions(+), 8 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 4e56141fde..a5e0e395de 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -113,6 +113,7 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	0.5
 RenderAvatarMaxComplexity   1	100000
 RenderAvatarPhysicsLODFactor 1	0.75
+RenderAvatarMaxNonImpostors 1   5
 RenderFarClip				1	96
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	8
@@ -142,6 +143,7 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	200000
 RenderAvatarPhysicsLODFactor 1	1.0
+RenderAvatarMaxNonImpostors 1   7
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
@@ -153,7 +155,7 @@ RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
-RenderVolumeLODFactor		1	1.125
+RenderVolumeLODFactor		1	1.25
 WindLightUseAtmosShaders	1	1
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
@@ -171,6 +173,7 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	250000
 RenderAvatarPhysicsLODFactor 1	1.0
+RenderAvatarMaxNonImpostors 1   9
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
@@ -182,7 +185,7 @@ RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
-RenderVolumeLODFactor		1	1.125
+RenderVolumeLODFactor		1	1.375
 WindLightUseAtmosShaders	1	1
 RenderDeferred				1	1
 RenderDeferredSSAO			1	0
@@ -200,6 +203,7 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	300000
 RenderAvatarPhysicsLODFactor 1	1.0
+RenderAvatarMaxNonImpostors 1   11
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
@@ -211,7 +215,7 @@ RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
-RenderVolumeLODFactor		1	1.125
+RenderVolumeLODFactor		1	1.5
 WindLightUseAtmosShaders	1	1
 RenderDeferred				1	1
 RenderDeferredSSAO			1	1
@@ -229,6 +233,7 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	350000
 RenderAvatarPhysicsLODFactor 1	1.0
+RenderAvatarMaxNonImpostors 1   16
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
@@ -240,7 +245,7 @@ RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
-RenderVolumeLODFactor		1	1.125
+RenderVolumeLODFactor		1	1.75
 WindLightUseAtmosShaders	1	1
 RenderDeferred				1	1
 RenderDeferredSSAO			1	1
@@ -256,6 +261,7 @@ list Ultra
 RenderAnisotropic			1	1
 RenderAvatarCloth			1	1
 RenderAvatarLODFactor		1	1.0
+RenderAvatarMaxNonImpostors 1   16
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderFarClip				1	256
 RenderFlexTimeFactor		1	1.0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 13ede23a91..5140614bab 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -112,6 +112,7 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	0.5
 RenderAvatarMaxComplexity   1	100000
 RenderAvatarPhysicsLODFactor 1	0.75
+RenderAvatarMaxNonImpostors 1   5
 RenderFarClip				1	96
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	8
@@ -141,6 +142,7 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	200000
 RenderAvatarPhysicsLODFactor 1	1.0
+RenderAvatarMaxNonImpostors 1   7
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
@@ -152,7 +154,7 @@ RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
-RenderVolumeLODFactor		1	1.125
+RenderVolumeLODFactor		1	1.25
 WindLightUseAtmosShaders	1	1
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
@@ -170,6 +172,7 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	250000
 RenderAvatarPhysicsLODFactor 1	1.0
+RenderAvatarMaxNonImpostors 1   9
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
@@ -181,7 +184,7 @@ RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
-RenderVolumeLODFactor		1	1.125
+RenderVolumeLODFactor		1	1.375
 WindLightUseAtmosShaders	1	1
 RenderDeferred				1	1
 RenderDeferredSSAO			1	0
@@ -199,6 +202,7 @@ RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
 RenderAvatarMaxComplexity   1	300000
 RenderAvatarPhysicsLODFactor 1	1.0
+RenderAvatarMaxNonImpostors 1   11
 RenderFarClip				1	128
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
@@ -210,7 +214,7 @@ RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
-RenderVolumeLODFactor		1	1.125
+RenderVolumeLODFactor		1	1.5
 WindLightUseAtmosShaders	1	1
 RenderDeferred				1	1
 RenderDeferredSSAO			1	1
@@ -226,6 +230,7 @@ list HighUltra
 RenderAnisotropic			1	1
 RenderAvatarCloth			1	0
 RenderAvatarLODFactor		1	1.0
+RenderAvatarMaxNonImpostors 1   16
 RenderAvatarMaxComplexity   1	350000
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderFarClip				1	128
@@ -239,7 +244,7 @@ RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
 RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
-RenderVolumeLODFactor		1	1.125
+RenderVolumeLODFactor		1	1.75
 WindLightUseAtmosShaders	1	1
 RenderDeferred				1	1
 RenderDeferredSSAO			1	1
@@ -256,6 +261,7 @@ RenderAnisotropic			1	1
 RenderAvatarCloth			1	1
 RenderAvatarLODFactor		1	1.0
 RenderAvatarPhysicsLODFactor 1	1.0
+RenderAvatarMaxNonImpostors 1   16
 RenderFarClip				1	256
 RenderFlexTimeFactor		1	1.0
 RenderGlowResolutionPow		1	9
-- 
cgit v1.2.3


From d7603ffc9c94a6cdab94bc23745903c7fff25ff1 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 24 Jan 2022 16:33:44 +0200
Subject: SL-16627 AutoFPS first pass

---
 indra/newview/app_settings/settings.xml            |  57 ++++++++++
 indra/newview/llagent.cpp                          |   4 +
 indra/newview/llfloaterperformance.cpp             |  50 ++++-----
 indra/newview/llfloaterperformance.h               |   4 +-
 indra/newview/llfloaterpreference.cpp              |  18 ++++
 indra/newview/llfloaterpreference.h                |   2 +
 .../llfloaterpreferencesgraphicsadvanced.cpp       |  37 ++++++-
 .../newview/llfloaterpreferencesgraphicsadvanced.h |   2 +
 indra/newview/llviewerdisplay.cpp                  |   2 +
 indra/newview/llworld.cpp                          |  27 +++++
 indra/newview/llworld.h                            |   3 +
 indra/newview/pipeline.cpp                         | 120 ++++++++++++++++++++-
 indra/newview/pipeline.h                           |   6 +-
 .../en/floater_preferences_graphics_advanced.xml   |   9 +-
 .../newview/skins/default/xui/en/notifications.xml |  13 +++
 .../xui/en/panel_performance_preferences.xml       |   5 +-
 .../default/xui/en/panel_preferences_graphics1.xml |  19 +++-
 17 files changed, 337 insertions(+), 41 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 0ccf74e923..442ac8895c 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16620,6 +16620,63 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>AutoFPS</key>
+    <map>
+      <key>Comment</key>
+      <string>
+        Allow dynamic adjustment of graphics preferences
+      </string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+  <key>AutoAdjustmentTimeout</key>
+  <map>
+    <key>Comment</key>
+    <string>Time before next iteration of automatic adjustments</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>5</real>
+  </map>
+  <key>InitialAdjustmentTimeout</key>
+  <map>
+    <key>Comment</key>
+    <string>Time before first iteration of automatic adjustments after login to the world, teleporting, maximizing Viewer etc.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>10</real>
+  </map>
+  <key>AutoFPSLowerBoundary</key>
+  <map>
+    <key>Comment</key>
+    <string>FPS lower boundary when automatic adjustments are occured to reduce graphics quality to increase FPS</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>S32</string>
+    <key>Value</key>
+    <real>30</real>
+  </map>
+  <key>AutoFPSUpperBoundary</key>
+  <map>
+    <key>Comment</key>
+    <string>FPS upper boundary when automatic adjustments are occured to increase graphics quality</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>S32</string>
+    <key>Value</key>
+    <real>50</real>
+  </map>
   <key>CameraOpacity</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index de382d4e23..b377d099be 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -4078,6 +4078,8 @@ void LLAgent::handleTeleportFinished()
             mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));
         }
     }
+
+    gPipeline.setAdjustmentTimerExpiry(gSavedSettings.getF32("InitialAdjustmentTimeout"));
 }
 
 void LLAgent::handleTeleportFailed()
@@ -4109,6 +4111,8 @@ void LLAgent::handleTeleportFailed()
 	}
 
     mTPNeedsNeabyChatSeparator = false;
+
+    gPipeline.setAdjustmentTimerExpiry(gSavedSettings.getF32("InitialAdjustmentTimeout"));
 }
 
 /*static*/
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index e53154dd75..e44c161b27 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -36,13 +36,15 @@
 #include "llfloaterpreference.h" // LLAvatarComplexityControls
 #include "llfloaterreg.h"
 #include "llnamelistctrl.h"
+#include "llnotificationsutil.h"
 #include "llradiogroup.h"
 #include "llsliderctrl.h"
 #include "lltextbox.h"
 #include "lltrans.h"
 #include "llviewerobjectlist.h"
 #include "llvoavatar.h"
-#include "llvoavatarself.h" 
+#include "llvoavatarself.h"
+#include "llworld.h"
 #include "pipeline.h"
 
 const F32 REFRESH_INTERVAL = 1.0f;
@@ -77,6 +79,8 @@ LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
     mNearbyMaxComplexity(0)
 {
     mContextMenu = new LLExceptionsContextMenu(this);
+
+    mCommitCallbackRegistrar.add("Pref.MouseDown", boost::bind(&LLFloaterPerformance::onUICtrlMouseDown, this));
 }
 
 LLFloaterPerformance::~LLFloaterPerformance()
@@ -328,7 +332,7 @@ void LLFloaterPerformance::populateNearbyList()
 
     static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
     std::vector<LLCharacter*> valid_nearby_avs;
-    getNearbyAvatars(valid_nearby_avs);
+    mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
 
     std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
     while (char_iter != valid_nearby_avs.end())
@@ -401,31 +405,6 @@ void LLFloaterPerformance::populateNearbyList()
     mNearbyList->selectByID(prev_selected_id);
 }
 
-void LLFloaterPerformance::getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs)
-{
-    static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
-    mNearbyMaxComplexity = 0;
-    F32 radius = render_far_clip * render_far_clip;
-    std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
-    while (char_iter != LLCharacter::sInstances.end())
-    {
-        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
-        if (avatar && !avatar->isDead() && !avatar->isControlAvatar())
-        {
-            if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
-                (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius))
-            {
-                char_iter++;
-                continue;
-            }
-            avatar->calculateUpdateRenderComplexity();
-            mNearbyMaxComplexity = llmax(mNearbyMaxComplexity, (S32)avatar->getVisualComplexity());
-            valid_nearby_avs.push_back(*char_iter);
-        }
-        char_iter++;
-    }
-}
-
 void LLFloaterPerformance::detachItem(const LLUUID& item_id)
 {
     LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
@@ -561,4 +540,21 @@ void LLFloaterPerformance::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
     }
 }
 
+void LLFloaterPerformance::onUICtrlMouseDown()
+{
+    static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
+    if (use_auto_adjust)
+    {
+        LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
+            [this](const LLSD&notif, const LLSD&resp)
+        {
+            S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+            if (opt == 0)
+            {
+                gSavedSettings.setBOOL("AutoFPS", FALSE);
+            }
+        });
+    }
+}
+
 // EOF
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index a5549685f6..7a1394c51b 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -63,11 +63,11 @@ private:
     void onClickHideAvatars();
     void onClickExceptions();
 
+    void onUICtrlMouseDown();
+
     void updateMaxComplexity();
     void updateComplexityText();
 
-    void getNearbyAvatars(std::vector<LLCharacter*> &valid_nearby_avs);
-
     LLPanel* mMainPanel;
     LLPanel* mNearbyPanel;
     LLPanel* mComplexityPanel;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 8ea5519929..fbc3275b1e 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -304,6 +304,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.RememberedUsernames",    boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
 	mCommitCallbackRegistrar.add("Pref.SpellChecker",           boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
 	mCommitCallbackRegistrar.add("Pref.Advanced",				boost::bind(&LLFloaterPreference::onClickAdvanced, this));
+    mCommitCallbackRegistrar.add("Pref.MouseDown",				boost::bind(&LLFloaterPreference::onUICtrlMouseDown, this));
 
 	sSkin = gSavedSettings.getString("SkinCurrent");
 
@@ -1782,6 +1783,23 @@ void LLFloaterPreference::updateSearchableItems()
     mSearchDataDirty = true;
 }
 
+void LLFloaterPreference::onUICtrlMouseDown()
+{
+    static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
+    if (use_auto_adjust)
+    {
+        LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
+            [this](const LLSD&notif, const LLSD&resp)
+        {
+            S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+            if (opt == 0)
+            {
+                gSavedSettings.setBOOL("AutoFPS", FALSE);
+            }
+        });
+    }
+}
+
 void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
 {
 	LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 788db960f0..8a68f9f279 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -110,6 +110,8 @@ public:
 	void updateClickActionViews();
     void updateSearchableItems();
 
+    void onUICtrlMouseDown();
+
     void		onBtnOK(const LLSD& userdata);
     void		onBtnCancel(const LLSD& userdata);
 
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index af5296117b..fdc36077a8 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -32,6 +32,7 @@
 #include "llfeaturemanager.h"
 #include "llfloaterpreference.h"
 #include "llfloaterreg.h"
+#include "llnotificationsutil.h"
 #include "llsliderctrl.h"
 #include "lltextbox.h"
 #include "lltrans.h"
@@ -48,8 +49,12 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
     mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
     mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",   boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
 
+    mCommitCallbackRegistrar.add("Pref.MouseDown", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onUICtrlMouseDown, this));
+
     mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
     mCommitCallbackRegistrar.add("Pref.OK",     boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
+
+    gSavedSettings.getControl("RenderAvatarMaxNonImpostors")->getSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors, this, _2));
 }
 
 LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
@@ -190,6 +195,23 @@ void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, L
     }
 }
 
+void LLFloaterPreferenceGraphicsAdvanced::onUICtrlMouseDown()
+{
+    static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
+    if (use_auto_adjust)
+    {
+        LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
+            [this](const LLSD&notif, const LLSD&resp)
+        {
+            S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+            if (opt == 0)
+            {
+                gSavedSettings.setBOOL("AutoFPS", FALSE);
+            }
+        });
+    }
+}
+
 void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
 {
     // Called when the IndirectMaxNonImpostors control changes
@@ -206,6 +228,16 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
     setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
 }
 
+void LLFloaterPreferenceGraphicsAdvanced::updateIndirectMaxNonImpostors(const LLSD& newvalue)
+{
+    U32 value = newvalue.asInteger();
+    if ((value != 0) && (value != gSavedSettings.getU32("IndirectMaxNonImpostors")))
+    {
+        gSavedSettings.setU32("IndirectMaxNonImpostors", value);
+        setMaxNonImpostorsText(value, getChild<LLTextBox>("IndirectMaxNonImpostorsText"));
+    }
+}
+
 void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTextBox* text_box)
 {
     if (0 == value)
@@ -340,9 +372,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
     ctrl_reflections->setEnabled(reflections);
     reflections_text->setEnabled(reflections);
 
-    // Transparent Water
-    LLCheckBoxCtrl* transparent_water_ctrl = getChild<LLCheckBoxCtrl>("TransparentWater");
-
     // Bump & Shiny	
     LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
     bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
@@ -393,9 +422,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
 
     BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
         ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
-        ((transparent_water_ctrl && transparent_water_ctrl->get()) ? TRUE : FALSE) &&
         gGLManager.mHasFramebufferObject &&
-        gSavedSettings.getBOOL("RenderAvatarVP") &&
         (ctrl_wind_light->get()) ? TRUE : FALSE;
 
     ctrl_deferred->setEnabled(enabled);
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
index c5d21ba35b..cf3ed02614 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.h
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
@@ -45,6 +45,8 @@ public:
     void refreshEnabledState();
     void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
     void updateMaxNonImpostors();
+    void updateIndirectMaxNonImpostors(const LLSD& newvalue);
+    void onUICtrlMouseDown();
     void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
     void updateMaxComplexity();
     void updateComplexityText();
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index b5d3dc5d30..a26331251c 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1024,6 +1024,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		gPipeline.clearReferences();
 
 		gPipeline.rebuildGroups();
+
+        gPipeline.autoAdjustSettings();
 	}
 
 	LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 6746a3a902..0a2ad82354 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -33,6 +33,7 @@
 #include "llstl.h"
 
 #include "llagent.h"
+#include "llagentcamera.h"
 #include "llviewercontrol.h"
 #include "lldrawpool.h"
 #include "llglheaders.h"
@@ -1396,6 +1397,32 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
 	}
 }
 
+S32 LLWorld::getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs)
+{
+    static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
+    S32 nearby_max_complexity = 0;
+    F32 radius = render_far_clip * render_far_clip;
+    std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
+    while (char_iter != LLCharacter::sInstances.end())
+    {
+        LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
+        if (avatar && !avatar->isDead() && !avatar->isControlAvatar())
+        {
+            if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
+                (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius))
+            {
+                char_iter++;
+                continue;
+            }
+            avatar->calculateUpdateRenderComplexity();
+            nearby_max_complexity = llmax(nearby_max_complexity, (S32)avatar->getVisualComplexity());
+            valid_nearby_avs.push_back(*char_iter);
+        }
+        char_iter++;
+    }
+    return nearby_max_complexity;
+}
+
 bool LLWorld::isRegionListed(const LLViewerRegion* region) const
 {
 	region_list_t::const_iterator it = find(mRegionList.begin(), mRegionList.end(), region);
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index 69f2df4203..1c12ad0e2c 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -51,6 +51,7 @@ class LLHost;
 class LLViewerObject;
 class LLSurfacePatch;
 
+class LLCharacter;
 class LLCloudPuff;
 class LLCloudGroup;
 class LLVOAvatar;
@@ -172,6 +173,8 @@ public:
 	// or if the circuit to this simulator had been lost.
 	bool isRegionListed(const LLViewerRegion* region) const;
 
+    S32 getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs);
+
 private:
 	region_list_t	mActiveRegionList;
 	region_list_t	mRegionList;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index dd9999d73a..96dd0b895d 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -43,6 +43,7 @@
 #include "llui.h" 
 #include "llglheaders.h"
 #include "llrender.h"
+#include "llstartup.h"
 #include "llwindow.h"	// swapBuffers()
 
 // newview includes
@@ -405,7 +406,8 @@ LLPipeline::LLPipeline() :
 	mLightMovingMask(0),
 	mLightingDetail(0),
 	mScreenWidth(0),
-	mScreenHeight(0)
+	mScreenHeight(0),
+    mUpdateTimer(new LLTimer())
 {
 	mNoiseMap = 0;
 	mTrueNoiseMap = 0;
@@ -613,7 +615,7 @@ void LLPipeline::init()
 
 LLPipeline::~LLPipeline()
 {
-
+    delete mUpdateTimer;
 }
 
 void LLPipeline::cleanup()
@@ -11428,3 +11430,117 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
 	}
 }
 
+const F32 MIN_DRAW_DISTANCE = 64;
+const F32 MAX_DRAW_DISTANCE = 256;
+
+void update_far_clip(F32 fps_dif)
+{
+    F32 DIST_PER_FRAME_DIF = 16;
+
+    F32 new_far_clip = llclamp(LLPipeline::RenderFarClip - llmin(fps_dif * DIST_PER_FRAME_DIF, (F32)128), MIN_DRAW_DISTANCE, MAX_DRAW_DISTANCE);
+    gSavedSettings.setF32("RenderFarClip", new_far_clip);
+}
+
+void update_max_non_impostors(F32 fps_dif, S32 max_avatars)
+{
+    const F32 IMPOSTORS_PER_FRAME_DIF = 0.5;
+
+    U32 new_non_imp = (U32)llclamp((S32)(LLVOAvatar::sMaxNonImpostors - llmin((S32)(fps_dif / IMPOSTORS_PER_FRAME_DIF), 10)), 1, max_avatars);
+    gSavedSettings.setU32("RenderAvatarMaxNonImpostors", new_non_imp);
+}
+
+void LLPipeline::autoAdjustSettings()
+{
+    static LLCachedControl<bool> use_auto_adjustment(gSavedSettings,"AutoFPS");
+    if (!use_auto_adjustment)
+    {
+        return;
+    }
+    
+    if (LLStartUp::getStartupState() < STATE_STARTED || LLApp::isExiting())
+    {
+        return;
+    }
+
+    static LLCachedControl<F32> adjustment_timeout(gSavedSettings, "AutoAdjustmentTimeout");
+    static LLCachedControl<F32> initial_adjustment_timeout(gSavedSettings, "InitialAdjustmentTimeout");
+ 
+    static LLCachedControl<S32> fps_lower_boundary(gSavedSettings, "AutoFPSLowerBoundary");
+    static LLCachedControl<S32> fps_upper_boundary(gSavedSettings, "AutoFPSUpperBoundary");
+
+    if (gViewerWindow && gViewerWindow->getWindow()->getVisible()
+        && gFocusMgr.getAppHasFocus() && !gTeleportDisplay)
+    {
+        static bool is_init = false;
+        if (!is_init)
+        {
+            //wait for FPS to stabilize after login in-world
+            mUpdateTimer->setTimerExpirySec((F32)initial_adjustment_timeout);
+            is_init = true;
+        }
+        if (mUpdateTimer->hasExpired())
+        {
+            mUpdateTimer->setTimerExpirySec((F32)adjustment_timeout);
+
+            const S32 FPS_STAT_PERIODS = 50;
+            S32 fps = (S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, FPS_STAT_PERIODS));
+            if (fps < fps_lower_boundary)
+            {
+                S32 fps_dif = fps_lower_boundary - fps;
+                
+                if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0)
+                {
+                    S32 shadow_detail = RenderShadowDetail - 1;
+                    gSavedSettings.setS32("RenderShadowDetail", shadow_detail);
+                    return;
+                }
+                
+                if (RenderFarClip > MIN_DRAW_DISTANCE)
+                {
+                    update_far_clip(fps_dif);
+                }
+
+                std::vector<LLCharacter*> valid_nearby_avs;
+                LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
+
+                if (valid_nearby_avs.size() > 1 && LLVOAvatar::sMaxNonImpostors > 1) 
+                {
+                    update_max_non_impostors(fps_dif, valid_nearby_avs.size());
+                }
+            }
+            else if (fps > fps_upper_boundary)
+            {
+                S32 fps_dif = fps_upper_boundary - fps;
+
+                std::vector<LLCharacter*> valid_nearby_avs;
+                LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
+                if (valid_nearby_avs.size() > 1 && (LLVOAvatar::sMaxNonImpostors < valid_nearby_avs.size()))
+                {
+                    update_max_non_impostors(fps_dif, valid_nearby_avs.size());
+                    return;
+                }
+                
+                if (RenderFarClip < MAX_DRAW_DISTANCE)
+                {
+                    update_far_clip(fps_dif);
+                }
+
+                if (LLPipeline::sRenderDeferred && RenderShadowDetail < 2)
+                {
+                    S32 shadow_detail = RenderShadowDetail + 1;
+                    gSavedSettings.setS32("RenderShadowDetail", shadow_detail);
+                }
+            }
+        }
+    }
+    else
+    {
+        //wait for FPS to stabilize if the window was minimized or not focused before
+        mUpdateTimer->setTimerExpirySec((F32)initial_adjustment_timeout);
+    }
+}
+
+void LLPipeline::setAdjustmentTimerExpiry(F32 expiration)
+{
+    mUpdateTimer->setTimerExpirySec(expiration);
+}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index fdc3738472..7eff573a34 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -424,6 +424,9 @@ public:
 	void hideObject( const LLUUID& id );
 	void restoreHiddenObject( const LLUUID& id );
 
+    void autoAdjustSettings();
+    void setAdjustmentTimerExpiry(F32 expiration);
+
 private:
 	void unloadShaders();
 	void addToQuickLookup( LLDrawPool* new_poolp );
@@ -715,7 +718,8 @@ protected:
 	U64						mOldRenderDebugMask;
 	std::stack<U32>			mRenderDebugFeatureStack;
 
-	
+    LLTimer* mUpdateTimer;
+
 	/////////////////////////////////////////////
 	//
 	//
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 d1e167df64..5978ae685a 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
@@ -39,7 +39,10 @@
     max_val="512"
     name="DrawDistance"
     top_delta="16"
-    width="330" />
+    width="330">
+    <slider.mouse_down_callback
+      function="Pref.MouseDown" />
+    </slider>
   <text
     type="string"
     length="1"
@@ -182,6 +185,8 @@
     <slider.commit_callback
       function="Pref.UpdateIndirectMaxNonImpostors"
       parameter="IndirectNonImpostorsText" />
+    <slider.mouse_down_callback
+      function="Pref.MouseDown" />
   </slider>
   <text
     type="string"
@@ -850,6 +855,8 @@
    top_delta="0" 
    name="ShadowDetail"
    width="150">
+    <combo_box.mouse_down_callback
+ function="Pref.MouseDown" />
      <combo_box.item
        label="None"
        name="0"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index d4f71fb370..2fed214d69 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1847,6 +1847,19 @@ Graphics Quality can be raised in Preferences &gt; Graphics.
   <tag>fail</tag>
   </notification>
 
+  <notification
+ icon="alertmodal.tga"
+ name="AutoFPSConfirmDisable"
+ type="alertmodal">
+    Changing this setting will disable automatic adjustment and turn off 'Auto FPS' setting.
+Are you sure you want to continue?
+    <tag>confirm</tag>
+    <usetemplate
+     name="okcancelbuttons"
+     notext="Cancel"
+     yestext="Continue"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="RegionNoTerraforming"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index 221dfa0222..60792c2f7d 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -206,7 +206,10 @@
     max_val="512"
     name="draw_distance"
     left_pad="5"
-    width="250" />
+    width="250">
+    <slider.mouse_down_callback
+      function="Pref.MouseDown" />
+  </slider>
   <text
     type="string"
     length="1"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 5aff7a5127..6e4a1a6859 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -217,7 +217,10 @@
     max_val="512"
     name="DrawDistance"
     top_delta="40"
-    width="330" />
+    width="330">
+    <slider.mouse_down_callback
+      function="Pref.MouseDown" />
+  </slider>
   <text
     type="string"
     length="1"
@@ -258,6 +261,18 @@
     <check_box.commit_callback
       function="Pref.RenderOptionUpdate" />
   </check_box>
+
+  <check_box
+    control_name="AutoFPS"
+    height="16"
+    initial_value="true"
+    label="Auto FPS"
+    layout="topleft"
+    left="30"
+    name="AutoFPS"
+    top_delta="30"
+    width="256">
+  </check_box>
   
   <slider
     control_name="IndirectMaxComplexity"
@@ -274,7 +289,7 @@
     max_val="101"
     name="IndirectMaxComplexity"
     show_text="false"
-    top_delta="60"
+    top_delta="34"
     width="300">
     <slider.commit_callback
       function="Pref.UpdateIndirectMaxComplexity"
-- 
cgit v1.2.3


From 5146e9564114460bb24500b40ebcf828ff329e04 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 24 Jan 2022 18:38:25 +0200
Subject: SL-16627 build fix

---
 indra/newview/llfloaterperformance.cpp                 | 2 +-
 indra/newview/llfloaterpreference.cpp                  | 2 +-
 indra/newview/llfloaterpreferencesgraphicsadvanced.cpp | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index e44c161b27..316b9ab1b6 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -546,7 +546,7 @@ void LLFloaterPerformance::onUICtrlMouseDown()
     if (use_auto_adjust)
     {
         LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
-            [this](const LLSD&notif, const LLSD&resp)
+            [](const LLSD&notif, const LLSD&resp)
         {
             S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
             if (opt == 0)
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index fbc3275b1e..b655a04b14 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1789,7 +1789,7 @@ void LLFloaterPreference::onUICtrlMouseDown()
     if (use_auto_adjust)
     {
         LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
-            [this](const LLSD&notif, const LLSD&resp)
+            [](const LLSD&notif, const LLSD&resp)
         {
             S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
             if (opt == 0)
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index fdc36077a8..548a6eb769 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -201,7 +201,7 @@ void LLFloaterPreferenceGraphicsAdvanced::onUICtrlMouseDown()
     if (use_auto_adjust)
     {
         LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
-            [this](const LLSD&notif, const LLSD&resp)
+            [](const LLSD&notif, const LLSD&resp)
         {
             S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
             if (opt == 0)
-- 
cgit v1.2.3


From 9c7ec66d248369ebfb589a9c84cf951f8d4b93b5 Mon Sep 17 00:00:00 2001
From: Runitai Linden <davep@lindenlab.com>
Date: Mon, 24 Jan 2022 11:04:11 -0600
Subject: SL-16691 Add GPU memory bandwidth to ViewerStats

---
 indra/newview/llfeaturemanager.cpp | 2 ++
 indra/newview/llfeaturemanager.h   | 5 +++++
 indra/newview/llviewerstats.cpp    | 1 +
 3 files changed, 8 insertions(+)

(limited to 'indra/newview')

diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index c3780e42c6..0813057714 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -419,6 +419,8 @@ bool LLFeatureManager::loadGPUClass()
 			LL_WARNS("RenderInit") << "GPU benchmark failed: " << e.what() << LL_ENDL;
 		}
 	
+        mGPUMemoryBandwidth = gbps;
+
         // bias by CPU speed
         F32 cpu_basis_mhz = gSavedSettings.getF32("RenderCPUBasis");
         F32 cpu_mhz = (F32) gSysCPU.getMHz();
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index 42a226cd18..651404d890 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -111,6 +111,10 @@ public:
 
 	EGPUClass getGPUClass() 			{ return mGPUClass; }
 	std::string& getGPUString() 		{ return mGPUString; }
+    
+    // get the measured GPU memory bandwidth in GB/sec
+    // may return 0 of benchmark has not been run or failed to run
+    F32 getGPUMemoryBandwidth() { return mGPUMemoryBandwidth; }
 	BOOL isGPUSupported()				{ return mGPUSupported; }
 	F32 getExpectedGLVersion()			{ return mExpectedGLVersion; }
 	
@@ -162,6 +166,7 @@ protected:
 	S32			mTableVersion;
 	BOOL		mSafe;					// Reinitialize everything to the "safe" mask
 	EGPUClass	mGPUClass;
+    F32         mGPUMemoryBandwidth = 0.f;  // measured memory bandwidth of GPU in GB/second
 	F32			mExpectedGLVersion;		//expected GL version according to gpu table
 	std::string	mGPUString;
 	BOOL		mGPUSupported;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 5ce97c086d..a560778ef4 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -512,6 +512,7 @@ void send_viewer_stats(bool include_preferences)
 
 	system["gpu"] = gpu_desc;
 	system["gpu_class"] = (S32)LLFeatureManager::getInstance()->getGPUClass();
+    system["gpu_memory_bandwidth"] = LLFeatureManager::getInstance()->getGPUMemoryBandwidth();
 	system["gpu_vendor"] = gGLManager.mGLVendorShort;
 	system["gpu_version"] = gGLManager.mDriverVersionVendorString;
 	system["opengl_version"] = gGLManager.mGLVersionString;
-- 
cgit v1.2.3


From b50de181623874ab799fdc31532dffe8f7bc610a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 25 Jan 2022 19:43:32 +0200
Subject: SL-16627 add auto-adjustment warning for affected settings

---
 indra/newview/llfloaterperformance.cpp                | 19 +------------------
 indra/newview/llfloaterperformance.h                  |  2 --
 indra/newview/llfloaterpreference.cpp                 |  4 ++--
 indra/newview/llfloaterpreference.h                   |  2 +-
 .../newview/llfloaterpreferencesgraphicsadvanced.cpp  | 19 +------------------
 indra/newview/llfloaterpreferencesgraphicsadvanced.h  |  1 -
 .../xui/en/floater_preferences_graphics_advanced.xml  |  6 +++---
 .../default/xui/en/panel_performance_preferences.xml  |  2 +-
 .../default/xui/en/panel_preferences_graphics1.xml    |  2 +-
 9 files changed, 10 insertions(+), 47 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 316b9ab1b6..9cb3c4ce66 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -80,7 +80,7 @@ LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
 {
     mContextMenu = new LLExceptionsContextMenu(this);
 
-    mCommitCallbackRegistrar.add("Pref.MouseDown", boost::bind(&LLFloaterPerformance::onUICtrlMouseDown, this));
+    mCommitCallbackRegistrar.add("Pref.AutoAdjustWarning", boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
 }
 
 LLFloaterPerformance::~LLFloaterPerformance()
@@ -540,21 +540,4 @@ void LLFloaterPerformance::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
     }
 }
 
-void LLFloaterPerformance::onUICtrlMouseDown()
-{
-    static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
-    if (use_auto_adjust)
-    {
-        LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
-            [](const LLSD&notif, const LLSD&resp)
-        {
-            S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
-            if (opt == 0)
-            {
-                gSavedSettings.setBOOL("AutoFPS", FALSE);
-            }
-        });
-    }
-}
-
 // EOF
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 7a1394c51b..d8288b0728 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -63,8 +63,6 @@ private:
     void onClickHideAvatars();
     void onClickExceptions();
 
-    void onUICtrlMouseDown();
-
     void updateMaxComplexity();
     void updateComplexityText();
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index b655a04b14..41ae39152b 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -304,7 +304,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.RememberedUsernames",    boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
 	mCommitCallbackRegistrar.add("Pref.SpellChecker",           boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
 	mCommitCallbackRegistrar.add("Pref.Advanced",				boost::bind(&LLFloaterPreference::onClickAdvanced, this));
-    mCommitCallbackRegistrar.add("Pref.MouseDown",				boost::bind(&LLFloaterPreference::onUICtrlMouseDown, this));
+    mCommitCallbackRegistrar.add("Pref.AutoAdjustWarning",				boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
 
 	sSkin = gSavedSettings.getString("SkinCurrent");
 
@@ -1783,7 +1783,7 @@ void LLFloaterPreference::updateSearchableItems()
     mSearchDataDirty = true;
 }
 
-void LLFloaterPreference::onUICtrlMouseDown()
+void LLFloaterPreference::showAutoAdjustWarning()
 {
     static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
     if (use_auto_adjust)
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 8a68f9f279..3e4c853a08 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -110,7 +110,7 @@ public:
 	void updateClickActionViews();
     void updateSearchableItems();
 
-    void onUICtrlMouseDown();
+    static void showAutoAdjustWarning();
 
     void		onBtnOK(const LLSD& userdata);
     void		onBtnCancel(const LLSD& userdata);
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index 548a6eb769..85a0fee143 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -49,7 +49,7 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
     mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
     mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",   boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
 
-    mCommitCallbackRegistrar.add("Pref.MouseDown", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onUICtrlMouseDown, this));
+    mCommitCallbackRegistrar.add("Pref.AutoAdjustWarning", boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
 
     mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
     mCommitCallbackRegistrar.add("Pref.OK",     boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
@@ -195,23 +195,6 @@ void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, L
     }
 }
 
-void LLFloaterPreferenceGraphicsAdvanced::onUICtrlMouseDown()
-{
-    static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
-    if (use_auto_adjust)
-    {
-        LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
-            [](const LLSD&notif, const LLSD&resp)
-        {
-            S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
-            if (opt == 0)
-            {
-                gSavedSettings.setBOOL("AutoFPS", FALSE);
-            }
-        });
-    }
-}
-
 void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
 {
     // Called when the IndirectMaxNonImpostors control changes
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
index cf3ed02614..7f26ff8b00 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.h
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
@@ -46,7 +46,6 @@ public:
     void updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box);
     void updateMaxNonImpostors();
     void updateIndirectMaxNonImpostors(const LLSD& newvalue);
-    void onUICtrlMouseDown();
     void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
     void updateMaxComplexity();
     void updateComplexityText();
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 5978ae685a..65b96d3694 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
@@ -41,7 +41,7 @@
     top_delta="16"
     width="330">
     <slider.mouse_down_callback
-      function="Pref.MouseDown" />
+      function="Pref.AutoAdjustWarning" />
     </slider>
   <text
     type="string"
@@ -186,7 +186,7 @@
       function="Pref.UpdateIndirectMaxNonImpostors"
       parameter="IndirectNonImpostorsText" />
     <slider.mouse_down_callback
-      function="Pref.MouseDown" />
+      function="Pref.AutoAdjustWarning" />
   </slider>
   <text
     type="string"
@@ -856,7 +856,7 @@
    name="ShadowDetail"
    width="150">
     <combo_box.mouse_down_callback
- function="Pref.MouseDown" />
+ function="Pref.AutoAdjustWarning" />
      <combo_box.item
        label="None"
        name="0"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index 60792c2f7d..5fd6af24c1 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -208,7 +208,7 @@
     left_pad="5"
     width="250">
     <slider.mouse_down_callback
-      function="Pref.MouseDown" />
+      function="Pref.AutoAdjustWarning" />
   </slider>
   <text
     type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 6e4a1a6859..f73149e77e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -219,7 +219,7 @@
     top_delta="40"
     width="330">
     <slider.mouse_down_callback
-      function="Pref.MouseDown" />
+      function="Pref.AutoAdjustWarning" />
   </slider>
   <text
     type="string"
-- 
cgit v1.2.3


From 7254795a77a78644eb8ec35cfa0a1af9cae4c3bc Mon Sep 17 00:00:00 2001
From: Runitai Linden <davep@lindenlab.com>
Date: Tue, 25 Jan 2022 13:22:45 -0600
Subject: SL-16699 Increase default cache size to 4GB

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 8712aa7b6e..184ee8daff 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1426,7 +1426,7 @@
       <key>Type</key>
       <string>U32</string>
       <key>Value</key>
-      <integer>1024</integer>
+      <integer>4096</integer>
     </map>
     <key>CacheValidateCounter</key>
     <map>
-- 
cgit v1.2.3


From 7af2d51f57416cb68b435cecfd4eacf5d1a4c9fc Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 4 Feb 2022 12:46:23 +0200
Subject: SL-15923 increase the shortcut level to the minimum required when
 clicking advanced lighting or shadows settings

---
 indra/newview/llfloaterperformance.cpp             | 55 ++++++++++++++++++++++
 indra/newview/llfloaterperformance.h               |  4 ++
 .../newview/skins/default/xui/en/notifications.xml | 28 +++++++++--
 3 files changed, 84 insertions(+), 3 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 9cb3c4ce66..e45d7a0c73 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -32,6 +32,7 @@
 #include "llavataractions.h"
 #include "llavatarrendernotifier.h"
 #include "llcheckboxctrl.h"
+#include "llcombobox.h"
 #include "llfeaturemanager.h"
 #include "llfloaterpreference.h" // LLAvatarComplexityControls
 #include "llfloaterreg.h"
@@ -120,6 +121,8 @@ BOOL LLFloaterPerformance::postBuild()
 
     mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
     mSettingsPanel->getChild<LLRadioGroup>("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2));
+    mSettingsPanel->getChild<LLCheckBoxCtrl>("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this));
+    mSettingsPanel->getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this));
 
     mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
     mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this));
@@ -540,4 +543,56 @@ void LLFloaterPerformance::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
     }
 }
 
+const U32 RENDER_QUALITY_LEVEL = 3;
+void LLFloaterPerformance::changeQualityLevel(const std::string& notif)
+{
+    LLNotificationsUtil::add(notif, LLSD(), LLSD(),
+        [](const LLSD&notif, const LLSD&resp)
+    {
+        S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+        if (opt == 0)
+        {
+            LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+            if (instance)
+            {
+                gSavedSettings.setU32("RenderQualityPerformance", RENDER_QUALITY_LEVEL);
+                instance->onChangeQuality(LLSD((S32)RENDER_QUALITY_LEVEL));
+            }
+        }
+    });
+}
+
+bool is_ALM_available()
+{
+    bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
+    bool shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+    
+    return LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+        bumpshiny &&
+        shaders &&
+        gGLManager.mHasFramebufferObject;
+}
+
+void LLFloaterPerformance::onClickAdvancedLighting()
+{
+    if (!is_ALM_available())
+    {
+        changeQualityLevel("AdvancedLightingConfirm");
+    }
+}
+
+void LLFloaterPerformance::onClickShadows()
+{
+    if (gSavedSettings.getBOOL("AutoFPS"))
+    {
+        LLFloaterPreference::showAutoAdjustWarning();
+    }
+    else
+    {
+        if (!is_ALM_available() || !gSavedSettings.getBOOL("RenderDeferred"))
+        {
+            changeQualityLevel("ShadowsConfirm");
+        }
+    }
+}
 // EOF
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index d8288b0728..9ccb29cd7b 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -62,10 +62,14 @@ private:
     void onChangeQuality(const LLSD& data);
     void onClickHideAvatars();
     void onClickExceptions();
+    void onClickShadows();
+    void onClickAdvancedLighting();
 
     void updateMaxComplexity();
     void updateComplexityText();
 
+    static void changeQualityLevel(const std::string& notif);
+
     LLPanel* mMainPanel;
     LLPanel* mNearbyPanel;
     LLPanel* mComplexityPanel;
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 2fed214d69..e01865a5ea 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1848,9 +1848,9 @@ Graphics Quality can be raised in Preferences &gt; Graphics.
   </notification>
 
   <notification
- icon="alertmodal.tga"
- name="AutoFPSConfirmDisable"
- type="alertmodal">
+   icon="alertmodal.tga"
+   name="AutoFPSConfirmDisable"
+   type="alertmodal">
     Changing this setting will disable automatic adjustment and turn off 'Auto FPS' setting.
 Are you sure you want to continue?
     <tag>confirm</tag>
@@ -1859,6 +1859,28 @@ Are you sure you want to continue?
      notext="Cancel"
      yestext="Continue"/>
   </notification>
+  <notification
+   icon="alertmodal.tga"
+   name="AdvancedLightingConfirm"
+   type="alertmodal">
+To turn on advanced lighting, we need to increase quality to level 4.
+    <tag>confirm</tag>
+  <usetemplate
+   name="okcancelbuttons"
+   notext="Cancel"
+   yestext="OK"/>
+  </notification>
+  <notification
+ icon="alertmodal.tga"
+   name="ShadowsConfirm"
+   type="alertmodal">
+To enable shadows, we need to increase quality to level 4.
+    <tag>confirm</tag>
+    <usetemplate
+     name="okcancelbuttons"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
 
   <notification
    icon="alertmodal.tga"
-- 
cgit v1.2.3


From 95f7b552adf179b47cb74a4e39581e8d9c58dddc Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 14 Feb 2022 18:59:55 +0200
Subject: SL-16841 Skip rendering shadows when decreasing shadow detail setting
 to avoid stalls

---
 indra/newview/llviewercontrol.cpp |  8 +++++++-
 indra/newview/pipeline.cpp        | 33 +++++++++++++++++++++++++--------
 indra/newview/pipeline.h          |  2 ++
 3 files changed, 34 insertions(+), 9 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index e53f988c6e..4d86da5f78 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -166,6 +166,12 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
 	return true;
 }
 
+static bool handleShadowDetailChanged(const LLSD& newvalue)
+{
+    gPipeline.handleShadowDetailChanged();
+    return true;
+}
+
 static bool handleRenderPerfTestChanged(const LLSD& newvalue)
 {
        bool status = !newvalue.asBoolean();
@@ -695,7 +701,7 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));
 	gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));
 	gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleRenderDeferredChanged, _2));
-	gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+	gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleShadowDetailChanged, _2));
 	gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
 	gSavedSettings.getControl("RenderPerformanceTest")->getSignal()->connect(boost::bind(&handleRenderPerfTestChanged, _2));
 	gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 96dd0b895d..c895c8a227 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -10215,14 +10215,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 
 	if (mSunDiffuse == LLColor4::black)
 	{ //sun diffuse is totally black, shadows don't matter
-		LLGLDepthTest depth(GL_TRUE);
-
-		for (S32 j = 0; j < 4; j++)
-		{
-			mShadow[j].bindTarget();
-			mShadow[j].clear();
-			mShadow[j].flush();
-		}
+        skipRenderingShadows();
 	}
 	else
 	{
@@ -11430,6 +11423,30 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
 	}
 }
 
+void LLPipeline::skipRenderingShadows()
+{
+    LLGLDepthTest depth(GL_TRUE);
+
+    for (S32 j = 0; j < 4; j++)
+    {
+        mShadow[j].bindTarget();
+        mShadow[j].clear();
+        mShadow[j].flush();
+    }
+}
+
+void LLPipeline::handleShadowDetailChanged()
+{
+    if (RenderShadowDetail > gSavedSettings.getS32("RenderShadowDetail"))
+    {
+        skipRenderingShadows();
+    }
+    else
+    {
+        LLViewerShaderMgr::instance()->setShaders();
+    }
+}
+
 const F32 MIN_DRAW_DISTANCE = 64;
 const F32 MAX_DRAW_DISTANCE = 256;
 
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 7eff573a34..3e5899d973 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -423,6 +423,7 @@ public:
 	void skipRenderingOfTerrain( bool flag );
 	void hideObject( const LLUUID& id );
 	void restoreHiddenObject( const LLUUID& id );
+    void handleShadowDetailChanged();
 
     void autoAdjustSettings();
     void setAdjustmentTimerExpiry(F32 expiration);
@@ -437,6 +438,7 @@ private:
 	void connectRefreshCachedSettingsSafe(const std::string name);
 	void hideDrawable( LLDrawable *pDrawable );
 	void unhideDrawable( LLDrawable *pDrawable );
+    void skipRenderingShadows();
 public:
 	enum {GPU_CLASS_MAX = 3 };
 
-- 
cgit v1.2.3


From 808684ee4fe0d9ed3868d0ee86d9cc28f32fcfcb Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 18 Feb 2022 12:34:38 +0200
Subject: SL-16841 Disable shadow splits one by one to improve FPS instead of
 disabling all shadows at once

---
 indra/newview/app_settings/settings.xml | 11 +++++++++++
 indra/newview/pipeline.cpp              | 29 ++++++++++++++++++++++-------
 indra/newview/pipeline.h                |  3 +++
 3 files changed, 36 insertions(+), 7 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 184ee8daff..43e554e532 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9049,6 +9049,17 @@
     <key>Value</key>
     <real>0.5</real>
   </map>
+  <key>RenderShadowSplits</key>
+  <map>
+    <key>Comment</key>
+    <string>Amount of shadow map splits to render (0 - 3).</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>S32</string>
+    <key>Value</key>
+    <integer>3</integer>
+  </map>
   <key>RenderSSAOScale</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c895c8a227..d3936fabcf 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -150,6 +150,7 @@ U32 LLPipeline::RenderFSAASamples;
 U32 LLPipeline::RenderResolutionDivisor;
 bool LLPipeline::RenderUIBuffer;
 S32 LLPipeline::RenderShadowDetail;
+S32 LLPipeline::RenderShadowSplits;
 bool LLPipeline::RenderDeferredSSAO;
 F32 LLPipeline::RenderShadowResolutionScale;
 bool LLPipeline::RenderLocalLights;
@@ -544,6 +545,7 @@ void LLPipeline::init()
 	connectRefreshCachedSettingsSafe("RenderResolutionDivisor");
 	connectRefreshCachedSettingsSafe("RenderUIBuffer");
 	connectRefreshCachedSettingsSafe("RenderShadowDetail");
+    connectRefreshCachedSettingsSafe("RenderShadowSplits");
 	connectRefreshCachedSettingsSafe("RenderDeferredSSAO");
 	connectRefreshCachedSettingsSafe("RenderShadowResolutionScale");
 	connectRefreshCachedSettingsSafe("RenderLocalLights");
@@ -611,6 +613,7 @@ void LLPipeline::init()
 	connectRefreshCachedSettingsSafe("CameraDoFResScale");
 	connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit");
 	gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
+    gSavedSettings.getControl("AutoFPS")->getCommitSignal()->connect(boost::bind(&LLPipeline::onToggleAutoFPS));
 }
 
 LLPipeline::~LLPipeline()
@@ -1073,6 +1076,7 @@ void LLPipeline::refreshCachedSettings()
 	RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
 	RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");
 	RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
+    RenderShadowSplits = gSavedSettings.getS32("RenderShadowSplits");
 	RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO");
 	RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale");
 	RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights");
@@ -10270,7 +10274,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 
 			std::vector<LLVector3> fp;
 
-			if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir))
+			if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)
+                || j > RenderShadowSplits)
 			{
 				//no possible shadow receivers
 				if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
@@ -11505,10 +11510,10 @@ void LLPipeline::autoAdjustSettings()
             {
                 S32 fps_dif = fps_lower_boundary - fps;
                 
-                if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0)
+                if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0 && RenderShadowSplits > 0)
                 {
-                    S32 shadow_detail = RenderShadowDetail - 1;
-                    gSavedSettings.setS32("RenderShadowDetail", shadow_detail);
+                    S32 shadow_splits = llclamp(RenderShadowSplits - 1, 0, 3);
+                    gSavedSettings.setS32("RenderShadowSplits", shadow_splits);
                     return;
                 }
                 
@@ -11542,10 +11547,10 @@ void LLPipeline::autoAdjustSettings()
                     update_far_clip(fps_dif);
                 }
 
-                if (LLPipeline::sRenderDeferred && RenderShadowDetail < 2)
+                if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0 && RenderShadowSplits < 3)
                 {
-                    S32 shadow_detail = RenderShadowDetail + 1;
-                    gSavedSettings.setS32("RenderShadowDetail", shadow_detail);
+                    S32 shadow_splits = llclamp(RenderShadowSplits + 1, 0, 3);
+                    gSavedSettings.setS32("RenderShadowSplits", shadow_splits);
                 }
             }
         }
@@ -11561,3 +11566,13 @@ void LLPipeline::setAdjustmentTimerExpiry(F32 expiration)
 {
     mUpdateTimer->setTimerExpirySec(expiration);
 }
+
+void LLPipeline::onToggleAutoFPS()
+{
+    if (!gSavedSettings.getBOOL("AutoFPS"))
+    {
+        //reset the number of shadow map splits rendered, when disabling auto-fps
+        //probably should be removed, if we'll have actual UI control for this setting
+        gSavedSettings.setS32("RenderShadowSplits", 3);
+    }
+}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 3e5899d973..b86b68b09d 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -416,6 +416,8 @@ public:
 	static void updateRenderDeferred();
 	static void refreshCachedSettings();
 
+    static void onToggleAutoFPS();
+
 	void addDebugBlip(const LLVector3& position, const LLColor4& color);
 
 	void hidePermanentObjects( std::vector<U32>& restoreList );
@@ -916,6 +918,7 @@ public:
 	static U32 RenderResolutionDivisor;
 	static bool RenderUIBuffer;
 	static S32 RenderShadowDetail;
+    static S32 RenderShadowSplits;
 	static bool RenderDeferredSSAO;
 	static F32 RenderShadowResolutionScale;
 	static bool RenderLocalLights;
-- 
cgit v1.2.3


From 882600de2afa366729be870355767282247be0ef Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 18 Feb 2022 18:30:59 +0200
Subject: SL-16627 water reflection detail settings should be affected by
 auto-adjustment

---
 indra/newview/pipeline.cpp                               | 16 +++++++++++++++-
 .../xui/en/floater_preferences_graphics_advanced.xml     |  2 ++
 2 files changed, 17 insertions(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index d3936fabcf..6738532bc3 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -132,7 +132,7 @@
 
 // NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
 // NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables.
-//  const S32 WATER_REFLECT_NONE_WATER_OPAQUE       = -2;
+    const S32 WATER_REFLECT_NONE_WATER_OPAQUE       = -2;
     const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT  = -1;
     const S32 WATER_REFLECT_MINIMAL                 =  0;
 //  const S32 WATER_REFLECT_TERRAIN                 =  1;
@@ -11510,6 +11510,13 @@ void LLPipeline::autoAdjustSettings()
             {
                 S32 fps_dif = fps_lower_boundary - fps;
                 
+                if (sWaterReflections && RenderReflectionDetail > WATER_REFLECT_NONE_WATER_OPAQUE)
+                {
+                    S32 reflection_detail = llclamp(RenderReflectionDetail - 1, WATER_REFLECT_NONE_WATER_OPAQUE, WATER_REFLECT_MINIMAL);
+                    gSavedSettings.setS32("RenderReflectionDetail", reflection_detail);
+                    return;
+                }
+                
                 if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0 && RenderShadowSplits > 0)
                 {
                     S32 shadow_splits = llclamp(RenderShadowSplits - 1, 0, 3);
@@ -11551,6 +11558,13 @@ void LLPipeline::autoAdjustSettings()
                 {
                     S32 shadow_splits = llclamp(RenderShadowSplits + 1, 0, 3);
                     gSavedSettings.setS32("RenderShadowSplits", shadow_splits);
+                    return;
+                }
+
+                if (sWaterReflections && RenderReflectionDetail < WATER_REFLECT_MINIMAL)
+                {
+                    S32 reflection_detail = llclamp(RenderReflectionDetail + 1, WATER_REFLECT_NONE_WATER_OPAQUE, WATER_REFLECT_MINIMAL);
+                    gSavedSettings.setS32("RenderReflectionDetail", reflection_detail);
                 }
             }
         }
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 65b96d3694..b02eb62112 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
@@ -697,6 +697,8 @@
     top_delta="0"
     name="Reflections"
     width="150">
+      <combo_box.mouse_down_callback
+        function="Pref.AutoAdjustWarning" />
       <combo_box.item
         label="None; opaque"
         name="0"
-- 
cgit v1.2.3


From 064f28b290026be0e77cd38de78b06477a9c0876 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 2 Mar 2022 00:47:02 +0200
Subject: merge fix

---
 indra/newview/llmodelpreview.cpp | 2 --
 1 file changed, 2 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index b9fcad6366..c9bf0b0a12 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -1801,8 +1801,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
             }
         }
     }
-
-    mResourceCost = calcResourceCost();
 }
 
 void LLModelPreview::updateStatusMessages()
-- 
cgit v1.2.3


From 6ab4aeb14878a091a04324c87f5f40d9270f7897 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 9 Mar 2022 13:22:26 +0200
Subject: SL-16627 Enable auto-adjustments for frist login and update UI

---
 indra/newview/llstartup.cpp                        |  6 ++-
 .../skins/default/xui/en/floater_performance.xml   |  2 +-
 .../xui/en/panel_performance_complexity.xml        |  4 +-
 .../default/xui/en/panel_performance_huds.xml      |  4 +-
 .../xui/en/panel_performance_preferences.xml       | 55 +++++++++++++++++-----
 .../default/xui/en/panel_preferences_graphics1.xml | 37 +++++++++------
 6 files changed, 77 insertions(+), 31 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 94bafcb612..537b431ea2 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2208,7 +2208,11 @@ bool idle_startup()
 
 	if (STATE_CLEANUP == LLStartUp::getStartupState())
 	{
-		set_startup_status(1.0, "", "");
+        if (gAgent.isFirstLogin())
+        {
+            gSavedSettings.setBOOL("AutoFPS", TRUE);
+        }
+        set_startup_status(1.0, "", "");
 		display_startup();
 
 		if (!mBenefitsSuccessfullyInit)
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index 84ee9d3c00..0107c59868 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- height="592"
+ height="642"
  layout="topleft"
  name="performance"
  save_rect="true"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
index 40159314f7..954fd0a8c1 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="530"
+ height="580"
  width="580"
  name="panel_performance_complexity"
  layout="topleft"
@@ -83,7 +83,7 @@
   <name_list
     column_padding="0"
     draw_stripes="true"
-    height="379"
+    height="429"
     follows="left|top"
     layout="topleft"
     name="obj_list"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_huds.xml b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
index eea6b79e30..289f865eb7 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_huds.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="530"
+ height="580"
  width="580"
  name="panel_performance_huds"
  layout="topleft"
@@ -71,7 +71,7 @@
   <name_list
     column_padding="0"
     draw_stripes="true"
-    height="400"
+    height="450"
     follows="left|top"
     layout="topleft"
     name="hud_list"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index 5fd6af24c1..1eee799986 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="none"
  follows="left|top"
- height="530"
+ height="580"
  width="580"
  name="panel_performance_preferences"
  layout="topleft"
@@ -54,13 +54,46 @@
     top_delta="0"
     width="200"/>
   <view_border
-    bevel_style="in"
-    height="0"
-    layout="topleft"
-    name="border1"
-    left="20"
-    top_pad="8"
-    width="540"/>
+   bevel_style="in"
+   height="0"
+   layout="topleft"
+   name="border0"
+   top_pad="8"
+   left="20"
+   width="540"/>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="20"
+   left="20"
+   name="auto_lbl"
+   width="105">
+    Automatic settings
+  </text>
+  <check_box
+   control_name="AutoFPS"
+   height="16"
+   initial_value="true"
+   label="Allow system to choose settings for best experience"
+   label_text.text_color="White"
+   label_text.v_pad="-1"
+   label_text.h_pad="3"
+   layout="topleft"
+   left_pad="30"
+   name="AutoFPS"
+   width="256">
+  </check_box>
+  <view_border
+   bevel_style="in"
+   height="0"
+   layout="topleft"
+   name="border1"
+   left="20"
+   top_pad="12"
+   width="540"/>
   <text
    follows="left|top"
    font="SansSerifSmall"
@@ -70,7 +103,7 @@
    top_pad="30"
    name="quality_lbl"
    width="100">
-    Shortcuts
+    Quality &amp; Speed
   </text>
   <text
    follows="left|top"
@@ -362,7 +395,7 @@
    top_delta="0"
    left="160"
    name="water_desc"
-   width="350">
+   width="380">
     Reducing or turning off water effects can greatly improve frame rate.
   </text>
   <check_box
@@ -487,7 +520,7 @@
    font="SansSerifSmall"
    height="18"
    layout="topleft"
-   top="78"
+   top="130"
    left="213"
    name="1_lbl"
    width="7">
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index f73149e77e..93cb3ea9c8 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -30,7 +30,28 @@
     width="120">
       (None)
   </text>
-
+  <view_border
+    bevel_style="in"
+    height="0"
+    layout="topleft"
+    name="border1"
+    left="12"
+    top_pad="12"
+    width="477"/>
+  <check_box
+    control_name="AutoFPS"
+    height="16"
+    initial_value="true"
+    label="Allow system to choose settings for best experience"
+    label_text.text_color="White"
+    label_text.v_pad="-1"
+    label_text.h_pad="5"
+    layout="topleft"
+    left="10"
+    name="AutoFPS"
+    top_delta="15"
+    width="256">
+  </check_box>
   <text
     type="string"
     length="1"
@@ -39,7 +60,7 @@
     layout="topleft"
     left="10"
     name="QualitySpeed"
-    top_delta="35" 
+    top_delta="30" 
     width="400">
       Quality &amp; speed:
   </text>
@@ -262,18 +283,6 @@
       function="Pref.RenderOptionUpdate" />
   </check_box>
 
-  <check_box
-    control_name="AutoFPS"
-    height="16"
-    initial_value="true"
-    label="Auto FPS"
-    layout="topleft"
-    left="30"
-    name="AutoFPS"
-    top_delta="30"
-    width="256">
-  </check_box>
-  
   <slider
     control_name="IndirectMaxComplexity"
     tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
-- 
cgit v1.2.3


From 00b71d8197ed2a64b2d2fa01a72f5cd316e198b7 Mon Sep 17 00:00:00 2001
From: Brad Kittenbrink <brad@lindenlab.com>
Date: Wed, 9 Mar 2022 10:11:40 -0800
Subject: Fix DRTVWR-550 TeamCity build.  codesigning retry block had some
 leftover python2 syntax

---
 indra/newview/viewer_manifest.py | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index c7e49206c8..6aafc07bc7 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1304,9 +1304,8 @@ class DarwinManifest(ViewerManifest):
                         ]
                     for attempt in range(3):
                         if attempt: # second or subsequent iteration
-                            print >> sys.stderr, \
-                                ("codesign failed, waiting %d seconds before retrying" %
-                                 sign_retry_wait)
+                            print("codesign failed, waiting {:d} seconds before retrying".format(sign_retry_wait),
+                                  file=sys.stderr)
                             time.sleep(sign_retry_wait)
                             sign_retry_wait*=2
 
-- 
cgit v1.2.3


From d922d2ba7dc9e2a0de1cf69b569174e3990ae80f Mon Sep 17 00:00:00 2001
From: Brad Kittenbrink <brad@lindenlab.com>
Date: Wed, 9 Mar 2022 16:47:35 -0800
Subject: More DRTVWR-550 Teamcity build fix. another piece of python2 syntax
 leftover in an error handling block

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

(limited to 'indra/newview')

diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 6aafc07bc7..76160b73ba 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1335,7 +1335,7 @@ class DarwinManifest(ViewerManifest):
                             # 'err' goes out of scope
                             sign_failed = err
                     else:
-                        print >> sys.stderr, "Maximum codesign attempts exceeded; giving up"
+                        print("Maximum codesign attempts exceeded; giving up", file=sys.stderr)
                         raise sign_failed
                     self.run_command(['spctl', '-a', '-texec', '-vvvv', app_in_dmg])
                     self.run_command([self.src_path_of("installers/darwin/apple-notarize.sh"), app_in_dmg])
-- 
cgit v1.2.3


From e5e710a1e6e0f74cd60647e3dae7d037076351ff Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 17 Mar 2022 18:47:42 +0200
Subject: SL-16627 show auto-adjustment warning when for Shadows quality and
 Water reflection settings

---
 indra/newview/llfloaterperformance.cpp                                | 1 +
 indra/newview/llfloaterpreferencesgraphicsadvanced.cpp                | 3 +++
 .../skins/default/xui/en/floater_preferences_graphics_advanced.xml    | 4 ----
 indra/newview/skins/default/xui/en/notifications.xml                  | 2 +-
 4 files changed, 5 insertions(+), 5 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index e45d7a0c73..c89c58c401 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -123,6 +123,7 @@ BOOL LLFloaterPerformance::postBuild()
     mSettingsPanel->getChild<LLRadioGroup>("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2));
     mSettingsPanel->getChild<LLCheckBoxCtrl>("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this));
     mSettingsPanel->getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this));
+    mSettingsPanel->getChild<LLComboBox>("Reflections")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
 
     mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
     mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this));
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index 85a0fee143..ba2fd6eef2 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -81,6 +81,9 @@ BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
 
     mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this));
 
+    getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
+    getChild<LLComboBox>("Reflections")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
+
     return TRUE;
 }
 
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 b02eb62112..154c8b7909 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
@@ -697,8 +697,6 @@
     top_delta="0"
     name="Reflections"
     width="150">
-      <combo_box.mouse_down_callback
-        function="Pref.AutoAdjustWarning" />
       <combo_box.item
         label="None; opaque"
         name="0"
@@ -857,8 +855,6 @@
    top_delta="0" 
    name="ShadowDetail"
    width="150">
-    <combo_box.mouse_down_callback
- function="Pref.AutoAdjustWarning" />
      <combo_box.item
        label="None"
        name="0"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 98f74d321b..1b9df53ad2 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1864,7 +1864,7 @@ Graphics Quality can be raised in Preferences &gt; Graphics.
    icon="alertmodal.tga"
    name="AutoFPSConfirmDisable"
    type="alertmodal">
-    Changing this setting will disable automatic adjustment and turn off 'Auto FPS' setting.
+Changing this setting will disable automatic adjustment and turn off 'Automatic settings'.
 Are you sure you want to continue?
     <tag>confirm</tag>
     <usetemplate
-- 
cgit v1.2.3


From 9e352924207447ab294f9581cfc349e17fdd6f6b Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 26 Apr 2022 16:10:52 +0300
Subject: merge fix

---
 indra/newview/llvoavatar.cpp | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 87aff6ca98..33f2ec81ab 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2546,7 +2546,11 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
 	if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
 		&& !disable_all_render_types && !isSelf())
 	{
-		return;
+        if (!mIsControlAvatar)
+        {
+            idleUpdateNameTag( mLastRootPos );
+        }
+        return;
 	}
 
     // Update should be happening max once per frame.
@@ -3189,11 +3193,9 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
     static LLCachedControl<F32> FADE_DURATION(gSavedSettings, "RenderNameFadeDuration"); // seconds
     static LLCachedControl<bool> use_chat_bubbles(gSavedSettings, "UseChatBubbles");
 
-	bool visible_avatar = isVisible() || mNeedsAnimUpdate;
 	bool visible_chat = use_chat_bubbles && (mChats.size() || mTyping);
 	bool render_name =	visible_chat ||
-		(visible_avatar &&
-		 ((sRenderName == RENDER_NAME_ALWAYS) ||
+		(((sRenderName == RENDER_NAME_ALWAYS) ||
 		  (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)));
 	// If it's your own avatar, don't draw in mouselook, and don't
 	// draw if we're specifically hiding our own name.
-- 
cgit v1.2.3


From ba9bff5b9bdd7904916c3ae844840c87376498c3 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 8 Jun 2022 01:21:42 +0300
Subject: SL-17541 Show the message that user is currently at maximum FPS

---
 indra/newview/llfloaterperformance.cpp               | 20 +++++++++++++++++---
 indra/newview/llfloaterperformance.h                 |  1 +
 .../skins/default/xui/en/floater_performance.xml     |  8 +++++++-
 3 files changed, 25 insertions(+), 4 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index c89c58c401..ecacadee3e 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -43,6 +43,7 @@
 #include "lltextbox.h"
 #include "lltrans.h"
 #include "llviewerobjectlist.h"
+#include "llviewerwindow.h"
 #include "llvoavatar.h"
 #include "llvoavatarself.h"
 #include "llworld.h"
@@ -162,11 +163,9 @@ void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
 
 void LLFloaterPerformance::draw()
 {
-    const S32 NUM_PERIODS = 50;
-
     if (mUpdateTimer->hasExpired())
     {
-        getChild<LLTextBox>("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, NUM_PERIODS)));
+        setFPSText();
         if (mHUDsPanel->getVisible())
         {
             populateHUDList();
@@ -409,6 +408,21 @@ void LLFloaterPerformance::populateNearbyList()
     mNearbyList->selectByID(prev_selected_id);
 }
 
+void LLFloaterPerformance::setFPSText()
+{
+    const S32 NUM_PERIODS = 50;
+    S32 current_fps = (S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, NUM_PERIODS));
+    getChild<LLTextBox>("fps_value")->setValue(current_fps);
+
+    std::string fps_text = getString("fps_text");
+    static LLCachedControl<bool> vsync_enabled(gSavedSettings, "RenderVSyncEnable", true);
+    if (vsync_enabled && (current_fps >= gViewerWindow->getWindow()->getRefreshRate()))
+    {
+        fps_text += getString("max_text");
+    }
+    getChild<LLTextBox>("fps_lbl")->setValue(fps_text);
+}
+
 void LLFloaterPerformance::detachItem(const LLUUID& item_id)
 {
     LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 9ccb29cd7b..e40eee162d 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -57,6 +57,7 @@ private:
     void populateHUDList();
     void populateObjectList();
     void populateNearbyList();
+    void setFPSText();
 
     void onClickAdvanced();
     void onChangeQuality(const LLSD& data);
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index 0107c59868..bf2623f356 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -6,6 +6,12 @@
  save_rect="true"
  title="IMPROVE GRAPHICS SPEED"
  width="580">
+  <string
+   name="fps_text"
+   value="frames per second"/>
+  <string
+   name="max_text"
+   value=" (maximum)"/>
   <panel
    bevel_style="none"
    follows="left|top"
@@ -35,7 +41,7 @@
        text_color="White"
        height="20"
        layout="topleft"
-       left="20"
+       left="10"
        top="8"
        name="fps_value"
        width="42">
-- 
cgit v1.2.3


From 76c8a7ff0b57e7856613960391be7c400384183b Mon Sep 17 00:00:00 2001
From: Mnikolenko ProductEngine <mnikolenko@productengine.com>
Date: Wed, 8 Jun 2022 03:15:59 +0300
Subject: SL-17541 show the message on mac

---
 indra/newview/llfloaterperformance.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index ecacadee3e..0ef9ab3215 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -416,7 +416,8 @@ void LLFloaterPerformance::setFPSText()
 
     std::string fps_text = getString("fps_text");
     static LLCachedControl<bool> vsync_enabled(gSavedSettings, "RenderVSyncEnable", true);
-    if (vsync_enabled && (current_fps >= gViewerWindow->getWindow()->getRefreshRate()))
+    S32 refresh_rate = gViewerWindow->getWindow()->getRefreshRate();
+    if (vsync_enabled && (refresh_rate > 0) && (current_fps >= refresh_rate))
     {
         fps_text += getString("max_text");
     }
-- 
cgit v1.2.3


From b66f2e7da7d3ec68984d7fcb5e5996e1451c0baf Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 21 Sep 2022 21:19:17 +0300
Subject: SL-18202 WIP merging autotune contribution and updating UI

---
 indra/newview/CMakeLists.txt                       |   3 +
 indra/newview/app_settings/settings.xml            | 132 ++++++
 indra/newview/app_settings/toolbars.xml            |   1 +
 indra/newview/llappviewer.cpp                      | 150 ++++---
 indra/newview/lldrawpool.cpp                       |  63 ++-
 indra/newview/lldrawpoolalpha.cpp                  |  34 +-
 indra/newview/lldrawpoolavatar.cpp                 |   9 +-
 indra/newview/lldrawpoolbump.cpp                   |  33 +-
 indra/newview/lldrawpoolmaterials.cpp              |  14 +-
 indra/newview/llfloaterperformance.cpp             |   4 +
 indra/newview/llfloaterperformance.h               |   1 +
 indra/newview/llfloaterpreference.cpp              |  18 +
 indra/newview/llfloaterpreference.h                |   2 +
 indra/newview/llperfstats.cpp                      | 469 +++++++++++++++++++++
 indra/newview/llperfstats.h                        | 454 ++++++++++++++++++++
 indra/newview/llstartup.cpp                        |   6 +
 indra/newview/llviewercontrol.cpp                  |  72 ++++
 indra/newview/llviewerdisplay.cpp                  |  13 +-
 indra/newview/llviewerjointmesh.cpp                |  11 +
 indra/newview/llvoavatar.cpp                       |  93 ++++
 indra/newview/llvoavatar.h                         |  24 ++
 indra/newview/llvovolume.cpp                       |  21 +-
 .../skins/default/xui/en/floater_performance.xml   |  54 +++
 .../xui/en/panel_performance_autoadjustments.xml   | 272 ++++++++++++
 24 files changed, 1872 insertions(+), 81 deletions(-)
 create mode 100644 indra/newview/llperfstats.cpp
 create mode 100644 indra/newview/llperfstats.h
 create mode 100644 indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml

(limited to 'indra/newview')

diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 776797da7c..1a009967f5 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -1383,6 +1383,9 @@ set(viewer_HEADER_FILES
     VorbisFramework.h
     )
 
+  list(APPEND viewer_SOURCE_FILES llperfstats.cpp)
+  list(APPEND viewer_HEADER_FILES llperfstats.h)
+
 source_group("CMake Rules" FILES ViewerInstall.cmake)
 
 #build_data.json creation moved to viewer_manifest.py MAINT-6413
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 1877c30dc4..d92632c0a2 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16776,6 +16776,138 @@
     <key>Value</key>
     <real>50</real>
   </map>
+  <key>TargetFPS</key>
+  <map>
+    <key>Comment</key>
+    <string>Desired minimum FPS</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>25</integer>
+  </map>
+  <key>AutoTuneFPS</key>
+  <map>
+    <key>Comment</key>
+    <string>Allow the viewer to adjust your settings to achieve target FPS</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>AutoTuneLock</key>
+  <map>
+    <key>Comment</key>
+    <string>When enabled the viewer will dynamically change settings until auto tune is explicitly turned off.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
+  <key>AllowSelfImpostor</key>
+  <map>
+    <key>Comment</key>
+    <string>Allow own render time to impostor your avatar.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>RenderAvatarMaxART</key>
+  <map>
+    <key>Comment</key>
+    <string>Render Time Limit in microseconds (0.0 = no limit)</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>4.699</real>
+  </map>
+  <key>AutoTuneRenderFarClipMin</key>
+  <map>
+    <key>Comment</key>
+    <string>The lowest draw distance that auto tune is allowed to use</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>32.0</real>
+  </map>
+  <key>AutoTuneRenderFarClipTarget</key>
+  <map>
+    <key>Comment</key>
+    <string>The draw distance that auto tune will try to achieve</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>256.0</real>
+  </map>
+  <key>UserTargetReflections</key>
+  <map>
+    <key>Comment</key>
+    <string>Set by auto tune floater on build</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>S32</string>
+    <key>Value</key>
+    <integer>4</integer>
+  </map>
+  <key>PerfStatsCaptureEnabled</key>
+  <map>
+    <key>Comment</key>
+    <string>Enable/disable render time data to support autotune.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
+  <key>AutoTuneImpostorByDistEnabled</key>
+  <map>
+    <key>Comment</key>
+    <string>Enable/disable using MaxNonImpostor to limit avatar rendering by distance.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>AutoTuneImpostorFarAwayDistance</key>
+  <map>
+    <key>Comment</key>
+    <string>Avatars beyond this range will automatically be optimized</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>64.0</real>
+  </map>
+  <key>TuningFPSStrategy</key>
+  <map>
+    <key>Comment</key>
+    <string>Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
   <key>CameraOpacity</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml
index f3a23edc58..a1c9d6d9ee 100644
--- a/indra/newview/app_settings/toolbars.xml
+++ b/indra/newview/app_settings/toolbars.xml
@@ -22,6 +22,7 @@
     <command name="voice"/>
     <command name="minimap"/>
     <command name="snapshot"/>
+    <command name="performance"/>
   </left_toolbar>
   <right_toolbar
     button_display_mode="icons_only">
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index d61a66c696..a04d21c4b0 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -108,6 +108,7 @@
 #include "llscenemonitor.h"
 #include "llavatarrenderinfoaccountant.h"
 #include "lllocalbitmaps.h"
+#include "llperfstats.h" 
 
 // Linden library includes
 #include "llavatarnamecache.h"
@@ -1377,82 +1378,91 @@ bool LLAppViewer::frame()
 
 bool LLAppViewer::doFrame()
 {
-	LL_RECORD_BLOCK_TIME(FTM_FRAME);
+    LL_RECORD_BLOCK_TIME(FTM_FRAME);
+    {
+    // and now adjust the visuals from previous frame.
+    if(LLPerfStats::tunables.userAutoTuneEnabled && LLPerfStats::tunables.tuningFlag != LLPerfStats::Tunables::Nothing)
+    {
+        LLPerfStats::tunables.applyUpdates();
+    }
 
+    LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_FRAME);
     if (!LLWorld::instanceExists())
     {
         LLWorld::createInstance();
     }
 
-	LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
-	LLSD newFrame;
-
-	{
-        LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace");
-        if (LLFloaterReg::instanceVisible("block_timers"))
+    LLEventPump& mainloop(LLEventPumps::instance().obtain("mainloop"));
+    LLSD newFrame;
+    {
+        LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE); // perf stats
         {
-	LLTrace::BlockTimer::processTimes();
-        }
-        
-	LLTrace::get_frame_recording().nextPeriod();
-	LLTrace::BlockTimer::logStats();
-	}
+            LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df LLTrace");
+            if (LLFloaterReg::instanceVisible("block_timers"))
+            {
+                LLTrace::BlockTimer::processTimes();
+            }
 
-	LLTrace::get_thread_recorder()->pullFromChildren();
+            LLTrace::get_frame_recording().nextPeriod();
+            LLTrace::BlockTimer::logStats();
+        }
 
-	//clear call stack records
-	LL_CLEAR_CALLSTACKS();
+        LLTrace::get_thread_recorder()->pullFromChildren();
 
-	{
-		LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df processMiscNativeEvents" )
-		pingMainloopTimeout("Main:MiscNativeWindowEvents");
+        //clear call stack records
+        LL_CLEAR_CALLSTACKS();
+    }
+    {
+        {
+            LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE); // ensure we have the entire top scope of frame covered (input event and coro)
+            LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df processMiscNativeEvents")
+            pingMainloopTimeout("Main:MiscNativeWindowEvents");
 
-		if (gViewerWindow)
-		{
-			LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
-			gViewerWindow->getWindow()->processMiscNativeEvents();
-		}
+            if (gViewerWindow)
+            {
+                LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
+                gViewerWindow->getWindow()->processMiscNativeEvents();
+            }
 
-		{
-			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df gatherInput" )
-		pingMainloopTimeout("Main:GatherInput");
-		}
+            {
+                LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df gatherInput")
+                pingMainloopTimeout("Main:GatherInput");
+            }
 
-		if (gViewerWindow)
-		{
-			LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
-			if (!restoreErrorTrap())
-			{
-				LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL;
-			}
+            if (gViewerWindow)
+            {
+                LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
+                if (!restoreErrorTrap())
+                {
+                    LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL;
+                }
 
-			gViewerWindow->getWindow()->gatherInput();
-		}
+                gViewerWindow->getWindow()->gatherInput();
+            }
 
-		//memory leaking simulation
-		if (gSimulateMemLeak)
-		{
-			LLFloaterMemLeak* mem_leak_instance =
-				LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
-			if (mem_leak_instance)
-			{
-				mem_leak_instance->idle();
-			}
-		}
+            //memory leaking simulation
+            if (gSimulateMemLeak)
+            {
+                LLFloaterMemLeak* mem_leak_instance =
+                    LLFloaterReg::findTypedInstance<LLFloaterMemLeak>("mem_leaking");
+                if (mem_leak_instance)
+                {
+                    mem_leak_instance->idle();
+                }
+            }
 
-		{
-			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df mainloop" )
-		// canonical per-frame event
-		mainloop.post(newFrame);
-		}
+            {
+                LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df mainloop")
+                // canonical per-frame event
+                mainloop.post(newFrame);
+            }
 
-		{
-			LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df suspend" )
-		// give listeners a chance to run
-		llcoro::suspend();
-		// if one of our coroutines threw an uncaught exception, rethrow it now
-		LLCoros::instance().rethrow();
-		}
+            {
+                LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df suspend")
+                // give listeners a chance to run
+                llcoro::suspend();
+            }
+        }
 
 		if (!LLApp::isExiting())
 		{
@@ -1470,6 +1480,7 @@ bool LLAppViewer::doFrame()
 				&& (gHeadlessClient || !gViewerWindow->getShowProgress())
 				&& !gFocusMgr.focusLocked())
 			{
+                LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);
 				joystick->scanJoystick();
 				gKeyboard->scanKeyboard();
                 gViewerInput.scanMouse();
@@ -1483,6 +1494,7 @@ bool LLAppViewer::doFrame()
 				}
 
 				{
+                    LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);
 					LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); //LL_RECORD_BLOCK_TIME(FTM_IDLE);
 					idle();
 				}
@@ -1517,13 +1529,14 @@ bool LLAppViewer::doFrame()
 
 				display();
 
-				{
-					LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
-				pingMainloopTimeout("Main:Snapshot");
-				LLFloaterSnapshot::update(); // take snapshots
-					LLFloaterOutfitSnapshot::update();
-				gGLActive = FALSE;
-			}
+                {
+                    LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE);
+                    LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
+                    pingMainloopTimeout("Main:Snapshot");
+                    LLFloaterSnapshot::update(); // take snapshots
+                    LLFloaterOutfitSnapshot::update();
+                    gGLActive = FALSE;
+                }
 		}
 		}
 
@@ -1569,7 +1582,8 @@ bool LLAppViewer::doFrame()
 				// of equal priority on Windows
 				if (milliseconds_to_sleep > 0)
 				{
-					ms_sleep(milliseconds_to_sleep);
+                    LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SLEEP );
+                    ms_sleep(milliseconds_to_sleep);
 					// also pause worker threads during this wait period
 					LLAppViewer::getTextureCache()->pause();
 					LLAppViewer::getImageDecodeThread()->pause();
@@ -1670,7 +1684,7 @@ bool LLAppViewer::doFrame()
 
 		LL_INFOS() << "Exiting main_loop" << LL_ENDL;
 	}
-
+    }LLPerfStats::StatsRecorder::endFrame();
     LL_PROFILER_FRAME_END
 
 	return ! LLApp::isRunning();
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index a3837fe10c..594cfe513d 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -52,6 +52,7 @@
 #include "llglcommonfunc.h"
 #include "llvoavatar.h"
 #include "llviewershadermgr.h"
+#include "llperfstats.h"
 
 
 S32 LLDrawPool::sNumDrawPools = 0;
@@ -391,13 +392,22 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
 	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
-	
+
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats 
 	for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
 	{
 		LLDrawInfo *pparams = *k;
 		if (pparams) 
         {
-			pushBatch(*pparams, mask, texture);
+            if(pparams->mFace)
+            {
+                LLViewerObject* vobj = pparams->mFace->getViewerObject();
+                if(vobj->isAttachment())
+                {
+                    trackAttachments(vobj, false, &ratPtr);
+                }
+            }
+            pushBatch(*pparams, mask, texture);
 		}
 	}
 }
@@ -410,11 +420,21 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,
     U64 lastMeshId = 0;
     mask |= LLVertexBuffer::MAP_WEIGHT4;
 
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats 
     for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
     {
         LLDrawInfo* pparams = *k;
         if (pparams) 
         {
+            if(pparams->mFace)
+            {
+                LLViewerObject* vobj = pparams->mFace->getViewerObject();
+                if(vobj->isAttachment())
+                {
+                    trackAttachments( vobj, true ,&ratPtr);
+                }
+            }
+
             if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
             {
                 uploadMatrixPalette(*pparams);
@@ -430,12 +450,21 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,
 void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
 	for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	
 	{
 		LLDrawInfo* pparams = *i;
 		if (pparams) 
 		{
-			pushBatch(*pparams, mask, texture, batch_textures);
+            if(pparams->mFace)
+            {
+                LLViewerObject* vobj = pparams->mFace->getViewerObject();
+                if(vobj->isAttachment())
+                {
+                    trackAttachments( vobj, false, &ratPtr);
+                }
+            }
+            pushBatch(*pparams, mask, texture, batch_textures);
 		}
 	}
 }
@@ -446,11 +475,21 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc
     LLVOAvatar* lastAvatar = nullptr;
     U64 lastMeshId = 0;
     mask |= LLVertexBuffer::MAP_WEIGHT4;
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats 
     for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
     {
         LLDrawInfo* pparams = *i;
         if (pparams)
         {
+            if(pparams->mFace)
+            {
+                LLViewerObject* vobj = pparams->mFace->getViewerObject();
+                if(vobj->isAttachment())
+                {
+                    trackAttachments( vobj, true, &ratPtr);
+                }
+            }
+
             if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
             {
                 uploadMatrixPalette(*pparams);
@@ -466,11 +505,20 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc
 void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
 	for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	
 	{
 		LLDrawInfo* pparams = *i;
 		if (pparams) 
 		{
+            if((*pparams).mFace)
+            {
+                LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
+                if(vobj->isAttachment())
+                {
+                    trackAttachments( vobj, false, &ratPtr);
+                }
+            }
 			LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
 			pushBatch(*pparams, mask, texture, batch_textures);
 		}
@@ -482,11 +530,20 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
     LLVOAvatar* lastAvatar = nullptr;
     U64 lastMeshId = 0;
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
     for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
     {
         LLDrawInfo* pparams = *i;
         if (pparams)
         {
+            if((*pparams).mFace)
+            {
+                LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
+                if(vobj->isAttachment())
+                {
+                    trackAttachments( vobj, true, &ratPtr);
+                }
+            }
             if (LLGLSLShader::sCurBoundShaderPtr)
             {
                 LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index e674707c01..de5b9d5062 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -49,6 +49,7 @@
 #include "llspatialpartition.h"
 #include "llglcommonfunc.h"
 #include "llvoavatar.h"
+#include "llperfstats.h"
 
 BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
 
@@ -327,10 +328,20 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
             {
                 LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass 
 
+                std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
                 for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
                 {
                     LLDrawInfo& params = **k;
 
+                    if(params.mFace)
+                    {
+                        LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
+                        if(vobj->isAttachment())
+                        {
+                            trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
+                        }
+                    }
+
                     if (params.mParticle)
                     {
                         continue;
@@ -500,8 +511,16 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
 
     mask |= LLVertexBuffer::MAP_WEIGHT4;
 
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
     for (LLDrawInfo* draw : emissives)
     {
+        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives");
+        auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
+        if(vobj && vobj->isAttachment())
+        {
+            trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
+        }
+
         bool tex_setup = TexSetup(draw, false);
         if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)
         {
@@ -566,7 +585,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 
 			LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA];
 
-			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
+            std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
+            for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
 			{
 				LLDrawInfo& params = **k;
                 if ((bool)params.mAvatar != rigged)
@@ -585,6 +605,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 					continue;
 				}
 
+                if(params.mFace)
+                {
+                    LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
+
+                    if(vobj->isAttachment())
+                    {
+                        trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
+                    }
+                }
+
 				if(depth_only)
 				{
                     // when updating depth buffer, discard faces that are more than 90% transparent
@@ -769,6 +799,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 				}
 			}
 
+            ratPtr.reset(); // force the final batch to terminate to avoid double counting on the subsidiary batches for FB and Emmissives
+
             // render emissive faces into alpha channel for bloom effects
             if (!depth_only)
             {
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 4a9a3caaec..02dea6b828 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -52,6 +52,7 @@
 #include "llviewerpartsim.h"
 #include "llviewercontrol.h" // for gSavedSettings
 #include "llviewertexturelist.h"
+#include "llperfstats.h"
 
 static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
 static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
@@ -380,9 +381,12 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
 	{
 		return;
 	}
+    LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_SHADOWS);
+
 	LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
-	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
-    if (impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
+	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();    
+    // no shadows if the shadows are causing this avatar to breach the limit.
+    if (avatarp->isTooSlowWithShadows() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
 	{
         // No shadows for impostored (including jellydolled) or invisible avs.
 		return;
@@ -789,6 +793,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 	{
 		return;
 	}
+    LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_GEOMETRY);
 
 	if (!single_avatar && !avatarp->isFullyLoaded() )
 	{
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 8db6a10e26..09b2400aff 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -48,6 +48,7 @@
 #include "llspatialpartition.h"
 #include "llviewershadermgr.h"
 #include "llmodel.h"
+#include "llperfstats.h"
 
 //#include "llimagebmp.h"
 //#include "../tools/imdebug/imdebug.h"
@@ -538,10 +539,18 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL
 {					
 	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];	
 	
-	for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) 
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
+    for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) 
 	{
 		LLDrawInfo& params = **k;
 		
+        LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
+
+        if( vobj && vobj->isAttachment() )
+        {
+            trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
+        }
+
 		applyModelMatrix(params);
 
 		if (params.mGroup)
@@ -706,10 +715,21 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
         LLVOAvatar* avatar = nullptr;
         U64 skin = 0;
 
+        std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
         for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
         {
             LLDrawInfo& params = **i;
 
+            if(params.mFace)
+            {
+                LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
+
+                if(vobj && vobj->isAttachment())
+                {
+                    trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
+                }
+            }
+
             LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
             LLDrawPoolBump::bindBumpMap(params, bump_channel);
 
@@ -1337,10 +1357,21 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
     LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
     LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
 
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
 	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)	
 	{
 		LLDrawInfo& params = **i;
 
+        if(params.mFace)
+        {
+            LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
+
+            if( vobj && vobj->isAttachment() )
+            {
+                trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
+            }
+        }
+
 		if (LLDrawPoolBump::bindBumpMap(params))
 		{
             if (mRigged)
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 2b05f4c453..f2408a3294 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -32,6 +32,7 @@
 #include "pipeline.h"
 #include "llglcommonfunc.h"
 #include "llvoavatar.h"
+#include "llperfstats.h"
 
 S32 diffuse_channel = -1;
 
@@ -164,9 +165,20 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
 	LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
 	LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
 	
-	for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
+    for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
 	{
 		LLDrawInfo& params = **i;
+
+        if(params.mFace)
+        {
+            LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
+
+            if( vobj && vobj->isAttachment() )
+            {
+                trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
+            }
+        }
 		
 		mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
 		mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 0ef9ab3215..257c0b2b37 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -99,16 +99,19 @@ BOOL LLFloaterPerformance::postBuild()
     mComplexityPanel = getChild<LLPanel>("panel_performance_complexity");
     mSettingsPanel = getChild<LLPanel>("panel_performance_preferences");
     mHUDsPanel = getChild<LLPanel>("panel_performance_huds");
+    mAutoadjustmentsPanel = getChild<LLPanel>("panel_performance_autoadjustments");
 
     getChild<LLPanel>("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel));
     getChild<LLPanel>("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel));
     getChild<LLPanel>("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel));
     getChild<LLPanel>("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel));
+    getChild<LLPanel>("autoadjustments_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mAutoadjustmentsPanel));
 
     initBackBtn(mNearbyPanel);
     initBackBtn(mComplexityPanel);
     initBackBtn(mSettingsPanel);
     initBackBtn(mHUDsPanel);
+    initBackBtn(mAutoadjustmentsPanel);
 
     mHUDList = mHUDsPanel->getChild<LLNameListCtrl>("hud_list");
     mHUDList->setNameListType(LLNameListCtrl::SPECIAL);
@@ -197,6 +200,7 @@ void LLFloaterPerformance::hidePanels()
     mComplexityPanel->setVisible(FALSE);
     mHUDsPanel->setVisible(FALSE);
     mSettingsPanel->setVisible(FALSE);
+    mAutoadjustmentsPanel->setVisible(FALSE);
 }
 
 void LLFloaterPerformance::initBackBtn(LLPanel* panel)
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index e40eee162d..01b65365da 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -76,6 +76,7 @@ private:
     LLPanel* mComplexityPanel;
     LLPanel* mHUDsPanel;
     LLPanel* mSettingsPanel;
+    LLPanel* mAutoadjustmentsPanel;
     LLNameListCtrl* mHUDList;
     LLNameListCtrl* mObjectList;
     LLNameListCtrl* mNearbyList;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index ac1dbe9867..77bf03852f 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -115,6 +115,7 @@
 #include "llpresetsmanager.h"
 
 #include "llsearchableui.h"
+#include "llperfstats.h"
 
 const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f;
 char const* const VISIBILITY_DEFAULT = "default";
@@ -1481,6 +1482,23 @@ void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box, bool sh
 	}
 }
 
+void LLAvatarComplexityControls::updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val)
+{
+    setRenderTimeText((F32)(LLPerfStats::renderAvatarMaxART_ns/1000), value_label, short_val);
+}
+
+void LLAvatarComplexityControls::setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val)
+{
+    if (0 == value)
+    {
+        text_box->setText(LLTrans::getString("no_limit"));
+    }
+    else
+    {
+        text_box->setText(llformat("%.0f", value));
+    }
+}
+
 void LLFloaterPreference::updateMaxComplexity()
 {
 	// Called when the IndirectMaxComplexity control changes
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index a089fde9ff..de4e3cd886 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -358,6 +358,8 @@ class LLAvatarComplexityControls
   public: 
 	static void updateMax(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false);
 	static void setText(U32 value, LLTextBox* text_box, bool short_val = false);
+	static void updateMaxRenderTime(LLSliderCtrl* slider, LLTextBox* value_label, bool short_val = false);
+	static void setRenderTimeText(F32 value, LLTextBox* text_box, bool short_val = false);
 	static void setIndirectControls();
 	static void setIndirectMaxNonImpostors();
 	static void setIndirectMaxArc();
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
new file mode 100644
index 0000000000..16d0df0245
--- /dev/null
+++ b/indra/newview/llperfstats.cpp
@@ -0,0 +1,469 @@
+/** 
+* @file llperfstats.cpp
+* @brief Statistics collection to support autotune and perf flaoter.
+*
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2022, Linden Research, Inc.
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+* 
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llperfstats.h"
+#include "llcontrol.h"
+#include "pipeline.h"
+#include "llagentcamera.h"
+#include "llvoavatar.h"
+#include "llworld.h"
+#include <llthread.h>
+
+extern LLControlGroup gSavedSettings;
+
+namespace LLPerfStats
+{
+    std::atomic<int64_t> tunedAvatars{0};
+    std::atomic<U64> renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features
+    bool belowTargetFPS{false};
+    U32 lastGlobalPrefChange{0}; 
+    std::mutex bufferToggleLock{};
+
+    Tunables tunables;
+
+    std::atomic<int> 	StatsRecorder::writeBuffer{0};
+    bool 	            StatsRecorder::collectionEnabled{true};
+    LLUUID              StatsRecorder::focusAv{LLUUID::null};
+	std::array<StatsRecorder::StatsTypeMatrix,2>  StatsRecorder::statsDoubleBuffer{ {} };
+    std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::max{ {} };
+    std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::sum{ {} };
+
+    void Tunables::applyUpdates()
+    {
+        assert_main_thread();
+        // these following variables are proxies for pipeline statics we do not need a two way update (no llviewercontrol handler)
+        if( tuningFlag & NonImpostors ){ gSavedSettings.setU32("IndirectMaxNonImpostors", nonImpostors); };
+        if( tuningFlag & ReflectionDetail ){ gSavedSettings.setS32("RenderReflectionDetail", reflectionDetail); };
+        if( tuningFlag & FarClip ){ gSavedSettings.setF32("RenderFarClip", farClip); };
+        if( tuningFlag & UserMinDrawDistance ){ gSavedSettings.setF32("AutoTuneRenderFarClipMin", userMinDrawDistance); };
+        if( tuningFlag & UserTargetDrawDistance ){ gSavedSettings.setF32("AutoTuneRenderFarClipTarget", userTargetDrawDistance); };
+        if( tuningFlag & UserImpostorDistance ){ gSavedSettings.setF32("AutoTuneImpostorFarAwayDistance", userImpostorDistance); };
+        if( tuningFlag & UserImpostorDistanceTuningEnabled ){ gSavedSettings.setBOOL("AutoTuneImpostorByDistEnabled", userImpostorDistanceTuningEnabled); };
+        if( tuningFlag & UserFPSTuningStrategy ){ gSavedSettings.setU32("TuningFPSStrategy", userFPSTuningStrategy); };
+        if( tuningFlag & UserAutoTuneEnabled ){ gSavedSettings.setBOOL("AutoTuneFPS", userAutoTuneEnabled); };
+        if( tuningFlag & UserAutoTuneLock ){ gSavedSettings.setBOOL("AutoTuneLock", userAutoTuneLock); };
+        if( tuningFlag & UserTargetFPS ){ gSavedSettings.setU32("TargetFPS", userTargetFPS); };
+        if( tuningFlag & UserTargetReflections ){ gSavedSettings.setS32("UserTargetReflections", userTargetReflections); };
+        // Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value
+        if( tuningFlag & UserARTCutoff ){ gSavedSettings.setF32("RenderAvatarMaxART", userARTCutoffSliderValue); };
+        resetChanges();
+    }
+
+    void Tunables::updateRenderCostLimitFromSettings()
+    {
+        assert_main_thread();
+	    const auto newval = gSavedSettings.getF32("RenderAvatarMaxART");
+	    if(newval < log10(LLPerfStats::ART_UNLIMITED_NANOS/1000))
+	    {
+    		LLPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000;
+    	}
+    	else
+    	{
+		    LLPerfStats::renderAvatarMaxART_ns = 0;
+	    };        
+    }
+
+    // static 
+    void Tunables::updateSettingsFromRenderCostLimit()
+    {
+        if( userARTCutoffSliderValue != log10( ( (F32)LLPerfStats::renderAvatarMaxART_ns )/1000 ) )
+        {
+            if( LLPerfStats::renderAvatarMaxART_ns != 0 )
+            {
+                updateUserARTCutoffSlider(log10( ( (F32)LLPerfStats::renderAvatarMaxART_ns )/1000 ) );
+            }
+            else
+            {
+                updateUserARTCutoffSlider(log10( (F32)LLPerfStats::ART_UNLIMITED_NANOS/1000 ) );
+            }
+        }        
+    }
+
+    void Tunables::initialiseFromSettings()
+    {
+        assert_main_thread();
+        // the following variables are two way and have "push" in llviewercontrol 
+        LLPerfStats::tunables.userMinDrawDistance = gSavedSettings.getF32("AutoTuneRenderFarClipMin");
+        LLPerfStats::tunables.userTargetDrawDistance = gSavedSettings.getF32("AutoTuneRenderFarClipTarget");
+        LLPerfStats::tunables.userImpostorDistance = gSavedSettings.getF32("AutoTuneImpostorFarAwayDistance");
+        LLPerfStats::tunables.userImpostorDistanceTuningEnabled = gSavedSettings.getBOOL("AutoTuneImpostorByDistEnabled");
+        LLPerfStats::tunables.userFPSTuningStrategy = gSavedSettings.getU32("TuningFPSStrategy");
+        LLPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("TargetFPS");
+        LLPerfStats::tunables.userTargetReflections = gSavedSettings.getS32("UserTargetReflections");
+        LLPerfStats::tunables.userAutoTuneEnabled = gSavedSettings.getBOOL("AutoTuneFPS");
+        LLPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("AutoTuneLock");
+        // Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value
+        updateRenderCostLimitFromSettings();
+        resetChanges();
+    }
+
+    StatsRecorder::StatsRecorder():q(1024*16),t(&StatsRecorder::run)
+    {
+        // create a queue
+        // create a thread to consume from the queue
+        tunables.initialiseFromSettings();
+        t.detach();
+    }
+
+    // static
+    void StatsRecorder::toggleBuffer()
+    {
+        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+        using ST = StatType_t;
+
+        bool unreliable{false};
+        LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);
+        auto& sceneStats = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null];
+        auto& lastStats = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null];
+
+        static constexpr std::initializer_list<StatType_t> sceneStatsToAvg = {
+            StatType_t::RENDER_FRAME, 
+            StatType_t::RENDER_DISPLAY, 
+            StatType_t::RENDER_HUDS,
+            StatType_t::RENDER_UI,
+            StatType_t::RENDER_SWAP,
+            // RENDER_LFS,
+            // RENDER_MESHREPO,
+            StatType_t::RENDER_IDLE };
+
+        static constexpr std::initializer_list<StatType_t> avatarStatsToAvg = {
+            StatType_t::RENDER_GEOMETRY, 
+            StatType_t::RENDER_SHADOWS, 
+            StatType_t::RENDER_COMBINED,
+            StatType_t::RENDER_IDLE };
+
+
+        if( /*sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] != 0 ||*/ sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] != 0 )
+        {
+            unreliable = true;
+            //lastStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)];
+            lastStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)];
+            lastStats[static_cast<size_t>(StatType_t::RENDER_FRAME)] = sceneStats[static_cast<size_t>(StatType_t::RENDER_FRAME)]; //  bring over the total frame render time to deal with region crossing overlap issues
+        }
+
+        if(!unreliable)
+        {
+            // only use these stats when things are reliable. 
+
+            for(auto & statEntry : sceneStatsToAvg)
+            {
+                auto avg = lastStats[static_cast<size_t>(statEntry)];
+                auto val = sceneStats[static_cast<size_t>(statEntry)];
+                sceneStats[static_cast<size_t>(statEntry)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS);
+                // LL_INFOS("scenestats") << "Scenestat: " << static_cast<size_t>(statEntry) << " before=" << avg << " new=" << val << " newavg=" << statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(statEntry)] << LL_ENDL;
+            }
+        }
+// Allow attachment times etc to update even when FPS limited or sleeping.
+        auto& statsMap = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)];
+        for(auto& stat_entry : statsMap)
+        {
+            auto val = stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)];
+            if(val > SMOOTHING_PERIODS){
+                auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)][stat_entry.first][static_cast<size_t>(ST::RENDER_COMBINED)];
+                stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS);
+            }
+        }
+
+
+        auto& statsMapAv = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_AVATAR)];
+        for(auto& stat_entry : statsMapAv)
+        {
+            for(auto& stat : avatarStatsToAvg)
+            {
+                auto val = stat_entry.second[static_cast<size_t>(stat)];
+                if(val > SMOOTHING_PERIODS)
+                {
+                    auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_AVATAR)][stat_entry.first][static_cast<size_t>(stat)];
+                    stat_entry.second[static_cast<size_t>(stat)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS);
+                }
+            }
+        }
+
+        // swap the buffers
+        if(enabled())
+        {
+            std::lock_guard<std::mutex> lock{bufferToggleLock};
+            writeBuffer ^= 1;
+        }; // note we are relying on atomic updates here. The risk is low and would cause minor errors in the stats display. 
+
+        // clean the write maps in all cases.
+        auto& statsTypeMatrix = statsDoubleBuffer[writeBuffer];
+        for(auto& statsMapByType : statsTypeMatrix)
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("Clear stats maps");
+            for(auto& stat_entry : statsMapByType)
+            {
+                std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0);
+            }
+            statsMapByType.clear();
+        }
+        for(int i=0; i< static_cast<size_t>(ObjType_t::OT_COUNT); i++)
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("clear max/sum");
+            max[writeBuffer][i].fill(0);
+            sum[writeBuffer][i].fill(0);
+        }
+
+        // and now adjust the proxy vars so that the main thread can adjust the visuals.
+        if(tunables.userAutoTuneEnabled)
+        {
+            updateAvatarParams();
+        }
+    }
+
+    // clear buffers when we change region or need a hard reset.
+    // static 
+    void StatsRecorder::clearStatsBuffers()
+    {
+        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+        using ST = StatType_t;
+
+        auto& statsTypeMatrix = statsDoubleBuffer[writeBuffer];
+        for(auto& statsMap : statsTypeMatrix)
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("Clear stats maps");
+            for(auto& stat_entry : statsMap)
+            {
+                std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0);
+            }
+            statsMap.clear();
+        }
+        for(int i=0; i< static_cast<size_t>(ObjType_t::OT_COUNT); i++)
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("clear max/sum");
+            max[writeBuffer][i].fill(0);
+            sum[writeBuffer][i].fill(0);
+        }
+        // swap the clean buffers in
+        if(enabled())
+        {
+            std::lock_guard<std::mutex> lock{bufferToggleLock};
+            writeBuffer ^= 1;
+        }; 
+        // repeat before we start processing new stuff
+        for(auto& statsMap : statsTypeMatrix)
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("Clear stats maps");
+            for(auto& stat_entry : statsMap)
+            {
+                std::fill_n(stat_entry.second.begin() ,static_cast<size_t>(ST::STATS_COUNT),0);
+            }
+            statsMap.clear();
+        }
+        for(int i=0; i< static_cast<size_t>(ObjType_t::OT_COUNT); i++)
+        {
+            LL_PROFILE_ZONE_NAMED_CATEGORY_STATS("clear max/sum");
+            max[writeBuffer][i].fill(0);
+            sum[writeBuffer][i].fill(0);
+        }
+    }
+
+    //static
+    int StatsRecorder::countNearbyAvatars(S32 distance)
+    {
+        const auto our_pos = gAgentCamera.getCameraPositionGlobal();
+
+       	std::vector<LLVector3d> positions;
+	    uuid_vec_t avatar_ids;
+        LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, our_pos, distance);
+        return positions.size();
+	}
+
+    // static
+    void StatsRecorder::updateAvatarParams()
+    {
+
+        if(tunables.userImpostorDistanceTuningEnabled)
+        {
+            // if we have less than the user's "max Non-Impostors" avatars within the desired range then adjust the limit.
+            // also adjusts back up again for nearby crowds.
+            auto count = countNearbyAvatars(std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance));
+            if( count != tunables.nonImpostors )
+            {
+                tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER );
+                LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance) << "m of the camera" << LL_ENDL;
+            }
+        }
+
+        auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
+        // Is our target frame time lower than current? If so we need to take action to reduce draw overheads.
+        // cumulative avatar time (includes idle processing, attachments and base av)
+        auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
+        // sleep time is basically forced sleep when window out of focus 
+        auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP);
+        // similar to sleep time, induced by FPS limit
+        //auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT);
+
+
+        // the time spent this frame on the "doFrame" call. Treated as "tot time for frame"
+        auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);
+
+        if( tot_sleep_time_raw != 0 )
+        {
+            // Note: we do not average sleep 
+            // if at some point we need to, the averaging will need to take this into account or 
+            // we forever think we're in the background due to residuals.
+            LL_DEBUGS() << "No tuning when not in focus" << LL_ENDL;
+            return;
+        }
+
+        // The frametime budget we have based on the target FPS selected
+        auto target_frame_time_raw = (U64)llround((F64)LLTrace::BlockTimer::countsPerSecond()/(tunables.userTargetFPS==0?1:tunables.userTargetFPS));
+        // LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL;
+        auto inferredFPS{1000/(U32)std::max(raw_to_ms(tot_frame_time_raw),1.0)};
+        U32 settingsChangeFrequency{inferredFPS > 25?inferredFPS:25};
+        /*if( tot_limit_time_raw != 0)
+        {
+            // This could be problematic.
+            tot_frame_time_raw -= tot_limit_time_raw;
+        }*/
+        // 1) Is the target frame time lower than current?
+        if( target_frame_time_raw <= tot_frame_time_raw )
+        {
+            if(belowTargetFPS == false)
+            {
+                // this is the first frame under. hold fire to add a little hysteresis
+                belowTargetFPS = true;
+                LLPerfStats::lastGlobalPrefChange = gFrameCount;
+            }
+            // if so we've got work to do
+
+            // how much of the frame was spent on non avatar related work?
+            U64 non_avatar_time_raw = tot_frame_time_raw - tot_avatar_time_raw;
+
+            // If the target frame time < scene time (estimated as non_avatar time)
+            U64 target_avatar_time_raw;
+            if(target_frame_time_raw < non_avatar_time_raw)
+            {
+                // we cannnot do this by avatar adjustment alone.
+                if((gFrameCount - LLPerfStats::lastGlobalPrefChange) > settingsChangeFrequency) // give  changes a short time to take effect.
+                {
+                    if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS)
+                    {
+                        // 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit.
+                        // the other reflection options make comparatively little change and if this overshoots we'll be stepping back up later
+                        if(LLPipeline::RenderReflectionDetail != -2)
+                        {
+                            LLPerfStats::tunables.updateReflectionDetail(-2);
+                            LLPerfStats::lastGlobalPrefChange = gFrameCount;
+                            return;
+                        }
+                        else // deliberately "else" here so we only do one of these in any given frame
+                        {
+                            // step down the DD by 10m per update
+                            auto new_dd = (LLPipeline::RenderFarClip - DD_STEP > tunables.userMinDrawDistance)?(LLPipeline::RenderFarClip - DD_STEP) : tunables.userMinDrawDistance;
+                            if(new_dd != LLPipeline::RenderFarClip)
+                            {
+                                LLPerfStats::tunables.updateFarClip( new_dd );
+                                LLPerfStats::lastGlobalPrefChange = gFrameCount;
+                                return;
+                            }
+                        }
+                    }
+                    // if we reach here, we've no more changes to make to tune scenery so we'll resort to agressive Avatar tuning
+                    // Note: moved from outside "if changefrequency elapsed" to stop fallthrough and allow scenery changes time to take effect.
+                    target_avatar_time_raw = 0;
+                }
+                else 
+                {
+                    // we made a settings change recently so let's give it time.
+                    return;
+                }
+            }
+            else
+            {
+                // set desired avatar budget.
+                target_avatar_time_raw =  target_frame_time_raw - non_avatar_time_raw;
+            }
+
+            if( target_avatar_time_raw < tot_avatar_time_raw )
+            {
+                // we need to spend less time drawing avatars to meet our budget
+                auto new_render_limit_ns {LLPerfStats::raw_to_ns(av_render_max_raw)};
+                // max render this frame may be higher than the last (cos new entrants and jitter) so make sure we are heading in the right direction
+                if( new_render_limit_ns > renderAvatarMaxART_ns )
+                {
+                    new_render_limit_ns = renderAvatarMaxART_ns;
+                }
+                new_render_limit_ns -= LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS;
+
+                // bounce at the bottom to prevent "no limit" 
+                new_render_limit_ns = std::max((U64)new_render_limit_ns, (U64)LLPerfStats::ART_MINIMUM_NANOS);
+
+                // assign the new value
+                if(renderAvatarMaxART_ns != new_render_limit_ns)
+                {
+                    renderAvatarMaxART_ns = new_render_limit_ns;
+                    tunables.updateSettingsFromRenderCostLimit();
+                }
+                // LL_DEBUGS() << "AUTO_TUNE: avatar_budget adjusted to:" << new_render_limit_ns << LL_ENDL;
+            }
+            // LL_DEBUGS() << "AUTO_TUNE: Target frame time:"<< LLPerfStats::raw_to_us(target_frame_time_raw) << "usecs (non_avatar is " << LLPerfStats::raw_to_us(non_avatar_time_raw) << "usecs) Max cost limited=" << renderAvatarMaxART_ns << LL_ENDL;
+        }
+        else if( LLPerfStats::raw_to_ns(target_frame_time_raw) > (LLPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns) )
+        {
+            if(belowTargetFPS == true)
+            {
+                // we reached target, force a pause
+                lastGlobalPrefChange = gFrameCount;
+                belowTargetFPS = false;
+            }
+
+            // once we're over the FPS target we slow down further
+            if((gFrameCount - lastGlobalPrefChange) > settingsChangeFrequency*3)
+            {
+                if(!tunables.userAutoTuneLock)
+                {
+                    // we've reached the target and stayed long enough to consider stable.
+                    // turn off if we are not locked.
+                    tunables.updateUserAutoTuneEnabled(false);
+                }
+                if( LLPerfStats::tunedAvatars > 0 )
+                {
+                    // if we have more time to spare let's shift up little in the hope we'll restore an avatar.
+                    renderAvatarMaxART_ns += LLPerfStats::ART_MIN_ADJUST_UP_NANOS;
+                    tunables.updateSettingsFromRenderCostLimit();
+                    return;
+                }
+                if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS)
+                {
+                    if( LLPipeline::RenderFarClip < tunables.userTargetDrawDistance ) 
+                    {
+                        LLPerfStats::tunables.updateFarClip( std::min(LLPipeline::RenderFarClip + DD_STEP, tunables.userTargetDrawDistance) );
+                        LLPerfStats::lastGlobalPrefChange = gFrameCount;
+                        return;
+                    }
+                    if( (tot_frame_time_raw * 1.5) < target_frame_time_raw )
+                    {
+                        // if everything else is "max" and we have >50% headroom let's knock the water quality up a notch at a time.
+                        LLPerfStats::tunables.updateReflectionDetail( std::min(LLPipeline::RenderReflectionDetail + 1, tunables.userTargetReflections) );
+                    }
+                }
+            }
+        }
+   }
+}
\ No newline at end of file
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
new file mode 100644
index 0000000000..1e867f5ef1
--- /dev/null
+++ b/indra/newview/llperfstats.h
@@ -0,0 +1,454 @@
+/** 
+* @file llperfstats.h
+* @brief Statistics collection to support autotune and perf flaoter.
+*
+* $LicenseInfo:firstyear=2022&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2022, Linden Research, Inc.
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+* 
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#pragma once
+#ifndef LL_PERFSTATS_H_INCLUDED
+#define LL_PERFSTATS_H_INCLUDED
+
+#include <atomic>
+#include <chrono>
+#include <array>
+#include <unordered_map>
+#include <mutex>
+#include "lluuid.h"
+#include "llfasttimer.h"
+#include "llapp.h"
+#include "llprofiler.h"
+#include "pipeline.h"
+
+extern U32 gFrameCount;
+extern LLUUID gAgentID;
+namespace LLPerfStats
+{
+// Note if changing these, they should correspond with the log range of the correpsonding sliders
+    static constexpr U64 ART_UNLIMITED_NANOS{50000000};
+    static constexpr U64 ART_MINIMUM_NANOS{100000};
+    static constexpr U64 ART_MIN_ADJUST_UP_NANOS{10000};
+    static constexpr U64 ART_MIN_ADJUST_DOWN_NANOS{10000}; 
+
+    static constexpr F32 PREFERRED_DD{180};
+    static constexpr U32 SMOOTHING_PERIODS{50};
+    static constexpr U32 DD_STEP{10};
+
+    static constexpr U32 TUNE_AVATARS_ONLY{0};
+    static constexpr U32 TUNE_SCENE_AND_AVATARS{1};
+
+    extern std::atomic<int64_t> tunedAvatars;
+    extern std::atomic<U64> renderAvatarMaxART_ns;
+    extern bool belowTargetFPS;
+    extern U32 lastGlobalPrefChange;
+    extern std::mutex bufferToggleLock;
+
+    enum class ObjType_t{
+        OT_GENERAL=0, // Also Unknown. Used for n/a type stats such as scenery
+        OT_AVATAR,
+        OT_ATTACHMENT,
+        OT_HUD,
+        OT_COUNT
+    };
+    enum class StatType_t{
+        RENDER_GEOMETRY=0,
+        RENDER_SHADOWS,
+        RENDER_HUDS,
+        RENDER_UI,
+        RENDER_COMBINED,
+        RENDER_SWAP,
+        RENDER_FRAME,
+        RENDER_DISPLAY,
+        RENDER_SLEEP,
+        RENDER_LFS,
+        RENDER_MESHREPO,
+        //RENDER_FPSLIMIT,
+        RENDER_FPS,
+        RENDER_IDLE,
+        RENDER_DONE, // toggle buffer & clearbuffer (see processUpdate for hackery)
+        STATS_COUNT
+    };
+
+    struct StatsRecord
+    { 
+        StatType_t  statType;
+        ObjType_t   objType;
+        LLUUID      avID;
+        LLUUID      objID;
+        uint64_t    time;
+        bool        isRigged;
+        bool        isHUD;
+    };
+
+    struct Tunables
+    {
+        static constexpr U32 Nothing{0};
+        static constexpr U32 NonImpostors{1};
+        static constexpr U32 ReflectionDetail{2};
+        static constexpr U32 FarClip{4};
+        static constexpr U32 UserMinDrawDistance{8};
+        static constexpr U32 UserTargetDrawDistance{16};
+        static constexpr U32 UserImpostorDistance{32};
+        static constexpr U32 UserImpostorDistanceTuningEnabled{64};
+        static constexpr U32 UserFPSTuningStrategy{128};
+        static constexpr U32 UserAutoTuneEnabled{256};
+        static constexpr U32 UserTargetFPS{512};
+        static constexpr U32 UserARTCutoff{1024};
+        static constexpr U32 UserTargetReflections{2048};
+        static constexpr U32 UserAutoTuneLock{4096};
+
+        U32 tuningFlag{0}; // bit mask for changed settings
+
+        // proxy variables, used to pas the new value to be set via the mainthread
+        U32 nonImpostors{0}; 
+        S32 reflectionDetail{0}; 
+        F32 farClip{0.0}; 
+        F32 userMinDrawDistance{0.0}; 
+        F32 userTargetDrawDistance{0.0};
+        F32 userImpostorDistance{0.0};
+        bool userImpostorDistanceTuningEnabled{false};
+        U32 userFPSTuningStrategy{0};
+        bool userAutoTuneEnabled{false};
+        bool userAutoTuneLock{true};
+        U32 userTargetFPS{0};
+        F32 userARTCutoffSliderValue{0};
+        S32 userTargetReflections{0};
+
+        void updateNonImposters(U32 nv){nonImpostors=nv; tuningFlag |= NonImpostors;};
+        void updateReflectionDetail(S32 nv){reflectionDetail=nv; tuningFlag |= ReflectionDetail;};
+        void updateFarClip(F32 nv){farClip=nv; tuningFlag |= FarClip;};
+        void updateUserMinDrawDistance(F32 nv){userMinDrawDistance=nv; tuningFlag |= UserMinDrawDistance;};
+        void updateUserTargetDrawDistance(F32 nv){userTargetDrawDistance=nv; tuningFlag |= UserTargetDrawDistance;};
+        void updateImposterDistance(F32 nv){userImpostorDistance=nv; tuningFlag |= UserImpostorDistance;};
+        void updateImposterDistanceTuningEnabled(bool nv){userImpostorDistanceTuningEnabled=nv; tuningFlag |= UserImpostorDistanceTuningEnabled;};
+        void updateUserFPSTuningStrategy(U32 nv){userFPSTuningStrategy=nv; tuningFlag |= UserFPSTuningStrategy;};
+        void updateTargetFps(U32 nv){userTargetFPS=nv; tuningFlag |= UserTargetFPS;};
+        void updateUserARTCutoffSlider(F32 nv){userARTCutoffSliderValue=nv; tuningFlag |= UserARTCutoff;};
+        void updateUserAutoTuneEnabled(bool nv){userAutoTuneEnabled=nv; tuningFlag |= UserAutoTuneEnabled;};
+        void updateUserAutoTuneLock(bool nv){userAutoTuneLock=nv; tuningFlag |= UserAutoTuneLock;};
+        void updateUserTargetReflections(S32 nv){userTargetReflections=nv; tuningFlag |= UserTargetReflections;};
+
+        void resetChanges(){tuningFlag=Nothing;};
+        void initialiseFromSettings();
+        void updateRenderCostLimitFromSettings();
+        void updateSettingsFromRenderCostLimit();
+        void applyUpdates();
+    };
+
+    extern Tunables tunables;
+
+    class StatsRecorder{
+        using Queue = LLThreadSafeQueue<StatsRecord>;
+    public:
+
+        static inline StatsRecorder& getInstance()
+        {
+            static StatsRecorder instance;
+            return instance;
+        }
+        static inline void setFocusAv(const LLUUID& avID){focusAv = avID;};
+        static inline const LLUUID& getFocusAv(){return focusAv;};
+        static inline void send(StatsRecord && upd){StatsRecorder::getInstance().q.pushFront(std::move(upd));};
+        static void endFrame(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 0});};
+        static void clearStats(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 1});};
+
+        static inline void setEnabled(bool on_or_off){collectionEnabled=on_or_off;};
+        static inline void enable()     { collectionEnabled=true; };
+        static inline void disable()    { collectionEnabled=false; };
+        static inline bool enabled()    { return collectionEnabled; };
+
+        static inline int getReadBufferIndex() { return (writeBuffer ^ 1); };
+        // static inline const StatsTypeMatrix& getCurrentStatsMatrix(){ return statsDoubleBuffer[getReadBufferIndex()];}
+        static inline uint64_t get(ObjType_t otype, LLUUID id, StatType_t type)
+        {
+            return statsDoubleBuffer[getReadBufferIndex()][static_cast<size_t>(otype)][id][static_cast<size_t>(type)];
+        }
+        static inline uint64_t getSceneStat(StatType_t type)
+        {
+            return statsDoubleBuffer[getReadBufferIndex()][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(type)];
+        }
+
+        static inline uint64_t getSum(ObjType_t otype, StatType_t type)
+        {
+            return sum[getReadBufferIndex()][static_cast<size_t>(otype)][static_cast<size_t>(type)];
+        }
+        static inline uint64_t getMax(ObjType_t otype, StatType_t type)
+        {
+            return max[getReadBufferIndex()][static_cast<size_t>(otype)][static_cast<size_t>(type)];
+        }
+        static void updateAvatarParams();
+    private:
+        StatsRecorder();
+
+        static int countNearbyAvatars(S32 distance);
+// StatsArray is a uint64_t for each possible statistic type.
+        using StatsArray    = std::array<uint64_t, static_cast<size_t>(LLPerfStats::StatType_t::STATS_COUNT)>;
+        using StatsMap      = std::unordered_map<LLUUID, StatsArray, boost::hash<LLUUID>>;
+        using StatsTypeMatrix = std::array<StatsMap, static_cast<size_t>(LLPerfStats::ObjType_t::OT_COUNT)>;
+        using StatsSummaryArray = std::array<StatsArray, static_cast<size_t>(LLPerfStats::ObjType_t::OT_COUNT)>;
+
+        static std::atomic<int> writeBuffer;
+        static LLUUID focusAv;
+        static std::array<StatsTypeMatrix,2> statsDoubleBuffer;
+        static std::array<StatsSummaryArray,2> max;
+        static std::array<StatsSummaryArray,2> sum;
+        static bool collectionEnabled;
+
+
+        void processUpdate(const StatsRecord& upd) const
+        {
+            LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+            // LL_INFOS("perfstats") << "processing update:" << LL_ENDL;
+            // Note: nullptr is used as the key for global stats
+            #ifdef TRACY_ENABLE
+            static char avstr[36];
+            static char obstr[36];
+            #endif
+
+            if (upd.statType == StatType_t::RENDER_DONE && upd.objType == ObjType_t::OT_GENERAL && upd.time == 0)
+            {
+                // LL_INFOS("perfstats") << "End of Frame Toggle Buffer:" << gFrameCount << LL_ENDL;
+                toggleBuffer();
+                return;
+            }
+            if (upd.statType == StatType_t::RENDER_DONE && upd.objType == ObjType_t::OT_GENERAL && upd.time == 1)
+            {
+                // LL_INFOS("perfstats") << "New region - clear buffers:" << gFrameCount << LL_ENDL;
+                clearStatsBuffers();
+                return;
+            }
+
+            auto ot{upd.objType};
+            auto& key{upd.objID};
+            auto& avKey{upd.avID};
+            auto type {upd.statType};
+            auto val {upd.time};
+
+            if (ot == ObjType_t::OT_GENERAL)
+            {
+                // LL_INFOS("perfstats") << "General update:" << LL_ENDL;
+                doUpd(key, ot, type,val);
+                return;
+            }
+
+            if (ot == ObjType_t::OT_AVATAR)
+            {
+                // LL_INFOS("perfstats") << "Avatar update:" << LL_ENDL;
+                doUpd(avKey, ot, type, val);
+                return;
+            }
+
+            if (ot == ObjType_t::OT_ATTACHMENT)
+            {
+                if( !upd.isHUD ) // don't include HUD cost in self.
+                {
+                    LL_PROFILE_ZONE_NAMED("Att as Av")
+                    // For all attachments that are not rigged we add them to the avatar (for all avatars) cost.
+                    doUpd(avKey, ObjType_t::OT_AVATAR, type, val);
+                }
+                if( avKey == focusAv )
+                {
+                    LL_PROFILE_ZONE_NAMED("Att as Att")
+                // For attachments that are for the focusAv (self for now) we record them for the attachment/complexity view
+                    if(upd.isHUD)
+                    {
+                        ot = ObjType_t::OT_HUD;
+                    }
+                    // LL_INFOS("perfstats") << "frame: " << gFrameCount << " Attachment update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << LL_ENDL;
+                    doUpd(key, ot, type, val);
+                }
+                // else
+                // {
+                //     // LL_INFOS("perfstats") << "frame: " << gFrameCount << " non-self Att update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << " for av " << avKey.asString() << LL_ENDL;
+                // }
+            }
+        }
+
+        static inline void doUpd(const LLUUID& key, ObjType_t ot, StatType_t type, uint64_t val)
+        {
+            LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+            using ST = StatType_t;
+            StatsMap& stm {statsDoubleBuffer[writeBuffer][static_cast<size_t>(ot)]};
+            auto& thisAsset = stm[key];
+
+            thisAsset[static_cast<size_t>(type)] += val;
+            thisAsset[static_cast<size_t>(ST::RENDER_COMBINED)] += val;
+
+            sum[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(type)] += val;
+            sum[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(ST::RENDER_COMBINED)] += val;
+
+            if(max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(type)] < thisAsset[static_cast<size_t>(type)])
+            {
+                max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(type)] = thisAsset[static_cast<size_t>(type)];
+            }
+            if(max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(ST::RENDER_COMBINED)] < thisAsset[static_cast<size_t>(ST::RENDER_COMBINED)])
+            {
+                max[writeBuffer][static_cast<size_t>(ot)][static_cast<size_t>(ST::RENDER_COMBINED)] = thisAsset[static_cast<size_t>(ST::RENDER_COMBINED)];
+            }
+        }
+
+        static void toggleBuffer();
+        static void clearStatsBuffers();
+
+        // thread entry
+        static void run()
+        {
+            StatsRecord upd[10];
+            auto & instance {StatsRecorder::getInstance()};
+            LL_PROFILER_SET_THREAD_NAME("PerfStats");
+
+            while( enabled() && !LLApp::isExiting() )
+            {
+                auto count = 0;
+                while (count < 10)
+                {
+                    if (instance.q.tryPopFor(std::chrono::milliseconds(10), upd[count]))
+                    {
+                        count++;
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+                //LL_PROFILER_THREAD_BEGIN("PerfStats");
+                if(count)
+                {
+                    // LL_INFOS("perfstats") << "processing " << count << " updates." << LL_ENDL;
+                    for(auto i =0; i < count; i++)
+                    {
+                        instance.processUpdate(upd[i]);
+                    }
+                }
+                //LL_PROFILER_THREAD_END("PerfStats");
+            }
+        }
+
+        Queue q;
+        std::thread t;
+
+        ~StatsRecorder() = default;
+        StatsRecorder(const StatsRecorder&) = delete;
+        StatsRecorder& operator=(const StatsRecorder&) = delete;
+
+    };
+
+    template <enum ObjType_t ObjTypeDiscriminator>
+    class RecordTime
+    {
+
+    private:
+        RecordTime(const RecordTime&) = delete;
+        RecordTime() = delete;
+        U64 start;
+    public:
+        StatsRecord stat;
+
+        RecordTime( const LLUUID& av, const LLUUID& id, StatType_t type, bool isRiggedAtt=false, bool isHUDAtt=false):
+                    start{LLTrace::BlockTimer::getCPUClockCount64()},
+                    stat{type, ObjTypeDiscriminator, std::move(av), std::move(id), 0, isRiggedAtt, isHUDAtt}
+        {
+            //LL_PROFILE_ZONE_COLOR(tracy::Color::Orange);
+        };
+
+        template < ObjType_t OD = ObjTypeDiscriminator,
+                   std::enable_if_t<OD == ObjType_t::OT_GENERAL> * = nullptr>
+        explicit RecordTime( StatType_t type ):RecordTime<ObjTypeDiscriminator>(LLUUID::null, LLUUID::null, type )
+        {
+            LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+        };
+
+        template < ObjType_t OD = ObjTypeDiscriminator,
+                   std::enable_if_t<OD == ObjType_t::OT_AVATAR> * = nullptr>
+        RecordTime( const LLUUID & av, StatType_t type ):RecordTime<ObjTypeDiscriminator>(std::move(av), LLUUID::null, type)
+        {
+            //LL_PROFILE_ZONE_COLOR(tracy::Color::Purple);
+        };
+
+        ~RecordTime()
+        { 
+            if(!LLPerfStats::StatsRecorder::enabled())
+            {
+                return;
+            }
+
+            //LL_PROFILE_ZONE_COLOR(tracy::Color::Red);
+
+            stat.time = LLTrace::BlockTimer::getCPUClockCount64() - start;
+            StatsRecorder::send(std::move(stat));
+        };
+    };
+
+    
+    inline double raw_to_ns(U64 raw)    { return (static_cast<double>(raw) * 1000000000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
+    inline double raw_to_us(U64 raw)    { return (static_cast<double>(raw) *    1000000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
+    inline double raw_to_ms(U64 raw)    { return (static_cast<double>(raw) *       1000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
+
+    using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>;
+    using RecordAvatarTime = RecordTime<ObjType_t::OT_AVATAR>;
+    using RecordAttachmentTime = RecordTime<ObjType_t::OT_ATTACHMENT>;
+    using RecordHudAttachmentTime = RecordTime<ObjType_t::OT_HUD>;
+     
+};// namespace LLPerfStats
+
+// helper functions
+using RATptr = std::unique_ptr<LLPerfStats::RecordAttachmentTime>;
+using RSTptr = std::unique_ptr<LLPerfStats::RecordSceneTime>;
+
+template <typename T>
+static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPtrp)
+{
+    if( !vobj ){ ratPtrp->reset(); return;};
+    
+    const T* rootAtt{vobj};
+    if (rootAtt->isAttachment())
+    {
+        LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+
+        while( !rootAtt->isRootEdit() )
+        {
+            rootAtt = (T*)(rootAtt->getParent());
+        }
+
+        auto avPtr = (T*)(rootAtt->getParent()); 
+        if(!avPtr){ratPtrp->reset(); return;}
+
+        auto& av = avPtr->getID();
+        auto& obj = rootAtt->getAttachmentItemID();
+        if (!*ratPtrp || (*ratPtrp)->stat.objID != obj || (*ratPtrp)->stat.avID != av)
+        {
+            if (*ratPtrp)
+            {
+                // deliberately reset to ensure destruction before construction of replacement.
+                ratPtrp->reset();
+            };
+            *ratPtrp = std::make_unique<LLPerfStats::RecordAttachmentTime>( 
+                av, 
+                obj,
+                ( LLPipeline::sShadowRender?LLPerfStats::StatType_t::RENDER_SHADOWS : LLPerfStats::StatType_t::RENDER_GEOMETRY ), 
+                isRigged, 
+                rootAtt->isHUDAttachment());
+        }
+    }
+    return;
+};
+
+#endif
\ No newline at end of file
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index dc48eaa823..9cbd56ee7f 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -207,6 +207,7 @@
 #include "llstacktrace.h"
 
 #include "threadpool.h"
+#include "llperfstats.h"
 
 
 #if LL_WINDOWS
@@ -1492,6 +1493,8 @@ bool idle_startup()
 			LLViewerParcelAskPlay::getInstance()->loadSettings();
 		}
 
+		gAgent.addRegionChangedCallback(boost::bind(&LLPerfStats::StatsRecorder::clearStats));
+
 		// *Note: this is where gWorldMap used to be initialized.
 
 		// register null callbacks for audio until the audio system is initialized
@@ -3405,6 +3408,9 @@ bool process_login_success_response()
 	if(!text.empty()) gAgentID.set(text);
 	gDebugInfo["AgentID"] = text;
 	
+	LLPerfStats::StatsRecorder::setEnabled(gSavedSettings.getBOOL("PerfStatsCaptureEnabled"));
+	LLPerfStats::StatsRecorder::setFocusAv(gAgentID);
+
 	// Agent id needed for parcel info request in LLUrlEntryParcel
 	// to resolve parcel name.
 	LLUrlEntryParcel::setAgentID(gAgentID);
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index fd07fc32bc..e5723ebfe5 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -75,6 +75,7 @@
 #include "llspellcheck.h"
 #include "llslurl.h"
 #include "llstartup.h"
+#include "llperfstats.h"
 
 // Third party library includes
 #include <boost/algorithm/string.hpp>
@@ -643,6 +644,66 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
 }
 
 void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);
+
+void handleTargetFPSChanged(const LLSD& newValue)
+{
+    const auto targetFPS = gSavedSettings.getU32("TargetFPS");
+    LLPerfStats::tunables.userTargetFPS = targetFPS;
+}
+
+void handleAutoTuneLockChanged(const LLSD& newValue)
+{
+    const auto newval = gSavedSettings.getBOOL("AutoTuneLock");
+    LLPerfStats::tunables.userAutoTuneLock = newval;
+}
+
+void handleAutoTuneFPSChanged(const LLSD& newValue)
+{
+    const auto newval = gSavedSettings.getBOOL("AutoTuneFPS");
+    LLPerfStats::tunables.userAutoTuneEnabled = newval;
+    if(newval && LLPerfStats::renderAvatarMaxART_ns == 0) // If we've enabled autotune we override "unlimited" to max
+    {
+        gSavedSettings.setF32("RenderAvatarMaxART",log10(LLPerfStats::ART_UNLIMITED_NANOS-1000));//triggers callback to update static var
+    }
+}
+
+void handleRenderAvatarMaxARTChanged(const LLSD& newValue)
+{
+    LLPerfStats::tunables.updateRenderCostLimitFromSettings();
+}
+
+void handleUserTargetDrawDistanceChanged(const LLSD& newValue)
+{
+    const auto newval = gSavedSettings.getF32("AutoTuneRenderFarClipTarget");
+    LLPerfStats::tunables.userTargetDrawDistance = newval;
+}
+
+void handleUserTargetReflectionsChanged(const LLSD& newValue)
+{
+    const auto newval = gSavedSettings.getS32("UserTargetReflections");
+    LLPerfStats::tunables.userTargetReflections = newval;
+}
+
+void handlePerformanceStatsEnabledChanged(const LLSD& newValue)
+{
+    const auto newval = gSavedSettings.getBOOL("PerfStatsCaptureEnabled");
+    LLPerfStats::StatsRecorder::setEnabled(newval);
+}
+void handleUserImpostorByDistEnabledChanged(const LLSD& newValue)
+{
+    const auto newval = gSavedSettings.getBOOL("AutoTuneImpostorByDistEnabled");
+    LLPerfStats::tunables.userImpostorDistanceTuningEnabled = newval;
+}
+void handleUserImpostorDistanceChanged(const LLSD& newValue)
+{
+    const auto newval = gSavedSettings.getF32("AutoTuneImpostorFarAwayDistance");
+    LLPerfStats::tunables.userImpostorDistance = newval;
+}
+void handleFPSTuningStrategyChanged(const LLSD& newValue)
+{
+    const auto newval = gSavedSettings.getU32("TuningFPSStrategy");
+    LLPerfStats::tunables.userFPSTuningStrategy = newval;
+}
 ////////////////////////////////////////////////////////////////////////////
 
 void settings_setup_listeners()
@@ -796,6 +857,17 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2));
 	gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2));
 	gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&handleAvatarHoverOffsetChanged, _2));
+
+    gSavedSettings.getControl("TargetFPS")->getSignal()->connect(boost::bind(&handleTargetFPSChanged, _2));
+    gSavedSettings.getControl("AutoTuneFPS")->getSignal()->connect(boost::bind(&handleAutoTuneFPSChanged, _2));
+    gSavedSettings.getControl("AutoTuneLock")->getSignal()->connect(boost::bind(&handleAutoTuneLockChanged, _2));
+    gSavedSettings.getControl("RenderAvatarMaxART")->getSignal()->connect(boost::bind(&handleRenderAvatarMaxARTChanged, _2));
+    gSavedSettings.getControl("PerfStatsCaptureEnabled")->getSignal()->connect(boost::bind(&handlePerformanceStatsEnabledChanged, _2));
+    gSavedSettings.getControl("UserTargetReflections")->getSignal()->connect(boost::bind(&handleUserTargetReflectionsChanged, _2));
+    gSavedSettings.getControl("AutoTuneRenderFarClipTarget")->getSignal()->connect(boost::bind(&handleUserTargetDrawDistanceChanged, _2));
+    gSavedSettings.getControl("AutoTuneImpostorFarAwayDistance")->getSignal()->connect(boost::bind(&handleUserImpostorDistanceChanged, _2));
+    gSavedSettings.getControl("AutoTuneImpostorByDistEnabled")->getSignal()->connect(boost::bind(&handleUserImpostorByDistEnabledChanged, _2));
+    gSavedSettings.getControl("TuningFPSStrategy")->getSignal()->connect(boost::bind(&handleFPSTuningStrategyChanged, _2));
 }
 
 #if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index be54cb2f96..fa026c2888 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -78,6 +78,7 @@
 #include "llscenemonitor.h"
 
 #include "llenvironment.h"
+#include "llperfstats.h"
 
 extern LLPointer<LLViewerTexture> gStartTexture;
 extern bool gShiftFrame;
@@ -256,7 +257,8 @@ static LLTrace::BlockTimerStatHandle FTM_EEP_UPDATE("Env Update");
 // Paint the display!
 void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 {
-	LL_RECORD_BLOCK_TIME(FTM_RENDER);
+    LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_DISPLAY); // render time capture - This is the main stat for overall rendering.
+    LL_RECORD_BLOCK_TIME(FTM_RENDER);
 
 	if (gWindowResized)
 	{ //skip render on frames where window has been resized
@@ -1051,7 +1053,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 
 void render_hud_attachments()
 {
-	gGL.matrixMode(LLRender::MM_PROJECTION);
+    LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_HUDS); // render time capture - Primary contributor to HUDs (though these end up in render batches)
+    gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
@@ -1242,7 +1245,8 @@ bool setup_hud_matrices(const LLRect& screen_region)
 
 void render_ui(F32 zoom_factor, int subfield)
 {
-	LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
+    LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_UI ); // render time capture - Primary UI stat can have HUD time overlap (TODO)
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
 
 	LLGLState::checkStates();
 	
@@ -1325,7 +1329,8 @@ static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
 
 void swap()
 {
-	LL_RECORD_BLOCK_TIME(FTM_SWAP);
+    LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SWAP ); // render time capture - Swap buffer time - can signify excessive data transfer to/from GPU
+    LL_RECORD_BLOCK_TIME(FTM_SWAP);
 
 	if (gDisplaySwapBuffers)
 	{
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index f3b0e82b3a..489f90aabb 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -55,6 +55,7 @@
 #include "m3math.h"
 #include "m4math.h"
 #include "llmatrix4a.h"
+#include "llperfstats.h" 
 
 #if !LL_DARWIN && !LL_LINUX
 extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
@@ -230,6 +231,16 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 		return 0;
 	}
 
+    // render time capture
+    // This path does not appear to have attachments. Prove this then remove.
+    std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
+    auto vobj = mFace->getViewerObject();
+    if( vobj && vobj->isAttachment() )
+    {
+        trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr );
+        LL_WARNS("trackAttachments") << "Attachment render time is captuted." << LL_ENDL;
+    }
+
 	U32 triangle_count = 0;
 
 	S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel;
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b66a6958fe..1a71780a88 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -113,6 +113,8 @@
 #include "llrendersphere.h"
 #include "llskinningutil.h"
 
+#include "llperfstats.h"
+
 #include <boost/lexical_cast.hpp>
 
 extern F32 SPEED_ADJUST_MAX;
@@ -2544,6 +2546,9 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
 		LL_INFOS() << "Warning!  Idle on dead avatar" << LL_ENDL;
 		return;
 	}
+    // record time and refresh "tooSlow" status
+    LLPerfStats::RecordAvatarTime T(getID(), LLPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time.
+    updateTooSlow();
 
 	static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");
 	if (!(gPipeline.hasRenderType(mIsControlAvatar ? LLPipeline::RENDER_TYPE_CONTROL_AV : LLPipeline::RENDER_TYPE_AVATAR))
@@ -8268,6 +8273,94 @@ bool LLVOAvatar::isTooComplex() const
 	return too_complex;
 }
 
+// use Avatar Render Time as complexity metric
+// markARTStale - Mark stale and set the frameupdate to now so that we can wait at least one frame to get a revised number.
+void LLVOAvatar::markARTStale()
+{
+    mARTStale=true;
+    mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
+}
+
+// Udpate Avatar state based on render time
+void LLVOAvatar::updateTooSlow()
+{
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+    static LLCachedControl<bool> alwaysRenderFriends(gSavedSettings, "AlwaysRenderFriends");
+    static LLCachedControl<bool> allowSelfImpostor(gSavedSettings, "AllowSelfImpostor");
+    const auto id = getID();
+
+    // mTooSlow - Is the avatar flagged as being slow (includes shadow time)
+    // mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed.
+    // mARTStale - the rendertime we have is stale because of an update. We need to force a re-render to re-assess slowness
+
+    if( mARTStale )
+    {
+        if ( LLFrameTimer::getFrameCount() - mLastARTUpdateFrame < 5 ) 
+        {
+            // LL_INFOS() << this->getFullname() << " marked stale " << LL_ENDL;
+            // we've not had a chance to update yet (allow a few to be certain a full frame has passed)
+            return;
+        }
+
+        mARTStale = false;
+        mTooSlow = false;
+        mTooSlowWithoutShadows = false;
+        // LL_INFOS() << this->getFullname() << " refreshed ART combined = " << mRenderTime << " @ " << mLastARTUpdateFrame << LL_ENDL;
+    }
+
+    // Either we're not stale or we've updated.
+
+    U64 render_time_raw;
+    U64 render_geom_time_raw;
+
+    if( !mTooSlow ) 
+    {
+        // we are fully rendered, so we use the live values
+        std::lock_guard<std::mutex> lock{LLPerfStats::bufferToggleLock};
+        render_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_COMBINED);
+        render_geom_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_GEOMETRY);
+    }
+    else
+    {
+        // use the cached values.
+        render_time_raw = mRenderTime;
+        render_geom_time_raw = mGeomTime;		
+    }
+    if( (LLPerfStats::renderAvatarMaxART_ns > 0) && 
+        (LLPerfStats::raw_to_ns(render_time_raw) >= LLPerfStats::renderAvatarMaxART_ns) ) 
+    {
+        if( !mTooSlow ) // if we were previously not slow (with or without shadows.)
+        {			
+            // if we weren't capped, we are now
+            mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
+            mRenderTime = render_time_raw;
+            mGeomTime = render_geom_time_raw;
+            mARTStale = false;
+            mTooSlow = true;
+        }
+        if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap
+        {
+            bool render_friend_or_exception =  	( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) ||
+                ( getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER ); 
+            if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception  )
+            {
+                // Note: slow rendering Friends still get their shadows zapped.
+                mTooSlowWithoutShadows = (LLPerfStats::raw_to_ns(render_geom_time_raw) >= LLPerfStats::renderAvatarMaxART_ns);
+            }
+        }
+    }
+    else
+    {
+        // LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") good render time = " << LLPerfStats::raw_to_ns(render_time_raw) << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL;
+        mTooSlow = false;
+        mTooSlowWithoutShadows = false;	
+    }
+    if(mTooSlow)
+    {
+        LLPerfStats::tunedAvatars++; // increment the number of avatars that have been tweaked.
+    }
+}
+
 //-----------------------------------------------------------------------------
 // findMotion()
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index e9c3d48a78..a27327d8a3 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -350,6 +350,18 @@ public:
 	//--------------------------------------------------------------------
 public:
 	BOOL			isFullyLoaded() const;
+
+    // check and return current state relative to limits
+    // default will test only the geometry (combined=false).
+    // this allows us to disable shadows separately on complex avatars.
+    inline bool 	isTooSlowWithShadows() const {return mTooSlow;};
+    inline bool 	isTooSlowWithoutShadows() const {return mTooSlowWithoutShadows;};
+    inline bool 	isTooSlow(bool combined = false) const 
+    {
+        return(combined?mTooSlow:mTooSlowWithoutShadows);
+    }
+    void 			updateTooSlow();
+
 	bool 			isTooComplex() const;
 	bool 			visualParamWeightsAreDefault();
 	virtual bool	getIsCloud() const;
@@ -369,6 +381,7 @@ public:
 	void 			logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);
 
     void            calcMutedAVColor();
+    void            markARTStale();
 
 protected:
 	LLViewerStats::PhaseMap& getPhases() { return mPhases; }
@@ -390,6 +403,15 @@ private:
 	LLFrameTimer	mFullyLoadedTimer;
 	LLFrameTimer	mRuthTimer;
 
+    U32				mLastARTUpdateFrame{0};
+    U64				mRenderTime{0};
+    U64				mGeomTime{0};
+    bool			mARTStale{true};
+    bool			mARTCapped{false};
+    // variables to hold "slowness" status
+    bool			mTooSlow{false};
+    bool			mTooSlowWithoutShadows{false};
+
 private:
 	LLViewerStats::PhaseMap mPhases;
 
@@ -1145,6 +1167,8 @@ public:
 	// COF version of last appearance message received for this av.
 	S32 mLastUpdateReceivedCOFVersion;
 
+    U64 getLastART() const { return mRenderTime; }
+
 /**                    Diagnostics
  **                                                                            **
  *******************************************************************************/
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index f4a938e57d..77d1511dcd 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -88,6 +88,7 @@
 #include "llcallstack.h"
 #include "llsculptidsize.h"
 #include "llavatarappearancedefines.h"
+#include "llperfstats.h" 
 
 const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
 const F32 FORCE_CULL_AREA = 8.f;
@@ -5589,6 +5590,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
         LL_PROFILE_ZONE_NAMED("rebuildGeom - face list");
 
 		//get all the faces into a list
+        std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
 		for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); 
              drawable_iter != group->getDataEnd(); ++drawable_iter)
 		{
@@ -5620,6 +5622,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 				continue;
 			}
 
+            if(vobj->isAttachment())
+            {
+                trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED),&ratPtr);
+            }
+
 			LLVolume* volume = vobj->getVolume();
 			if (volume)
 			{
@@ -6010,6 +6017,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 
 			U32 buffer_count = 0;
 
+            std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
 			for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
 			{
 				LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
@@ -6019,6 +6027,11 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
 					LLVOVolume* vobj = drawablep->getVOVolume();
 					
 					if (!vobj) continue;
+
+                    if (vobj->isAttachment())
+                    {
+                        trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr );
+                    }
 					
 					if (debugLoggingEnabled("AnimatedObjectsLinkset"))
 					{
@@ -6458,10 +6471,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
 		U32 indices_index = 0;
 		U16 index_offset = 0;
 
-		while (face_iter < i)
+        std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr;
+        while (face_iter < i)
 		{
 			//update face indices for new buffer
 			facep = *face_iter;
+            LLViewerObject* vobj = facep->getViewerObject();
+            if(vobj && vobj->isAttachment())
+            {
+                trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr);
+            }
 			if (buffer.isNull())
 			{
 				// Bulk allocation failed
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index bf2623f356..ee88701037 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -277,6 +277,52 @@
        top="19"
        right="-20"/>
     </panel>
+    <panel
+     bg_alpha_color="PanelGray"
+     background_visible="true"
+     background_opaque="false"
+     border="true"
+     bevel_style="none"
+     follows="left|top"
+     height="50"
+     width="560"
+     name="autoadjustments_subpanel"
+     layout="topleft"
+     top_pad="10">
+      <text
+       follows="left|top"
+       font="SansSerifLarge"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="auto_adj_lbl"
+       top="7"
+       width="175">
+        Preferred frame rate
+      </text>
+      <text
+       follows="left|top"
+       font="SansSerif"
+       text_color="White"
+       height="20"
+       layout="topleft"
+       left="10"
+       name="auto_adj_desc"
+       top_pad="0"
+       width="485">
+        Allow automatic adjustments to reach your preferred frame rate (advanced).
+      </text>
+      <icon
+       height="16"
+       width="16"
+       image_name="Arrow_Right_Off"
+       mouse_opaque="true"
+       name="icon_arrow4"
+       follows="right|top"
+       top="19"
+       right="-20"/>
+    </panel>
   </panel>
   <panel
     filename="panel_performance_nearby.xml"
@@ -310,4 +356,12 @@
     name="panel_performance_huds"
     visible="false"
     top="55" />
+  <panel
+    filename="panel_performance_autoadjustments.xml"
+    follows="all"
+    layout="topleft"
+    left="0"
+    name="panel_performance_autoadjustments"
+    visible="false"
+    top="55" />
 </floater>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
new file mode 100644
index 0000000000..10ac4b98b7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
@@ -0,0 +1,272 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ bevel_style="none"
+ follows="left|top"
+ height="580"
+ width="580"
+ name="panel_performance_autoadjustments"
+ layout="topleft"
+ left="0"
+ top="0">
+  <button
+    height="16"
+    width="16"
+    layout="topleft"
+    mouse_opaque="true"
+    follows="left|top"
+    name="back_btn"
+    top="7"
+    image_selected="Arrow_Left_Off"
+    image_pressed="Arrow_Left_Off"
+    image_unselected="Arrow_Left_Off"
+    left="15"
+    is_toggle="true">
+  </button>
+  <text
+   follows="left|top"
+   height="20"
+   layout="topleft"
+   left_pad="3"
+   top="10"
+   name="back_lbl"
+   width="40">
+    Back
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifLarge"
+   text_color="white"
+   height="20"
+   layout="topleft"
+   left="20"
+   top_pad="10"
+   name="settings_title"
+   width="300">
+    Preferred frame rate
+  </text>
+  <view_border
+   bevel_style="in"
+   height="0"
+   layout="topleft"
+   name="border0"
+   top_pad="15"
+   left="20"
+   width="540"/>
+  <text
+   follows="left|top"
+   font="SansSerif"
+   text_color="White"
+   height="20"
+   layout="topleft"
+   left="20"
+   name="targetfps_desc"
+   wrap="true"
+   width="140"
+   top_pad="20">
+    Desired frame rate
+  </text>
+  <spinner
+   name="target_fps"
+   control_name="TargetFPS"
+   font="SansSerifLarge"
+   tool_tip="The viewer will attempt to achieve this by adjusting your graphics settings."
+   layout="topleft"
+   follows="right|top"
+   left_pad="5"
+   top_delta="0"
+   height="25"
+   visible="true"
+   decimal_digits="0"
+   increment="1"
+   initial_value="25"
+   max_val="300"
+   min_val="1"
+   width="48"
+   label_width="0" />
+  <button
+   control_name="AutoTuneFPS"
+   follows="top|right"
+   height="24"
+   initial_value="false"
+   image_pressed="PushButton_Press"
+   image_pressed_selected="PushButton_Selected_Press"
+   image_selected="PushButton_Selected_Press"
+   is_toggle="true"
+   label="Start"
+   label_selected="Stop"
+   layout="topleft"
+   left_pad="10"
+   name="AutoTuneFPS"
+   top_delta="-1"
+   tool_tip="The viewer will attempt to adjust settings to meet the target FPS."
+   width="72">
+  </button>
+  <check_box
+   control_name="AutoTuneLock"
+   follows="top|right"
+   height="20"
+   initial_value="true"
+   image_pressed="PushButton_Press"
+   image_pressed_selected="PushButton_Selected_Press"
+   image_selected="PushButton_Selected_Press"
+   is_toggle="true"
+   label="Continuous"
+   layout="topleft"
+   left_pad="10"
+   name="AutoTuneContinuous"
+   top_delta="0"
+   tool_tip="The viewer will continually adapt the settings to meet the target FPS until stopped even with the floater closed. When disabled clicking the Auto Tune button will adjust for the current settings then stop."
+   width="64">
+  </check_box>
+  <text
+   follows="left|top"
+   font="SansSerif"
+   text_color="White"
+   height="20"
+   layout="topleft"
+   left="20"
+   name="settings_desc"
+   top_pad="20"
+   wrap="true"
+   width="150">
+    Settings affect
+  </text>
+  <combo_box
+   follows="top|left"
+   font="SansSerif"
+   height="20"
+   layout="topleft"
+   left_pad="15"
+   control_name="TuningFPSStrategy"
+   name="TuningFPSStrategy"
+   width="130">
+    <combo_box.item
+     label="Avatars Only"
+     name="av_only"
+     value="0" />
+    <combo_box.item
+     label="Avatars and Scene"
+     name="av_and_scene"
+     value="1" />
+  </combo_box>
+  <view_border
+   bevel_style="in"
+   height="0"
+   layout="topleft"
+   name="border1"
+   top_pad="20"
+   left="20"
+   width="540"/>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left="20"
+   top_pad="15"
+   name="simplify_dist_desc"
+   width="580">
+    Reducing detail shown on avatars that are far away will improve graphics speed.
+  </text>
+  <check_box
+   control_name="AutoTuneImpostorByDistEnabled"
+   height="19"
+   label="Simplify avatars beyond"
+   label_text.text_color="White"
+   layout="topleft"
+   follows="top|left"
+   name="AutoTuneImpostorByDistEnabled"
+   tool_tip="When enabled the viewer will adjust the MaxNonImpostors setting to limit fully rendered avatars to those within the defined radius."
+   top_pad="15"
+   width="190" />
+  <spinner
+   control_name="AutoTuneImpostorFarAwayDistance"
+   height="20"
+   layout="topleft"
+   follows="top|left"
+   name="ffa_autotune"
+   left_pad="20"
+   decimal_digits="2"
+   min_val="16"
+   max_val="256"
+   width="60" >
+  </spinner>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left_pad="10"
+   name="dist_meters"
+   width="70">
+    meters
+  </text>
+  <view_border
+   bevel_style="in"
+   height="0"
+   layout="topleft"
+   name="border2"
+   top_pad="20"
+   left="20"
+   width="540"/>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left="20"
+   top_pad="20"
+   name="dist_limits_desc"
+   width="580">
+    Choose the distance range that automatic settings will affect.
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="15"
+   name="min_dist_lbl"
+   width="120">
+    Minimum distance
+  </text>
+  <spinner
+   control_name="AutoTuneRenderFarClipMin"
+   height="20"
+   layout="topleft"
+   left_pad="15"
+   follows="top|left"
+   name="min_dd_autotune"
+   decimal_digits="2"
+   min_val="32"
+   max_val="256"
+   width="60">
+  </spinner>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="15"
+   left="20"
+   name="pref_dist_lbl"
+   width="120">
+    Maximum distance
+  </text>
+  <spinner
+   control_name="AutoTuneRenderFarClipTarget"
+   height="20"
+   layout="topleft"
+   follows="top|left"
+   name="pref_dd_autotune"
+   left_pad="15"
+   min_val="32"
+   max_val="256"
+   width="60">
+  </spinner>
+</panel>
-- 
cgit v1.2.3


From 81c287f877a48381bfa212ad00fe23aef260ef5f Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 22 Sep 2022 20:34:29 +0300
Subject: SL-18202 WIP merging autotune contribution and updating UI #2

---
 indra/newview/app_settings/settings.xml            |  11 ++
 indra/newview/llfloaterperformance.cpp             | 146 ++++++++++++---------
 indra/newview/llfloaterperformance.h               |   5 +-
 indra/newview/llperfstats.cpp                      |  20 +--
 indra/newview/llperfstats.h                        |   2 +-
 indra/newview/pipeline.cpp                         |  10 +-
 .../default/xui/en/panel_performance_nearby.xml    |  24 ++--
 7 files changed, 125 insertions(+), 93 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d92632c0a2..b1b971da14 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16820,6 +16820,17 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
+  <key>ShowTunedART</key>
+  <map>
+    <key>Comment</key>
+    <string>Show the current render time not the pre-tuning render time in the avatar display.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
   <key>RenderAvatarMaxART</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 257c0b2b37..afa46db1e3 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -38,6 +38,7 @@
 #include "llfloaterreg.h"
 #include "llnamelistctrl.h"
 #include "llnotificationsutil.h"
+#include "llperfstats.h"
 #include "llradiogroup.h"
 #include "llsliderctrl.h"
 #include "lltextbox.h"
@@ -54,6 +55,11 @@ const S32 BAR_LEFT_PAD = 2;
 const S32 BAR_RIGHT_PAD = 5;
 const S32 BAR_BOTTOM_PAD = 9;
 
+constexpr auto AvType       {LLPerfStats::ObjType_t::OT_AVATAR};
+constexpr auto AttType      {LLPerfStats::ObjType_t::OT_ATTACHMENT};
+constexpr auto HudType      {LLPerfStats::ObjType_t::OT_HUD};
+constexpr auto SceneType    {LLPerfStats::ObjType_t::OT_GENERAL};
+
 class LLExceptionsContextMenu : public LLListContextMenu
 {
 public:
@@ -87,7 +93,7 @@ LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
 
 LLFloaterPerformance::~LLFloaterPerformance()
 {
-    mComplexityChangedSignal.disconnect();
+    mMaxARTChangedSignal.disconnect();
     delete mContextMenu;
     delete mUpdateTimer;
 }
@@ -135,11 +141,15 @@ BOOL LLFloaterPerformance::postBuild()
     mNearbyList = mNearbyPanel->getChild<LLNameListCtrl>("nearby_list");
     mNearbyList->setRightMouseDownCallback(boost::bind(&LLFloaterPerformance::onAvatarListRightClick, this, _1, _2, _3));
 
-    updateComplexityText();
-    mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this));
-    mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxComplexity, this));
+    mMaxARTChangedSignal = gSavedSettings.getControl("RenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
+    mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
 
-    LLAvatarComplexityControls::setIndirectMaxArc();
+    // store the current setting as the users desired reflection detail and DD
+    gSavedSettings.setS32("UserTargetReflections", LLPipeline::RenderReflectionDetail);
+    if(!LLPerfStats::tunables.userAutoTuneEnabled)
+    {
+        gSavedSettings.setF32("AutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip);
+    }
 
     return TRUE;
 }
@@ -224,16 +234,13 @@ void LLFloaterPerformance::populateHUDList()
     hud_complexity_list_t::iterator iter = complexity_list.begin();
     hud_complexity_list_t::iterator end = complexity_list.end();
 
-    U32 max_complexity = 0;
-    for (; iter != end; ++iter)
-    {
-        max_complexity = llmax(max_complexity, (*iter).objectsCost);
-    }
-   
+    auto huds_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(HudType, LLPerfStats::StatType_t::RENDER_GEOMETRY);
     for (iter = complexity_list.begin(); iter != end; ++iter)
     {
-        LLHUDComplexity hud_object_complexity = *iter;        
-        S32 obj_cost_short = llmax((S32)hud_object_complexity.objectsCost / 1000, 1);
+        LLHUDComplexity hud_object_complexity = *iter;
+
+        auto hud_render_time_raw = LLPerfStats::StatsRecorder::get(HudType, hud_object_complexity.objectId, LLPerfStats::StatType_t::RENDER_GEOMETRY);
+
         LLSD item;
         item["special_id"] = hud_object_complexity.objectId;
         item["target"] = LLNameListCtrl::SPECIAL;
@@ -241,14 +248,14 @@ void LLFloaterPerformance::populateHUDList()
         row[0]["column"] = "complex_visual";
         row[0]["type"] = "bar";
         LLSD& value = row[0]["value"];
-        value["ratio"] = (F32)obj_cost_short / max_complexity * 1000;
+        value["ratio"] = (F32)hud_render_time_raw / huds_max_render_time_raw;
         value["bottom"] = BAR_BOTTOM_PAD;
         value["left_pad"] = BAR_LEFT_PAD;
         value["right_pad"] = BAR_RIGHT_PAD;
 
         row[1]["column"] = "complex_value";
         row[1]["type"] = "text";
-        row[1]["value"] = std::to_string(obj_cost_short);
+        row[1]["value"] = llformat( "%.f",LLPerfStats::raw_to_us(hud_render_time_raw) );
         row[1]["font"]["name"] = "SANSSERIF";
  
         row[2]["column"] = "name";
@@ -283,45 +290,46 @@ void LLFloaterPerformance::populateObjectList()
     object_complexity_list_t::iterator iter = complexity_list.begin();
     object_complexity_list_t::iterator end = complexity_list.end();
 
-    U32 max_complexity = 0;
-    for (; iter != end; ++iter)
+    // for consistency we lock the buffer while we build the list. In theory this is uncontended as the buffer should only toggle on end of frame
     {
-        max_complexity = llmax(max_complexity, (*iter).objectCost);
-    }
+        std::lock_guard<std::mutex> guard{ LLPerfStats::bufferToggleLock };
+        auto att_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(AttType, LLPerfStats::StatType_t::RENDER_COMBINED);
 
-    for (iter = complexity_list.begin(); iter != end; ++iter)
-    {
-        LLObjectComplexity object_complexity = *iter;        
-        S32 obj_cost_short = llmax((S32)object_complexity.objectCost / 1000, 1);
-        LLSD item;
-        item["special_id"] = object_complexity.objectId;
-        item["target"] = LLNameListCtrl::SPECIAL;
-        LLSD& row = item["columns"];
-        row[0]["column"] = "complex_visual";
-        row[0]["type"] = "bar";
-        LLSD& value = row[0]["value"];
-        value["ratio"] = (F32)obj_cost_short / max_complexity * 1000;
-        value["bottom"] = BAR_BOTTOM_PAD;
-        value["left_pad"] = BAR_LEFT_PAD;
-        value["right_pad"] = BAR_RIGHT_PAD;
+        for (iter = complexity_list.begin(); iter != end; ++iter)
+        {
+            LLObjectComplexity object_complexity = *iter;
 
-        row[1]["column"] = "complex_value";
-        row[1]["type"] = "text";
-        row[1]["value"] = std::to_string(obj_cost_short);
-        row[1]["font"]["name"] = "SANSSERIF";
+            auto attach_render_time_raw = LLPerfStats::StatsRecorder::get(AttType, object_complexity.objectId, LLPerfStats::StatType_t::RENDER_COMBINED);
+            LLSD item;
+            item["special_id"] = object_complexity.objectId;
+            item["target"] = LLNameListCtrl::SPECIAL;
+            LLSD& row = item["columns"];
+            row[0]["column"] = "complex_visual";
+            row[0]["type"] = "bar";
+            LLSD& value = row[0]["value"];
+            value["ratio"] = ((F32)attach_render_time_raw) / att_max_render_time_raw;
+            value["bottom"] = BAR_BOTTOM_PAD;
+            value["left_pad"] = BAR_LEFT_PAD;
+            value["right_pad"] = BAR_RIGHT_PAD;
 
-        row[2]["column"] = "name";
-        row[2]["type"] = "text";
-        row[2]["value"] = object_complexity.objectName;
-        row[2]["font"]["name"] = "SANSSERIF";
+            row[1]["column"] = "complex_value";
+            row[1]["type"] = "text";
+            row[1]["value"] = llformat("%.f", LLPerfStats::raw_to_us(attach_render_time_raw));
+            row[1]["font"]["name"] = "SANSSERIF";
 
-        LLScrollListItem* obj = mObjectList->addElement(item);
-        if (obj)
-        {
-            LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
-            if (value_text)
+            row[2]["column"] = "name";
+            row[2]["type"] = "text";
+            row[2]["value"] = object_complexity.objectName;
+            row[2]["font"]["name"] = "SANSSERIF";
+
+            LLScrollListItem* obj = mObjectList->addElement(item);
+            if (obj)
             {
-                value_text->setAlignment(LLFontGL::HCENTER);
+                LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
+                if (value_text)
+                {
+                    value_text->setAlignment(LLFontGL::HCENTER);
+                }
             }
         }
     }
@@ -332,6 +340,7 @@ void LLFloaterPerformance::populateObjectList()
 
 void LLFloaterPerformance::populateNearbyList()
 {
+    static LLCachedControl<bool> showTunedART(gSavedSettings, "ShowTunedART");
     S32 prev_pos = mNearbyList->getScrollPos();
     LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem();
     mNearbyList->clearRows();
@@ -342,26 +351,44 @@ void LLFloaterPerformance::populateNearbyList()
     mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
 
     std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
+
+    LLPerfStats::bufferToggleLock.lock();
+    auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(AvType, LLPerfStats::StatType_t::RENDER_COMBINED);
+    LLPerfStats::bufferToggleLock.unlock();
+
     while (char_iter != valid_nearby_avs.end())
     {
         LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
         if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))
         {
-            S32 complexity_short = llmax((S32)avatar->getVisualComplexity() / 1000, 1);;
+            LLPerfStats::bufferToggleLock.lock();
+            auto render_av_raw  = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_COMBINED);
+            LLPerfStats::bufferToggleLock.unlock();
+
+            auto is_slow = avatar->isTooSlowWithShadows();
             LLSD item;
             item["id"] = avatar->getID();
             LLSD& row = item["columns"];
             row[0]["column"] = "complex_visual";
             row[0]["type"] = "bar";
             LLSD& value = row[0]["value"];
-            value["ratio"] = (F32)complexity_short / mNearbyMaxComplexity * 1000;
+            // The ratio used in the bar is the current cost, as soon as we take action this changes so we keep the 
+            // pre-tune value for the numerical column and sorting.
+            value["ratio"] = (double)render_av_raw / av_render_max_raw;
             value["bottom"] = BAR_BOTTOM_PAD;
             value["left_pad"] = BAR_LEFT_PAD;
             value["right_pad"] = BAR_RIGHT_PAD;
 
             row[1]["column"] = "complex_value";
             row[1]["type"] = "text";
-            row[1]["value"] = std::to_string(complexity_short);
+            if (is_slow && !showTunedART)
+            {
+                row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( avatar->getLastART() ) );
+            }
+            else
+            {
+                row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( render_av_raw ) );
+            }
             row[1]["font"]["name"] = "SANSSERIF";
 
             row[2]["column"] = "name";
@@ -387,7 +414,7 @@ void LLFloaterPerformance::populateNearbyList()
                     else
                     {
                         std::string color = "white";
-                        if (LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance())
+                        if (is_slow || LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance())
                         {
                             color = "LabelDisabledColor";
                             LLScrollListBar* bar = dynamic_cast<LLScrollListBar*>(av_item->getColumn(0));
@@ -462,18 +489,11 @@ void LLFloaterPerformance::onClickExceptions()
     LLFloaterReg::showInstance("avatar_render_settings");
 }
 
-void LLFloaterPerformance::updateMaxComplexity()
-{
-    LLAvatarComplexityControls::updateMax(
-        mNearbyPanel->getChild<LLSliderCtrl>("IndirectMaxComplexity"),
-        mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText"), 
-        true);
-}
-
-void LLFloaterPerformance::updateComplexityText()
+void LLFloaterPerformance::updateMaxRenderTime()
 {
-    LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"),
-        mNearbyPanel->getChild<LLTextBox>("IndirectMaxComplexityText", true), 
+    LLAvatarComplexityControls::updateMaxRenderTime(
+        mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART"),
+        mNearbyPanel->getChild<LLTextBox>("RenderAvatarMaxARTText"), 
         true);
 }
 
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 01b65365da..a79da7460b 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -66,8 +66,7 @@ private:
     void onClickShadows();
     void onClickAdvancedLighting();
 
-    void updateMaxComplexity();
-    void updateComplexityText();
+    void updateMaxRenderTime();
 
     static void changeQualityLevel(const std::string& notif);
 
@@ -87,7 +86,7 @@ private:
 
     S32 mNearbyMaxComplexity;
 
-    boost::signals2::connection	mComplexityChangedSignal;
+    boost::signals2::connection	mMaxARTChangedSignal;
 };
 
 #endif // LL_LLFLOATERPERFORMANCE_H
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 16d0df0245..1a0e5842e2 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -76,15 +76,15 @@ namespace LLPerfStats
     void Tunables::updateRenderCostLimitFromSettings()
     {
         assert_main_thread();
-	    const auto newval = gSavedSettings.getF32("RenderAvatarMaxART");
-	    if(newval < log10(LLPerfStats::ART_UNLIMITED_NANOS/1000))
-	    {
-    		LLPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000;
-    	}
-    	else
-    	{
-		    LLPerfStats::renderAvatarMaxART_ns = 0;
-	    };        
+        const auto newval = gSavedSettings.getF32("RenderAvatarMaxART");
+        if(newval < log10(LLPerfStats::ART_UNLIMITED_NANOS/1000))
+        {
+            LLPerfStats::renderAvatarMaxART_ns = pow(10,newval)*1000;
+        }
+        else
+        {
+            LLPerfStats::renderAvatarMaxART_ns = 0;
+        }
     }
 
     // static 
@@ -466,4 +466,4 @@ namespace LLPerfStats
             }
         }
    }
-}
\ No newline at end of file
+}
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index 1e867f5ef1..961594f18c 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -451,4 +451,4 @@ static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPt
     return;
 };
 
-#endif
\ No newline at end of file
+#endif
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7044d27430..2a059e5db4 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -10853,10 +10853,12 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
                               << " is " << ( too_complex ? "" : "not ") << "too complex"
                               << LL_ENDL;
 
-	pushRenderTypeMask();
-	
-	if (visually_muted || too_complex)
-	{
+    bool too_slow = avatar->isTooSlowWithoutShadows(); // only if we really have to do we imposter.
+
+    pushRenderTypeMask();
+
+    if ( !too_slow && ( visually_muted || too_complex ) )
+    {
         // only show jelly doll geometry
 		andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
 							LLPipeline::RENDER_TYPE_CONTROL_AV,
diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
index e1aef13717..e80bf592e4 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
@@ -57,22 +57,22 @@
     Hide the most complex avatars to boost speed.
   </text>
   <slider
-    control_name="IndirectMaxComplexity"
-    tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
+    control_name="RenderAvatarMaxART"
+    tool_tip="Controls when a visually complex avatar is considered to be taking too long to render (unit: microseconds)"
     follows="left|top"
     height="16"
-    initial_value="101"
-    increment="1"
-    label="Maximum complexity (K)"
+    initial_value="4.7"
+    increment="0.01"
+    label="Maximum render time (μs)"
     text_color="White"
     label_width="165"
     layout="topleft"
-    min_val="1"
-    max_val="101"
-    name="IndirectMaxComplexity"
+    min_val="2"
+    max_val="4.7"
+    name="RenderAvatarMaxART"
     show_text="false"
     top_pad="10"
-    width="300">
+    width="490">
   </slider>
   <text
     type="string"
@@ -81,11 +81,11 @@
     height="16"
     layout="topleft"
     top_delta="0"
-    left_delta="304"
+    left_pad="5"
     text_color="White"
-    name="IndirectMaxComplexityText"
+    name="RenderAvatarMaxARTText"
     width="65">
-    0
+    no limit
   </text>
   <name_list
     column_padding="0"
-- 
cgit v1.2.3


From 3098d315a34f6d9e1bdf0f0de4e695a89626282f Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 23 Sep 2022 16:49:47 +0300
Subject: SL-18202 remove old autofps

---
 indra/newview/app_settings/settings.xml            |  57 --------
 indra/newview/llagent.cpp                          |   2 -
 indra/newview/llfloaterperformance.cpp             |  16 +--
 indra/newview/llfloaterpreference.cpp              |  18 ---
 indra/newview/llfloaterpreference.h                |   2 -
 .../llfloaterpreferencesgraphicsadvanced.cpp       |   5 -
 indra/newview/llstartup.cpp                        |   4 -
 indra/newview/llviewerdisplay.cpp                  |   2 -
 indra/newview/pipeline.cpp                         | 143 +--------------------
 indra/newview/pipeline.h                           |   7 -
 .../en/floater_preferences_graphics_advanced.xml   |   4 -
 .../xui/en/panel_performance_preferences.xml       |  37 +-----
 .../default/xui/en/panel_preferences_graphics1.xml |  34 +----
 13 files changed, 10 insertions(+), 321 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b1b971da14..bf72492a28 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16719,63 +16719,6 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>AutoFPS</key>
-    <map>
-      <key>Comment</key>
-      <string>
-        Allow dynamic adjustment of graphics preferences
-      </string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
-  <key>AutoAdjustmentTimeout</key>
-  <map>
-    <key>Comment</key>
-    <string>Time before next iteration of automatic adjustments</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>5</real>
-  </map>
-  <key>InitialAdjustmentTimeout</key>
-  <map>
-    <key>Comment</key>
-    <string>Time before first iteration of automatic adjustments after login to the world, teleporting, maximizing Viewer etc.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>10</real>
-  </map>
-  <key>AutoFPSLowerBoundary</key>
-  <map>
-    <key>Comment</key>
-    <string>FPS lower boundary when automatic adjustments are occured to reduce graphics quality to increase FPS</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>S32</string>
-    <key>Value</key>
-    <real>30</real>
-  </map>
-  <key>AutoFPSUpperBoundary</key>
-  <map>
-    <key>Comment</key>
-    <string>FPS upper boundary when automatic adjustments are occured to increase graphics quality</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>S32</string>
-    <key>Value</key>
-    <real>50</real>
-  </map>
   <key>TargetFPS</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 78c726043e..8a6186123e 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -4097,7 +4097,6 @@ void LLAgent::handleTeleportFinished()
         }
     }
 
-    gPipeline.setAdjustmentTimerExpiry(gSavedSettings.getF32("InitialAdjustmentTimeout"));
 }
 
 void LLAgent::handleTeleportFailed()
@@ -4130,7 +4129,6 @@ void LLAgent::handleTeleportFailed()
 
     mTPNeedsNeabyChatSeparator = false;
 
-    gPipeline.setAdjustmentTimerExpiry(gSavedSettings.getF32("InitialAdjustmentTimeout"));
 }
 
 /*static*/
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index afa46db1e3..da1670c15e 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -58,7 +58,6 @@ const S32 BAR_BOTTOM_PAD = 9;
 constexpr auto AvType       {LLPerfStats::ObjType_t::OT_AVATAR};
 constexpr auto AttType      {LLPerfStats::ObjType_t::OT_ATTACHMENT};
 constexpr auto HudType      {LLPerfStats::ObjType_t::OT_HUD};
-constexpr auto SceneType    {LLPerfStats::ObjType_t::OT_GENERAL};
 
 class LLExceptionsContextMenu : public LLListContextMenu
 {
@@ -87,8 +86,6 @@ LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
     mNearbyMaxComplexity(0)
 {
     mContextMenu = new LLExceptionsContextMenu(this);
-
-    mCommitCallbackRegistrar.add("Pref.AutoAdjustWarning", boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
 }
 
 LLFloaterPerformance::~LLFloaterPerformance()
@@ -133,7 +130,6 @@ BOOL LLFloaterPerformance::postBuild()
     mSettingsPanel->getChild<LLRadioGroup>("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2));
     mSettingsPanel->getChild<LLCheckBoxCtrl>("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this));
     mSettingsPanel->getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this));
-    mSettingsPanel->getChild<LLComboBox>("Reflections")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
 
     mNearbyPanel->getChild<LLButton>("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this));
     mNearbyPanel->getChild<LLCheckBoxCtrl>("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this));
@@ -623,16 +619,10 @@ void LLFloaterPerformance::onClickAdvancedLighting()
 
 void LLFloaterPerformance::onClickShadows()
 {
-    if (gSavedSettings.getBOOL("AutoFPS"))
+    if (!is_ALM_available() || !gSavedSettings.getBOOL("RenderDeferred"))
     {
-        LLFloaterPreference::showAutoAdjustWarning();
-    }
-    else
-    {
-        if (!is_ALM_available() || !gSavedSettings.getBOOL("RenderDeferred"))
-        {
-            changeQualityLevel("ShadowsConfirm");
-        }
+        changeQualityLevel("ShadowsConfirm");
     }
+
 }
 // EOF
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 77bf03852f..e9d5a8e02c 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -305,7 +305,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.RememberedUsernames",    boost::bind(&LLFloaterPreference::onClickRememberedUsernames, this));
 	mCommitCallbackRegistrar.add("Pref.SpellChecker",           boost::bind(&LLFloaterPreference::onClickSpellChecker, this));
 	mCommitCallbackRegistrar.add("Pref.Advanced",				boost::bind(&LLFloaterPreference::onClickAdvanced, this));
-    mCommitCallbackRegistrar.add("Pref.AutoAdjustWarning",				boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
 
 	sSkin = gSavedSettings.getString("SkinCurrent");
 
@@ -1800,23 +1799,6 @@ void LLFloaterPreference::updateSearchableItems()
     mSearchDataDirty = true;
 }
 
-void LLFloaterPreference::showAutoAdjustWarning()
-{
-    static LLCachedControl<bool> use_auto_adjust(gSavedSettings,"AutoFPS");
-    if (use_auto_adjust)
-    {
-        LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(),
-            [](const LLSD&notif, const LLSD&resp)
-        {
-            S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
-            if (opt == 0)
-            {
-                gSavedSettings.setBOOL("AutoFPS", FALSE);
-            }
-        });
-    }
-}
-
 void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
 {
 	LLUIColorTable::instance().setColor(param.asString(), LLColor4(ctrl->getValue()));
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index de4e3cd886..94aac56506 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -109,8 +109,6 @@ public:
 	void updateClickActionViews();
     void updateSearchableItems();
 
-    static void showAutoAdjustWarning();
-
     void		onBtnOK(const LLSD& userdata);
     void		onBtnCancel(const LLSD& userdata);
 
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index ba2fd6eef2..4cfc91f88e 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -49,8 +49,6 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
     mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxNonImpostors", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors,this));
     mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",   boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity,this));
 
-    mCommitCallbackRegistrar.add("Pref.AutoAdjustWarning", boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
-
     mCommitCallbackRegistrar.add("Pref.Cancel", boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnCancel, this, _2));
     mCommitCallbackRegistrar.add("Pref.OK",     boost::bind(&LLFloaterPreferenceGraphicsAdvanced::onBtnOK, this, _2));
 
@@ -81,9 +79,6 @@ BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
 
     mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this));
 
-    getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
-    getChild<LLComboBox>("Reflections")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning));
-
     return TRUE;
 }
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 9cbd56ee7f..00c2fca7df 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2254,10 +2254,6 @@ bool idle_startup()
 
 	if (STATE_CLEANUP == LLStartUp::getStartupState())
 	{
-        if (gAgent.isFirstLogin())
-        {
-            gSavedSettings.setBOOL("AutoFPS", TRUE);
-        }
         set_startup_status(1.0, "", "");
 		display_startup();
 
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index fa026c2888..a1773ae8d5 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1024,8 +1024,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 		gPipeline.clearReferences();
 
 		gPipeline.rebuildGroups();
-
-        gPipeline.autoAdjustSettings();
 	}
 
 	LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2a059e5db4..3110a1cbe5 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -409,8 +409,7 @@ LLPipeline::LLPipeline() :
 	mLightMovingMask(0),
 	mLightingDetail(0),
 	mScreenWidth(0),
-	mScreenHeight(0),
-    mUpdateTimer(new LLTimer())
+	mScreenHeight(0)
 {
 	mNoiseMap = 0;
 	mTrueNoiseMap = 0;
@@ -615,12 +614,10 @@ void LLPipeline::init()
 	connectRefreshCachedSettingsSafe("CameraDoFResScale");
 	connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit");
 	gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
-    gSavedSettings.getControl("AutoFPS")->getCommitSignal()->connect(boost::bind(&LLPipeline::onToggleAutoFPS));
 }
 
 LLPipeline::~LLPipeline()
 {
-    delete mUpdateTimer;
 }
 
 void LLPipeline::cleanup()
@@ -11522,141 +11519,3 @@ void LLPipeline::handleShadowDetailChanged()
     }
 }
 
-const F32 MIN_DRAW_DISTANCE = 64;
-const F32 MAX_DRAW_DISTANCE = 256;
-
-void update_far_clip(F32 fps_dif)
-{
-    F32 DIST_PER_FRAME_DIF = 16;
-
-    F32 new_far_clip = llclamp(LLPipeline::RenderFarClip - llmin(fps_dif * DIST_PER_FRAME_DIF, (F32)128), MIN_DRAW_DISTANCE, MAX_DRAW_DISTANCE);
-    gSavedSettings.setF32("RenderFarClip", new_far_clip);
-}
-
-void update_max_non_impostors(F32 fps_dif, S32 max_avatars)
-{
-    const F32 IMPOSTORS_PER_FRAME_DIF = 0.5;
-
-    U32 new_non_imp = (U32)llclamp((S32)(LLVOAvatar::sMaxNonImpostors - llmin((S32)(fps_dif / IMPOSTORS_PER_FRAME_DIF), 10)), 1, max_avatars);
-    gSavedSettings.setU32("RenderAvatarMaxNonImpostors", new_non_imp);
-}
-
-void LLPipeline::autoAdjustSettings()
-{
-    static LLCachedControl<bool> use_auto_adjustment(gSavedSettings,"AutoFPS");
-    if (!use_auto_adjustment)
-    {
-        return;
-    }
-    
-    if (LLStartUp::getStartupState() < STATE_STARTED || LLApp::isExiting())
-    {
-        return;
-    }
-
-    static LLCachedControl<F32> adjustment_timeout(gSavedSettings, "AutoAdjustmentTimeout");
-    static LLCachedControl<F32> initial_adjustment_timeout(gSavedSettings, "InitialAdjustmentTimeout");
- 
-    static LLCachedControl<S32> fps_lower_boundary(gSavedSettings, "AutoFPSLowerBoundary");
-    static LLCachedControl<S32> fps_upper_boundary(gSavedSettings, "AutoFPSUpperBoundary");
-
-    if (gViewerWindow && gViewerWindow->getWindow()->getVisible()
-        && gFocusMgr.getAppHasFocus() && !gTeleportDisplay)
-    {
-        static bool is_init = false;
-        if (!is_init)
-        {
-            //wait for FPS to stabilize after login in-world
-            mUpdateTimer->setTimerExpirySec((F32)initial_adjustment_timeout);
-            is_init = true;
-        }
-        if (mUpdateTimer->hasExpired())
-        {
-            mUpdateTimer->setTimerExpirySec((F32)adjustment_timeout);
-
-            const S32 FPS_STAT_PERIODS = 50;
-            S32 fps = (S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, FPS_STAT_PERIODS));
-            if (fps < fps_lower_boundary)
-            {
-                S32 fps_dif = fps_lower_boundary - fps;
-                
-                if (sWaterReflections && RenderReflectionDetail > WATER_REFLECT_NONE_WATER_OPAQUE)
-                {
-                    S32 reflection_detail = llclamp(RenderReflectionDetail - 1, WATER_REFLECT_NONE_WATER_OPAQUE, WATER_REFLECT_MINIMAL);
-                    gSavedSettings.setS32("RenderReflectionDetail", reflection_detail);
-                    return;
-                }
-                
-                if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0 && RenderShadowSplits > 0)
-                {
-                    S32 shadow_splits = llclamp(RenderShadowSplits - 1, 0, 3);
-                    gSavedSettings.setS32("RenderShadowSplits", shadow_splits);
-                    return;
-                }
-                
-                if (RenderFarClip > MIN_DRAW_DISTANCE)
-                {
-                    update_far_clip(fps_dif);
-                }
-
-                std::vector<LLCharacter*> valid_nearby_avs;
-                LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
-
-                if (valid_nearby_avs.size() > 1 && LLVOAvatar::sMaxNonImpostors > 1) 
-                {
-                    update_max_non_impostors(fps_dif, valid_nearby_avs.size());
-                }
-            }
-            else if (fps > fps_upper_boundary)
-            {
-                S32 fps_dif = fps_upper_boundary - fps;
-
-                std::vector<LLCharacter*> valid_nearby_avs;
-                LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
-                if (valid_nearby_avs.size() > 1 && (LLVOAvatar::sMaxNonImpostors < valid_nearby_avs.size()))
-                {
-                    update_max_non_impostors(fps_dif, valid_nearby_avs.size());
-                    return;
-                }
-                
-                if (RenderFarClip < MAX_DRAW_DISTANCE)
-                {
-                    update_far_clip(fps_dif);
-                }
-
-                if (LLPipeline::sRenderDeferred && RenderShadowDetail > 0 && RenderShadowSplits < 3)
-                {
-                    S32 shadow_splits = llclamp(RenderShadowSplits + 1, 0, 3);
-                    gSavedSettings.setS32("RenderShadowSplits", shadow_splits);
-                    return;
-                }
-
-                if (sWaterReflections && RenderReflectionDetail < WATER_REFLECT_MINIMAL)
-                {
-                    S32 reflection_detail = llclamp(RenderReflectionDetail + 1, WATER_REFLECT_NONE_WATER_OPAQUE, WATER_REFLECT_MINIMAL);
-                    gSavedSettings.setS32("RenderReflectionDetail", reflection_detail);
-                }
-            }
-        }
-    }
-    else
-    {
-        //wait for FPS to stabilize if the window was minimized or not focused before
-        mUpdateTimer->setTimerExpirySec((F32)initial_adjustment_timeout);
-    }
-}
-
-void LLPipeline::setAdjustmentTimerExpiry(F32 expiration)
-{
-    mUpdateTimer->setTimerExpirySec(expiration);
-}
-
-void LLPipeline::onToggleAutoFPS()
-{
-    if (!gSavedSettings.getBOOL("AutoFPS"))
-    {
-        //reset the number of shadow map splits rendered, when disabling auto-fps
-        //probably should be removed, if we'll have actual UI control for this setting
-        gSavedSettings.setS32("RenderShadowSplits", 3);
-    }
-}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index bdd498abff..584d32a767 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -418,8 +418,6 @@ public:
 	static void updateRenderDeferred();
 	static void refreshCachedSettings();
 
-    static void onToggleAutoFPS();
-
 	void addDebugBlip(const LLVector3& position, const LLColor4& color);
 
 	void hidePermanentObjects( std::vector<U32>& restoreList );
@@ -429,9 +427,6 @@ public:
 	void restoreHiddenObject( const LLUUID& id );
     void handleShadowDetailChanged();
 
-    void autoAdjustSettings();
-    void setAdjustmentTimerExpiry(F32 expiration);
-
 private:
 	void unloadShaders();
 	void addToQuickLookup( LLDrawPool* new_poolp );
@@ -724,8 +719,6 @@ protected:
 	U64						mOldRenderDebugMask;
 	std::stack<U32>			mRenderDebugFeatureStack;
 
-    LLTimer* mUpdateTimer;
-
 	/////////////////////////////////////////////
 	//
 	//
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 154c8b7909..9da6ec093b 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
@@ -40,8 +40,6 @@
     name="DrawDistance"
     top_delta="16"
     width="330">
-    <slider.mouse_down_callback
-      function="Pref.AutoAdjustWarning" />
     </slider>
   <text
     type="string"
@@ -185,8 +183,6 @@
     <slider.commit_callback
       function="Pref.UpdateIndirectMaxNonImpostors"
       parameter="IndirectNonImpostorsText" />
-    <slider.mouse_down_callback
-      function="Pref.AutoAdjustWarning" />
   </slider>
   <text
     type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index 1eee799986..ee8105eac9 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -61,39 +61,6 @@
    top_pad="8"
    left="20"
    width="540"/>
-  <text
-   follows="left|top"
-   font="SansSerifSmall"
-   text_color="White"
-   height="18"
-   layout="topleft"
-   top_pad="20"
-   left="20"
-   name="auto_lbl"
-   width="105">
-    Automatic settings
-  </text>
-  <check_box
-   control_name="AutoFPS"
-   height="16"
-   initial_value="true"
-   label="Allow system to choose settings for best experience"
-   label_text.text_color="White"
-   label_text.v_pad="-1"
-   label_text.h_pad="3"
-   layout="topleft"
-   left_pad="30"
-   name="AutoFPS"
-   width="256">
-  </check_box>
-  <view_border
-   bevel_style="in"
-   height="0"
-   layout="topleft"
-   name="border1"
-   left="20"
-   top_pad="12"
-   width="540"/>
   <text
    follows="left|top"
    font="SansSerifSmall"
@@ -240,8 +207,6 @@
     name="draw_distance"
     left_pad="5"
     width="250">
-    <slider.mouse_down_callback
-      function="Pref.AutoAdjustWarning" />
   </slider>
   <text
     type="string"
@@ -520,7 +485,7 @@
    font="SansSerifSmall"
    height="18"
    layout="topleft"
-   top="130"
+   top="80"
    left="213"
    name="1_lbl"
    width="7">
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 93cb3ea9c8..5aff7a5127 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -30,28 +30,7 @@
     width="120">
       (None)
   </text>
-  <view_border
-    bevel_style="in"
-    height="0"
-    layout="topleft"
-    name="border1"
-    left="12"
-    top_pad="12"
-    width="477"/>
-  <check_box
-    control_name="AutoFPS"
-    height="16"
-    initial_value="true"
-    label="Allow system to choose settings for best experience"
-    label_text.text_color="White"
-    label_text.v_pad="-1"
-    label_text.h_pad="5"
-    layout="topleft"
-    left="10"
-    name="AutoFPS"
-    top_delta="15"
-    width="256">
-  </check_box>
+
   <text
     type="string"
     length="1"
@@ -60,7 +39,7 @@
     layout="topleft"
     left="10"
     name="QualitySpeed"
-    top_delta="30" 
+    top_delta="35" 
     width="400">
       Quality &amp; speed:
   </text>
@@ -238,10 +217,7 @@
     max_val="512"
     name="DrawDistance"
     top_delta="40"
-    width="330">
-    <slider.mouse_down_callback
-      function="Pref.AutoAdjustWarning" />
-  </slider>
+    width="330" />
   <text
     type="string"
     length="1"
@@ -282,7 +258,7 @@
     <check_box.commit_callback
       function="Pref.RenderOptionUpdate" />
   </check_box>
-
+  
   <slider
     control_name="IndirectMaxComplexity"
     tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
@@ -298,7 +274,7 @@
     max_val="101"
     name="IndirectMaxComplexity"
     show_text="false"
-    top_delta="34"
+    top_delta="60"
     width="300">
     <slider.commit_callback
       function="Pref.UpdateIndirectMaxComplexity"
-- 
cgit v1.2.3


From dcd74c98dc5ab1373f1e7f692fd30dee92472acf Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 27 Sep 2022 19:35:49 +0300
Subject: SL-18202 impostor too slow avatars and add autotune settings button
 to Preference

---
 indra/newview/llfloaterperformance.cpp                    |  5 +++++
 indra/newview/llfloaterperformance.h                      |  1 +
 indra/newview/llfloaterpreference.cpp                     | 15 ++++++++++++++-
 indra/newview/llfloaterpreference.h                       |  1 +
 indra/newview/llviewerpartsim.cpp                         |  2 +-
 indra/newview/llvoavatar.cpp                              |  8 ++++----
 indra/newview/pipeline.cpp                                |  8 ++++----
 .../skins/default/xui/en/panel_preferences_graphics1.xml  | 14 +++++++++++++-
 8 files changed, 43 insertions(+), 11 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index da1670c15e..e79e9d19b1 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -170,6 +170,11 @@ void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel)
     }
 }
 
+void LLFloaterPerformance::showAutoadjustmentsPanel()
+{
+    showSelectedPanel(mAutoadjustmentsPanel);
+}
+
 void LLFloaterPerformance::draw()
 {
     if (mUpdateTimer->hasExpired())
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index a79da7460b..09bcd18bb5 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -44,6 +44,7 @@ public:
     void showSelectedPanel(LLPanel* selected_panel);
     void showMainPanel();
     void hidePanels();
+    void showAutoadjustmentsPanel();
 
     void detachItem(const LLUUID& item_id);
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index e9d5a8e02c..179f70a4a7 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -51,6 +51,7 @@
 #include "llfloaterabout.h"
 #include "llfavoritesbar.h"
 #include "llfloaterpreferencesgraphicsadvanced.h"
+#include "llfloaterperformance.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfloaterimsession.h"
 #include "llkeyboard.h"
@@ -287,6 +288,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.ClickDisablePopup",		boost::bind(&LLFloaterPreference::onClickDisablePopup, this));	
 	mCommitCallbackRegistrar.add("Pref.LogPath",				boost::bind(&LLFloaterPreference::onClickLogPath, this));
 	mCommitCallbackRegistrar.add("Pref.RenderExceptions",       boost::bind(&LLFloaterPreference::onClickRenderExceptions, this));
+	mCommitCallbackRegistrar.add("Pref.AutoAdjustments",         boost::bind(&LLFloaterPreference::onClickAutoAdjustments, this));
 	mCommitCallbackRegistrar.add("Pref.HardwareDefaults",		boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
 	mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable",	boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
 	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",	boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
@@ -726,13 +728,15 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	LLButton* save_btn = findChild<LLButton>("PrefSaveButton");
 	LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
 	LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton");
+    LLButton* auto_adjustments_btn = findChild<LLButton>("AutoAdjustmentsButton");
 
-	if (load_btn && save_btn && delete_btn && exceptions_btn)
+	if (load_btn && save_btn && delete_btn && exceptions_btn && auto_adjustments_btn)
 	{
 		load_btn->setEnabled(started);
 		save_btn->setEnabled(started);
 		delete_btn->setEnabled(started);
 		exceptions_btn->setEnabled(started);
+        auto_adjustments_btn->setEnabled(started);
 	}
 
     collectSearchableItems();
@@ -1655,6 +1659,15 @@ void LLFloaterPreference::onClickRenderExceptions()
     LLFloaterReg::showInstance("avatar_render_settings");
 }
 
+void LLFloaterPreference::onClickAutoAdjustments()
+{
+    LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<LLFloaterPerformance>("performance");
+    if (performance_floater)
+    {
+        performance_floater->showAutoadjustmentsPanel();
+    }
+}
+
 void LLFloaterPreference::onClickAdvanced()
 {
 	LLFloaterReg::showInstance("prefs_graphics_advanced");
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 94aac56506..1079b41000 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -185,6 +185,7 @@ public:
 	void onClickAutoReplace();
 	void onClickSpellChecker();
 	void onClickRenderExceptions();
+	void onClickAutoAdjustments();
 	void onClickAdvanced();
 	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
 	void getUIColor(LLUICtrl* ctrl, const LLSD& param);
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index e5265f1dcd..a440f3232a 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -716,7 +716,7 @@ void LLViewerPartSim::updateSimulation()
 
 			if (upd && vobj && (vobj->getPCode() == LL_PCODE_VOLUME))
 			{
-				if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex())
+				if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex() && vobj->getAvatar()->isTooSlowWithShadows())
 				{
 					upd = FALSE;
 				}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 1a71780a88..976b69502f 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3136,7 +3136,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
 																 LLPartData::LL_PART_TARGET_POS_MASK );
 			
 			// do not generate particles for dummy or overly-complex avatars
-			if (!mIsDummy && !isTooComplex())
+			if (!mIsDummy && !isTooComplex() && !isTooSlowWithShadows())
 			{
 				setParticleSource(particle_parameters, getID());
 			}
@@ -3717,7 +3717,7 @@ bool LLVOAvatar::isVisuallyMuted()
         }
 		else 
 		{
-			muted = isTooComplex();
+			muted = isTooComplex() || isTooSlowWithShadows();
 		}
 	}
 
@@ -11174,7 +11174,7 @@ LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const
 		{	// Always want to see this AV as an impostor
 			result = AOA_JELLYDOLL;
 		}
-		else if (isTooComplex())
+		else if (isTooComplex() || isTooSlowWithShadows())
 		{
 			result = AOA_JELLYDOLL;
 		}
@@ -11201,7 +11201,7 @@ void LLVOAvatar::calcMutedAVColor()
         new_color = LLColor4::grey4;
         change_msg = " blocked: color is grey4";
     }
-    else if (!isTooComplex())
+    else if (!isTooComplex() && !isTooSlowWithShadows())
     {
         new_color = LLColor4::white;
         change_msg = " simple imposter ";
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 3110a1cbe5..ba5e35fd3e 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -132,7 +132,7 @@
 
 // NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
 // NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables.
-    const S32 WATER_REFLECT_NONE_WATER_OPAQUE       = -2;
+//  const S32 WATER_REFLECT_NONE_WATER_OPAQUE       = -2;
     const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT  = -1;
     const S32 WATER_REFLECT_MINIMAL                 =  0;
 //  const S32 WATER_REFLECT_TERRAIN                 =  1;
@@ -5993,7 +5993,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 			LLDrawable* drawable = light->drawable;
             const LLViewerObject *vobj = light->drawable->getVObj();
             if(vobj && vobj->getAvatar() 
-               && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList())
+               && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList() || vobj->getAvatar()->isTooSlowWithShadows())
                )
             {
                 drawable->clearState(LLDrawable::NEARBY_LIGHT);
@@ -6072,7 +6072,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 				continue;
 			}
             LLVOAvatar * av = light->getAvatar();
-            if (av && (av->isTooComplex() || av->isInMuteList()))
+            if (av && (av->isTooComplex() || av->isInMuteList() || av->isTooSlowWithShadows()))
             {
                 // avatars that are already in the list will be removed by removeMutedAVsLights
                 continue;
@@ -10850,7 +10850,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
                               << " is " << ( too_complex ? "" : "not ") << "too complex"
                               << LL_ENDL;
 
-    bool too_slow = avatar->isTooSlowWithoutShadows(); // only if we really have to do we imposter.
+    bool too_slow = avatar->isTooSlowWithShadows();
 
     pushRenderTypeMask();
 
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 5aff7a5127..ad02df3087 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -258,6 +258,18 @@
     <check_box.commit_callback
       function="Pref.RenderOptionUpdate" />
   </check_box>
+
+  <button
+  height="23"
+  label="Automatic adjustments settings"
+  layout="topleft"
+  left="30"
+  name="AutoAdjustmentsButton"
+  top_delta="30"
+  width="200">
+    <button.commit_callback
+      function="Pref.AutoAdjustments"/>
+  </button>
   
   <slider
     control_name="IndirectMaxComplexity"
@@ -274,7 +286,7 @@
     max_val="101"
     name="IndirectMaxComplexity"
     show_text="false"
-    top_delta="60"
+    top_delta="40"
     width="300">
     <slider.commit_callback
       function="Pref.UpdateIndirectMaxComplexity"
-- 
cgit v1.2.3


From 198420f9f61bc0f747102a2d5783327f13583be8 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 28 Sep 2022 14:16:16 +0300
Subject: SL-18248 Move frame breakdown stats to 'Scene loading statistics'
 floater

---
 indra/newview/llviewerstats.cpp                    | 91 ++++++++++++++++++++++
 .../default/xui/en/floater_scene_load_stats.xml    | 53 +++++++++++++
 2 files changed, 144 insertions(+)

(limited to 'indra/newview')

diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index a420de98f5..0045dcb547 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -58,6 +58,7 @@
 #include "llfeaturemanager.h"
 #include "llviewernetwork.h"
 #include "llmeshrepository.h" //for LLMeshRepository::sBytesReceived
+#include "llperfstats.h"
 #include "llsdserialize.h"
 #include "llsdutil.h"
 #include "llcorehttputil.h"
@@ -208,6 +209,13 @@ LLTrace::EventStatHandle<F64Seconds >	AVATAR_EDIT_TIME("avataredittime", "Second
 LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE("object_cache_hits");
 
 LLTrace::EventStatHandle<F64Seconds >	TEXTURE_FETCH_TIME("texture_fetch_time");
+
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  SCENERY_FRAME_PCT("scenery_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  AVATAR_FRAME_PCT("avatar_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  HUDS_FRAME_PCT("huds_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  UI_FRAME_PCT("ui_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  SWAP_FRAME_PCT("swap_frame_pct");
+LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >  IDLE_FRAME_PCT("idle_frame_pct");
 }
 
 LLViewerStats::LLViewerStats() 
@@ -414,6 +422,89 @@ void update_statistics()
 			texture_stats_timer.reset();
 		}
 	}
+
+    if (LLFloaterReg::instanceVisible("scene_load_stats"))
+    {
+        static const F32 perf_stats_freq = 1;
+        static LLFrameTimer perf_stats_timer;
+        if (perf_stats_timer.getElapsedTimeF32() >= perf_stats_freq)
+        {
+            LLStringUtil::format_map_t args;
+            LLPerfStats::bufferToggleLock.lock(); // prevent toggle for a moment
+
+            auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);
+            // cumulative avatar time (includes idle processing, attachments and base av)
+            auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(LLPerfStats::ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
+            // cumulative avatar render specific time (a bit arbitrary as the processing is too.)
+            // auto tot_av_idle_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_IDLE);
+            // auto tot_avatar_render_time_raw = tot_avatar_time_raw - tot_av_idle_time_raw;
+            // the time spent this frame on the "display()" call. Treated as "tot time rendering"
+            auto tot_render_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_DISPLAY);
+            // sleep time is basically forced sleep when window out of focus 
+            auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP);
+            // time spent on UI
+            auto tot_ui_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_UI);
+            // cumulative time spent rendering HUDS
+            auto tot_huds_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_HUDS);
+            // "idle" time. This is the time spent in the idle poll section of the main loop
+            auto tot_idle_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_IDLE);
+            // similar to sleep time, induced by FPS limit
+            //auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT);
+            // swap time is time spent in swap buffer
+            auto tot_swap_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SWAP);
+
+            LLPerfStats::bufferToggleLock.unlock();
+
+             auto tot_frame_time_ns = LLPerfStats::raw_to_ns(tot_frame_time_raw);
+            auto tot_avatar_time_ns = LLPerfStats::raw_to_ns(tot_avatar_time_raw);
+            auto tot_huds_time_ns = LLPerfStats::raw_to_ns(tot_huds_time_raw);
+            // UI time includes HUD time so dedut that before we calc percentages
+            auto tot_ui_time_ns = LLPerfStats::raw_to_ns(tot_ui_time_raw - tot_huds_time_raw);
+
+            // auto tot_sleep_time_ns          = LLPerfStats::raw_to_ns( tot_sleep_time_raw );
+            // auto tot_limit_time_ns          = LLPerfStats::raw_to_ns( tot_limit_time_raw );
+
+            // auto tot_render_time_ns         = LLPerfStats::raw_to_ns( tot_render_time_raw );
+            auto tot_idle_time_ns = LLPerfStats::raw_to_ns(tot_idle_time_raw);
+            auto tot_swap_time_ns = LLPerfStats::raw_to_ns(tot_swap_time_raw);
+            auto tot_scene_time_ns = LLPerfStats::raw_to_ns(tot_render_time_raw - tot_avatar_time_raw - tot_swap_time_raw - tot_ui_time_raw);
+            // auto tot_overhead_time_ns  = LLPerfStats::raw_to_ns( tot_frame_time_raw - tot_render_time_raw - tot_idle_time_raw );
+
+            // // remove time spent sleeping for fps limit or out of focus.
+            // tot_frame_time_ns -= tot_limit_time_ns;
+            // tot_frame_time_ns -= tot_sleep_time_ns;
+
+            if (tot_frame_time_ns != 0)
+            {
+                auto pct_avatar_time = (tot_avatar_time_ns * 100) / tot_frame_time_ns;
+                auto pct_huds_time = (tot_huds_time_ns * 100) / tot_frame_time_ns;
+                auto pct_ui_time = (tot_ui_time_ns * 100) / tot_frame_time_ns;
+                auto pct_idle_time = (tot_idle_time_ns * 100) / tot_frame_time_ns;
+                auto pct_swap_time = (tot_swap_time_ns * 100) / tot_frame_time_ns;
+                auto pct_scene_render_time = (tot_scene_time_ns * 100) / tot_frame_time_ns;
+                pct_avatar_time = llclamp(pct_avatar_time, 0., 100.);
+                pct_huds_time = llclamp(pct_huds_time, 0., 100.);
+                pct_ui_time = llclamp(pct_ui_time, 0., 100.);
+                pct_idle_time = llclamp(pct_idle_time, 0., 100.);
+                pct_swap_time = llclamp(pct_swap_time, 0., 100.);
+                pct_scene_render_time = llclamp(pct_scene_render_time, 0., 100.);
+                if (tot_sleep_time_raw == 0)
+                {
+                    sample(LLStatViewer::SCENERY_FRAME_PCT, (U32)llround(pct_scene_render_time));
+                    sample(LLStatViewer::AVATAR_FRAME_PCT, (U32)llround(pct_avatar_time));
+                    sample(LLStatViewer::HUDS_FRAME_PCT, (U32)llround(pct_huds_time));
+                    sample(LLStatViewer::UI_FRAME_PCT, (U32)llround(pct_ui_time));
+                    sample(LLStatViewer::SWAP_FRAME_PCT, (U32)llround(pct_swap_time));
+                    sample(LLStatViewer::IDLE_FRAME_PCT, (U32)llround(pct_idle_time));
+                }
+            }
+            else
+            {
+                LL_WARNS("performance") << "Scene time 0. Skipping til we have data." << LL_ENDL;
+            }
+            perf_stats_timer.reset();
+        }
+    }
 }
 
 void update_texture_time()
diff --git a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
index 2abd8ec5c0..37efbe654e 100644
--- a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
@@ -410,6 +410,59 @@
           </stat_view>
 			  </stat_view>
 		  </stat_view>
+      <stat_view 
+        name="frame_stats"
+        label="Frame breakdown"
+        show_label="true">
+          <stat_bar name="packet_loss"
+            label="Scenery"
+            orientation="horizontal"
+            unit_label=" %"
+            stat="scenery_frame_pct"
+            bar_max="100"
+            tick_spacing="0.5"
+            show_bar="false"/>
+          <stat_bar name="packet_loss"
+            label="Avatar"
+            orientation="horizontal"
+            unit_label=" %"
+            stat="avatar_frame_pct"
+            bar_max="100"
+            tick_spacing="0.5"
+            show_bar="false"/>
+          <stat_bar name="packet_loss"
+            label="UI"
+            orientation="horizontal"
+            unit_label=" %"
+            stat="ui_frame_pct"
+            bar_max="100"
+            tick_spacing="0.5"
+            show_bar="false"/>
+          <stat_bar name="packet_loss"
+            label="HUDs"
+            orientation="horizontal"
+            unit_label=" %"
+            stat="huds_frame_pct"
+            bar_max="100"
+            tick_spacing="0.5"
+            show_bar="false"/>
+        <stat_bar name="packet_loss"
+            label="Swap"
+            orientation="horizontal"
+            unit_label=" %"
+            stat="swap_frame_pct"
+            bar_max="100"
+            tick_spacing="0.5"
+            show_bar="false"/>
+        <stat_bar name="packet_loss"
+            label="Tasks"
+            orientation="horizontal"
+            unit_label=" %"
+            stat="idle_frame_pct"
+            bar_max="100"
+            tick_spacing="0.5"
+            show_bar="false"/>
+      </stat_view>
     </container_view>
   </scroll_container>
 </floater>
-- 
cgit v1.2.3


From 0bd3560b3e057f7ca74f4d586a02a29235d46489 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 3 Oct 2022 20:49:08 +0300
Subject: SL-18273 add VSync checkbox to Preferred frame rate pane

---
 .../xui/en/panel_performance_autoadjustments.xml   | 43 ++++++++++++++++++++++
 1 file changed, 43 insertions(+)

(limited to 'indra/newview')

diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
index 10ac4b98b7..4c2061bc60 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
@@ -149,6 +149,49 @@
      name="av_and_scene"
      value="1" />
   </combo_box>
+  <view_border
+   bevel_style="in"
+   height="0"
+   layout="topleft"
+   name="border_vsync"
+   top_pad="20"
+   left="20"
+   width="540"/>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   left="20"
+   top_pad="20"
+   name="vsync_desc"
+   width="580">
+    Synchronize the refresh rate and frame rate of a monitor,
+  </text>
+  <text
+   follows="left|top"
+   font="SansSerifSmall"
+   text_color="White"
+   height="18"
+   layout="topleft"
+   top_pad="3"
+   left="20"
+   name="vsync_desc2"
+   width="580">
+    which can result in smoother performance.
+  </text>
+  <check_box
+   control_name="RenderVSyncEnable"
+   height="16"
+   initial_value="true"
+   label="Enable VSync"
+   label_text.text_color="White"
+   layout="topleft"
+   top_pad="15"
+   name="vsync"
+   tool_tip="Enable Vertical synchronization to reduce screen tearing and stuttering."
+   width="315" />
   <view_border
    bevel_style="in"
    height="0"
-- 
cgit v1.2.3


From 56c87233329cf74c2c9111d8b6a1c262b4c29c1e Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 3 Oct 2022 20:56:15 +0300
Subject: SL-18271 update tooltip text for Continuous checkbox

---
 .../newview/skins/default/xui/en/panel_performance_autoadjustments.xml  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
index 4c2061bc60..5d4ffd232b 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
@@ -115,7 +115,7 @@
    left_pad="10"
    name="AutoTuneContinuous"
    top_delta="0"
-   tool_tip="The viewer will continually adapt the settings to meet the target FPS until stopped even with the floater closed. When disabled clicking the Auto Tune button will adjust for the current settings then stop."
+   tool_tip="The viewer will continually adapt the settings to meet the target FPS until stopped even with the floater closed. When disabled clicking the Start button will adjust for the current settings then stop."
    width="64">
   </check_box>
   <text
-- 
cgit v1.2.3


From 82572f0ed422f68838162ead62c7b3ab8ff32014 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 4 Oct 2022 13:17:04 +0300
Subject: SL-18296 FIXED 'Start' button is till toggled when desired FPS is
 reached

---
 indra/newview/llfloaterperformance.cpp | 6 ++++++
 1 file changed, 6 insertions(+)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index e79e9d19b1..644e52c022 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -194,6 +194,12 @@ void LLFloaterPerformance::draw()
             populateObjectList();
         }
 
+        auto button = getChild<LLButton>("AutoTuneFPS");
+        if((bool)button->getToggleState() != LLPerfStats::tunables.userAutoTuneEnabled)
+        {
+            button->toggleState();
+        }
+
         mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL);
     }
     LLFloater::draw();
-- 
cgit v1.2.3


From 386334f32c92be34c1c574c9d30346e559300353 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 21 Oct 2022 18:31:31 +0300
Subject: Post-merge fix

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

(limited to 'indra/newview')

diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 161c8ce0da..2140c70a20 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -781,7 +781,7 @@ void settings_setup_listeners()
     setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
     setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
     setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
-    setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
+    setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleShadowDetailChanged);
     setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
     setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
     setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged);
-- 
cgit v1.2.3


From f5b447bc4781d518fbe7841eea6cadd909b57a0a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 31 Oct 2022 16:46:28 +0200
Subject: SL-18495 Enable autofps for new users by default

---
 indra/newview/app_settings/settings.xml | 4 ++--
 indra/newview/llstartup.cpp             | 4 ++++
 2 files changed, 6 insertions(+), 2 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 657119ae53..292eef64b9 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16742,14 +16742,14 @@
     <key>Type</key>
     <string>U32</string>
     <key>Value</key>
-    <integer>25</integer>
+    <integer>30</integer>
   </map>
   <key>AutoTuneFPS</key>
   <map>
     <key>Comment</key>
     <string>Allow the viewer to adjust your settings to achieve target FPS</string>
     <key>Persist</key>
-    <integer>0</integer>
+    <integer>1</integer>
     <key>Type</key>
     <string>Boolean</string>
     <key>Value</key>
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index e66fefdd1a..87fba5ec1b 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2254,6 +2254,10 @@ bool idle_startup()
 
 	if (STATE_CLEANUP == LLStartUp::getStartupState())
 	{
+        if (gAgent.isFirstLogin())
+        {
+            gSavedSettings.setBOOL("AutoTuneFPS", TRUE);
+        }
         set_startup_status(1.0, "", "");
 		display_startup();
 
-- 
cgit v1.2.3


From af675bbe6311f712738976dc35d89061bff35962 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 8 Nov 2022 12:45:25 +0200
Subject: SL-18584 FIXED viewer starts in minimized mode after a clean install

---
 indra/newview/llappviewer.cpp | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index aef78e08e6..6ef92c98ef 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3024,15 +3024,9 @@ void LLAppViewer::initStrings()
 	}
 }
 
-//
-// This function decides whether the client machine meets the minimum requirements to
-// run in a maximized window, per the consensus of davep, boa and nyx on 3/30/2011.
-//
 bool LLAppViewer::meetsRequirementsForMaximizedStart()
 {
-	bool maximizedOk = (LLFeatureManager::getInstance()->getGPUClass() >= GPU_CLASS_2);
-
-	maximizedOk &= (gSysMemory.getPhysicalMemoryKB() >= U32Gigabytes(1));
+    bool maximizedOk = (gSysMemory.getPhysicalMemoryKB() >= U32Gigabytes(1));
 
 	return maximizedOk;
 }
-- 
cgit v1.2.3


From 72b1cfc76b6deda8771935b086f040b887ffe804 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Wed, 9 Nov 2022 14:42:27 +0200
Subject: SL-18586 FIXED Crash when opening 360 snapshot

---
 indra/newview/llfloater360capture.cpp | 11 +----------
 indra/newview/llperfstats.cpp         |  6 +++++-
 indra/newview/llperfstats.h           |  8 +++++---
 3 files changed, 11 insertions(+), 14 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index c075f7e8bd..a70cd903c5 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -319,13 +319,7 @@ const std::string LLFloater360Capture::getHTMLBaseFolder()
 // triggered when the 'capture' button in the UI is pressed
 void LLFloater360Capture::onCapture360ImagesBtn()
 {
-    // launch the main capture code in a coroutine so we can
-    // yield/suspend at some points to give the main UI
-    // thread a look-in occasionally.
-    LLCoros::instance().launch("capture360cap", [this]()
-    {
-        capture360Images();
-    });
+    capture360Images();
 }
 
 // Gets the full path name for a given JavaScript file in the HTML folder. We
@@ -680,9 +674,6 @@ void LLFloater360Capture::capture360Images()
     mCaptureBtn->setEnabled(true);
     mSaveLocalBtn->setEnabled(true);
 
-    // allow the UI to update by suspending and waiting for the
-    // main render loop to update the UI
-    suspendForAFrame();
 }
 
 // once the request is made to navigate to the web page containing the code
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 1a0e5842e2..3bf88bb2a6 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -43,6 +43,8 @@ namespace LLPerfStats
     U32 lastGlobalPrefChange{0}; 
     std::mutex bufferToggleLock{};
 
+    F64 cpu_hertz{0.0};
+
     Tunables tunables;
 
     std::atomic<int> 	StatsRecorder::writeBuffer{0};
@@ -126,6 +128,8 @@ namespace LLPerfStats
         // create a queue
         // create a thread to consume from the queue
         tunables.initialiseFromSettings();
+        LLPerfStats::cpu_hertz = (F64)LLTrace::BlockTimer::countsPerSecond();
+
         t.detach();
     }
 
@@ -332,7 +336,7 @@ namespace LLPerfStats
         }
 
         // The frametime budget we have based on the target FPS selected
-        auto target_frame_time_raw = (U64)llround((F64)LLTrace::BlockTimer::countsPerSecond()/(tunables.userTargetFPS==0?1:tunables.userTargetFPS));
+        auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz/(tunables.userTargetFPS==0?1:tunables.userTargetFPS));
         // LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL;
         auto inferredFPS{1000/(U32)std::max(raw_to_ms(tot_frame_time_raw),1.0)};
         U32 settingsChangeFrequency{inferredFPS > 25?inferredFPS:25};
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index 961594f18c..ac44afe5db 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -55,6 +55,8 @@ namespace LLPerfStats
     static constexpr U32 TUNE_AVATARS_ONLY{0};
     static constexpr U32 TUNE_SCENE_AND_AVATARS{1};
 
+    extern F64 cpu_hertz;
+
     extern std::atomic<int64_t> tunedAvatars;
     extern std::atomic<U64> renderAvatarMaxART_ns;
     extern bool belowTargetFPS;
@@ -398,9 +400,9 @@ namespace LLPerfStats
     };
 
     
-    inline double raw_to_ns(U64 raw)    { return (static_cast<double>(raw) * 1000000000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
-    inline double raw_to_us(U64 raw)    { return (static_cast<double>(raw) *    1000000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
-    inline double raw_to_ms(U64 raw)    { return (static_cast<double>(raw) *       1000.0) / (F64)LLTrace::BlockTimer::countsPerSecond(); };
+    inline double raw_to_ns(U64 raw)    { return (static_cast<double>(raw) * 1000000000.0) / LLPerfStats::cpu_hertz; };
+    inline double raw_to_us(U64 raw)    { return (static_cast<double>(raw) *    1000000.0) / LLPerfStats::cpu_hertz; };
+    inline double raw_to_ms(U64 raw)    { return (static_cast<double>(raw) *       1000.0) / LLPerfStats::cpu_hertz; };
 
     using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>;
     using RecordAvatarTime = RecordTime<ObjType_t::OT_AVATAR>;
-- 
cgit v1.2.3


From 0ee82f5264067e22013c49abf19344172c2f658b Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Thu, 17 Nov 2022 15:04:38 +0200
Subject: SL-18641 fix for 'Always display friends in full detail' setting

---
 indra/newview/lldrawpoolavatar.cpp     |  2 +-
 indra/newview/llfloaterperformance.cpp |  2 +-
 indra/newview/llviewerpartsim.cpp      |  2 +-
 indra/newview/llvoavatar.cpp           | 20 ++++++++++++++++----
 indra/newview/llvoavatar.h             |  8 +++-----
 indra/newview/pipeline.cpp             |  6 +++---
 6 files changed, 25 insertions(+), 15 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 02dea6b828..4ffa903cca 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -386,7 +386,7 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
 	LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
 	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();    
     // no shadows if the shadows are causing this avatar to breach the limit.
-    if (avatarp->isTooSlowWithShadows() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
+    if (avatarp->isTooSlow() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
 	{
         // No shadows for impostored (including jellydolled) or invisible avs.
 		return;
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 10595f5b6a..51eb137d82 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -372,7 +372,7 @@ void LLFloaterPerformance::populateNearbyList()
             auto render_av_raw  = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_COMBINED);
             LLPerfStats::bufferToggleLock.unlock();
 
-            auto is_slow = avatar->isTooSlowWithShadows();
+            auto is_slow = avatar->isTooSlow();
             LLSD item;
             item["id"] = avatar->getID();
             LLSD& row = item["columns"];
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index a440f3232a..449fd4ba43 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -716,7 +716,7 @@ void LLViewerPartSim::updateSimulation()
 
 			if (upd && vobj && (vobj->getPCode() == LL_PCODE_VOLUME))
 			{
-				if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex() && vobj->getAvatar()->isTooSlowWithShadows())
+				if(vobj->getAvatar() && vobj->getAvatar()->isTooComplex() && vobj->getAvatar()->isTooSlow())
 				{
 					upd = FALSE;
 				}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 776223da9d..c0835e3ed0 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3137,7 +3137,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
 																 LLPartData::LL_PART_TARGET_POS_MASK );
 			
 			// do not generate particles for dummy or overly-complex avatars
-			if (!mIsDummy && !isTooComplex() && !isTooSlowWithShadows())
+			if (!mIsDummy && !isTooComplex() && !isTooSlow())
 			{
 				setParticleSource(particle_parameters, getID());
 			}
@@ -3718,7 +3718,7 @@ bool LLVOAvatar::isVisuallyMuted()
         }
 		else 
 		{
-			muted = isTooComplex() || isTooSlowWithShadows();
+			muted = isTooComplex() || isTooSlow();
 		}
 	}
 
@@ -8288,6 +8288,18 @@ bool LLVOAvatar::isTooComplex() const
 	return too_complex;
 }
 
+bool LLVOAvatar::isTooSlow() const
+{
+    static LLCachedControl<bool> always_render_friends(gSavedSettings, "AlwaysRenderFriends");
+    bool render_friend =  (LLAvatarTracker::instance().isBuddy(getID()) && always_render_friends);
+
+    if (render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+    {
+        return false;
+    }
+    return mTooSlow;
+}
+
 // use Avatar Render Time as complexity metric
 // markARTStale - Mark stale and set the frameupdate to now so that we can wait at least one frame to get a revised number.
 void LLVOAvatar::markARTStale()
@@ -11189,7 +11201,7 @@ LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const
 		{	// Always want to see this AV as an impostor
 			result = AOA_JELLYDOLL;
 		}
-		else if (isTooComplex() || isTooSlowWithShadows())
+		else if (isTooComplex() || isTooSlow())
 		{
 			result = AOA_JELLYDOLL;
 		}
@@ -11216,7 +11228,7 @@ void LLVOAvatar::calcMutedAVColor()
         new_color = LLColor4::grey4;
         change_msg = " blocked: color is grey4";
     }
-    else if (!isTooComplex() && !isTooSlowWithShadows())
+    else if (!isTooComplex() && !isTooSlow())
     {
         new_color = LLColor4::white;
         change_msg = " simple imposter ";
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index a27327d8a3..3429f47dc9 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -354,12 +354,10 @@ public:
     // check and return current state relative to limits
     // default will test only the geometry (combined=false).
     // this allows us to disable shadows separately on complex avatars.
-    inline bool 	isTooSlowWithShadows() const {return mTooSlow;};
+
     inline bool 	isTooSlowWithoutShadows() const {return mTooSlowWithoutShadows;};
-    inline bool 	isTooSlow(bool combined = false) const 
-    {
-        return(combined?mTooSlow:mTooSlowWithoutShadows);
-    }
+    bool 	isTooSlow() const;
+
     void 			updateTooSlow();
 
 	bool 			isTooComplex() const;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 500cea98fb..3e78c9b82c 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -5993,7 +5993,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 			LLDrawable* drawable = light->drawable;
             const LLViewerObject *vobj = light->drawable->getVObj();
             if(vobj && vobj->getAvatar() 
-               && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList() || vobj->getAvatar()->isTooSlowWithShadows())
+               && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList() || vobj->getAvatar()->isTooSlow())
                )
             {
                 drawable->clearState(LLDrawable::NEARBY_LIGHT);
@@ -6072,7 +6072,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 				continue;
 			}
             LLVOAvatar * av = light->getAvatar();
-            if (av && (av->isTooComplex() || av->isInMuteList() || av->isTooSlowWithShadows()))
+            if (av && (av->isTooComplex() || av->isInMuteList() || av->isTooSlow()))
             {
                 // avatars that are already in the list will be removed by removeMutedAVsLights
                 continue;
@@ -10856,7 +10856,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
                               << " is " << ( too_complex ? "" : "not ") << "too complex"
                               << LL_ENDL;
 
-    bool too_slow = avatar->isTooSlowWithShadows();
+    bool too_slow = avatar->isTooSlow();
 
     pushRenderTypeMask();
 
-- 
cgit v1.2.3


From d2766f34c549508feb61b91633caf2aad813923f Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Sat, 19 Nov 2022 11:40:14 +0200
Subject: SL-18675 Display render time as 1 even it's actually less

---
 indra/newview/llfloaterperformance.cpp | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 51eb137d82..36912971d9 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -262,7 +262,7 @@ void LLFloaterPerformance::populateHUDList()
 
         row[1]["column"] = "complex_value";
         row[1]["type"] = "text";
-        row[1]["value"] = llformat( "%.f",LLPerfStats::raw_to_us(hud_render_time_raw) );
+        row[1]["value"] = llformat( "%.f", llmax(LLPerfStats::raw_to_us(hud_render_time_raw), (double)1));
         row[1]["font"]["name"] = "SANSSERIF";
  
         row[2]["column"] = "name";
@@ -321,7 +321,7 @@ void LLFloaterPerformance::populateObjectList()
 
             row[1]["column"] = "complex_value";
             row[1]["type"] = "text";
-            row[1]["value"] = llformat("%.f", LLPerfStats::raw_to_us(attach_render_time_raw));
+            row[1]["value"] = llformat("%.f", llmax(LLPerfStats::raw_to_us(attach_render_time_raw), (double)1));
             row[1]["font"]["name"] = "SANSSERIF";
 
             row[2]["column"] = "name";
-- 
cgit v1.2.3


From f0809019f807bdcfec719f32538582ea86edf9e3 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Sat, 19 Nov 2022 12:04:33 +0200
Subject: SL-18670 change limits of RenderVolumeLODFactor in Preference similar
 to Distance detail ctrl; update slider text correctly

---
 indra/newview/llfloaterpreferencesgraphicsadvanced.cpp         | 10 ++++++++--
 indra/newview/llfloaterpreferencesgraphicsadvanced.h           |  2 ++
 .../default/xui/en/floater_preferences_graphics_advanced.xml   |  4 ++--
 3 files changed, 12 insertions(+), 4 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index 98ebe7d4e8..a976b97831 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -58,6 +58,7 @@ LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const L
 LLFloaterPreferenceGraphicsAdvanced::~LLFloaterPreferenceGraphicsAdvanced()
 {
     mComplexityChangedSignal.disconnect();
+    mLODFactorChangedSignal.disconnect();
 }
 
 BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
@@ -77,8 +78,8 @@ BOOL LLFloaterPreferenceGraphicsAdvanced::postBuild()
     use_HiDPI->setVisible(FALSE);
 #endif
 
-    mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this));
-
+    mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this)); 
+    mLODFactorChangedSignal = gSavedSettings.getControl("RenderVolumeLODFactor")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateObjectMeshDetailText, this));
     return TRUE;
 }
 
@@ -164,6 +165,11 @@ void LLFloaterPreferenceGraphicsAdvanced::updateComplexityText()
         getChild<LLTextBox>("IndirectMaxComplexityText", true));
 }
 
+void LLFloaterPreferenceGraphicsAdvanced::updateObjectMeshDetailText()
+{
+    updateSliderText(getChild<LLSliderCtrl>("ObjectMeshDetail", true), getChild<LLTextBox>("ObjectMeshDetailText", true));
+}
+
 void LLFloaterPreferenceGraphicsAdvanced::updateSliderText(LLSliderCtrl* ctrl, LLTextBox* text_box)
 {
     if (text_box == NULL || ctrl== NULL)
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
index 7f26ff8b00..2c92f3dbf1 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.h
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h
@@ -49,6 +49,7 @@ public:
     void setMaxNonImpostorsText(U32 value, LLTextBox* text_box);
     void updateMaxComplexity();
     void updateComplexityText();
+    void updateObjectMeshDetailText();
     void refresh();
     // callback for when client modifies a render option
     void onRenderOptionEnable();
@@ -60,6 +61,7 @@ protected:
     void		onBtnCancel(const LLSD& userdata);
 
     boost::signals2::connection	mComplexityChangedSignal;
+    boost::signals2::connection	mLODFactorChangedSignal;
 };
 
 #endif //LLFLOATERPREFERENCEGRAPHICSADVANCED_H
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 9da6ec093b..11c2d11987 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
@@ -522,8 +522,8 @@
     label_width="185"
     layout="topleft"
     left="420"
-    min_val="1"
-    max_val="2"
+    min_val="0"
+    max_val="4"
     name="ObjectMeshDetail"
     show_text="false"
     top_delta="16"
-- 
cgit v1.2.3


From 24839c8cf601cac5dbc9ca49166470f0263f7e3c Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Thu, 5 Jan 2023 19:13:57 +0200
Subject: SL-18884 Remove dead spot from Back button

---
 .../default/xui/en/panel_performance_autoadjustments.xml     | 12 +++++++-----
 .../skins/default/xui/en/panel_performance_complexity.xml    | 12 +++++++-----
 .../newview/skins/default/xui/en/panel_performance_huds.xml  | 12 +++++++-----
 .../skins/default/xui/en/panel_performance_nearby.xml        | 12 +++++++-----
 .../skins/default/xui/en/panel_performance_preferences.xml   | 12 +++++++-----
 5 files changed, 35 insertions(+), 25 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
index 5d4ffd232b..ab7b4d3ee7 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
@@ -24,12 +24,14 @@
   </button>
   <text
    follows="left|top"
-   height="20"
+   height="18"
    layout="topleft"
-   left_pad="3"
-   top="10"
+   left_pad="0"
+   valign="center"
+   halign="center"
+   top="6"
    name="back_lbl"
-   width="40">
+   width="32">
     Back
   </text>
   <text
@@ -39,7 +41,7 @@
    height="20"
    layout="topleft"
    left="20"
-   top_pad="10"
+   top_pad="15"
    name="settings_title"
    width="300">
     Preferred frame rate
diff --git a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
index 954fd0a8c1..cd3f610a92 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_complexity.xml
@@ -24,12 +24,14 @@
   </button>
   <text
    follows="left|top"
-   height="20"
+   height="18"
    layout="topleft"
-   left_pad="3"
-   top="10"
+   left_pad="0"
+   valign="center"
+   halign="center"
+   top="6"
    name="back_lbl"
-   width="40">
+   width="32">
     Back
   </text>
   <text
@@ -39,7 +41,7 @@
    height="20"
    layout="topleft"
    left="20"
-   top_pad="10"
+   top_pad="15"
    name="attachments_title"
    width="195">
     Your avatar complexity 
diff --git a/indra/newview/skins/default/xui/en/panel_performance_huds.xml b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
index 289f865eb7..2fddcb3b9e 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_huds.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_huds.xml
@@ -24,12 +24,14 @@
   </button>
   <text
    follows="left|top"
-   height="20"
+   height="18"
    layout="topleft"
-   left_pad="3"
-   top="10"
+   left_pad="0"
+   valign="center"
+   halign="center"
+   top="6"
    name="back_lbl"
-   width="40">
+   width="32">
     Back
   </text>
   <text
@@ -39,7 +41,7 @@
    height="20"
    layout="topleft"
    left="20"
-   top_pad="10"
+   top_pad="15"
    name="huds_title"
    width="135">
     Your active HUDs
diff --git a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
index e80bf592e4..cb795e59a9 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml
@@ -24,12 +24,14 @@
   </button>
   <text
    follows="left|top"
-   height="20"
+   height="18"
    layout="topleft"
-   left_pad="3"
-   top="10"
+   left_pad="0"
+   valign="center"
+   halign="center"
+   top="6"
    name="back_lbl"
-   width="40">
+   width="32">
     Back
   </text>
   <text
@@ -39,7 +41,7 @@
    height="20"
    layout="topleft"
    left="20"
-   top_pad="10"
+   top_pad="15"
    name="av_nearby_title"
    width="205">
     Avatars nearby
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index ee8105eac9..9c1a3ebd9e 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -24,12 +24,14 @@
   </button>
   <text
    follows="left|top"
-   height="20"
+   height="18"
    layout="topleft"
-   left_pad="3"
-   top="10"
+   left_pad="0"
+   valign="center"
+   halign="center"
+   top="6"
    name="back_lbl"
-   width="40">
+   width="32">
     Back
   </text>
   <text
@@ -39,7 +41,7 @@
    height="20"
    layout="topleft"
    left="20"
-   top_pad="10"
+   top_pad="15"
    name="settings_title"
    width="300">
     Graphics settings
-- 
cgit v1.2.3


From 495e34b84fa34ae5394f33f6f1175e959c56e769 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Tue, 10 Jan 2023 16:29:28 +0200
Subject: SL-18922 FIXED Imposters load with attachments using Perf floater

---
 indra/newview/pipeline.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index ad47b3d154..51d7082b40 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -10871,11 +10871,9 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
                               << " is " << ( too_complex ? "" : "not ") << "too complex"
                               << LL_ENDL;
 
-    bool too_slow = avatar->isTooSlow();
-
     pushRenderTypeMask();
 
-    if ( !too_slow && ( visually_muted || too_complex ) )
+    if (visually_muted || too_complex)
     {
         // only show jelly doll geometry
 		andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR,
-- 
cgit v1.2.3


From 020bfa66ba9f1fee3e403595a1d6c95332bb16f7 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Tue, 10 Jan 2023 22:53:32 +0200
Subject: SL-18923 Add Reset to default settings button

---
 indra/newview/llfloaterperformance.cpp             | 10 +++++++++
 indra/newview/llfloaterperformance.h               |  1 +
 indra/newview/llfloaterpreference.cpp              |  6 ++++++
 indra/newview/llfloaterpreference.h                |  2 ++
 .../xui/en/panel_performance_preferences.xml       | 25 +++++++++++++++-------
 5 files changed, 36 insertions(+), 8 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 36912971d9..88319b170f 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -127,6 +127,7 @@ BOOL LLFloaterPerformance::postBuild()
     mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1));
 
     mSettingsPanel->getChild<LLButton>("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this));
+    mSettingsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this));
     mSettingsPanel->getChild<LLRadioGroup>("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2));
     mSettingsPanel->getChild<LLCheckBoxCtrl>("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this));
     mSettingsPanel->getChild<LLComboBox>("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this));
@@ -477,6 +478,15 @@ void LLFloaterPerformance::onClickAdvanced()
     LLFloaterReg::showInstance("prefs_graphics_advanced");
 }
 
+void LLFloaterPerformance::onClickDefaults()
+{
+    LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
+    if (instance)
+    {
+        instance->setRecommendedSettings();
+    }
+}
+
 void LLFloaterPerformance::onChangeQuality(const LLSD& data)
 {
     LLFloaterPreference* instance = LLFloaterReg::getTypedInstance<LLFloaterPreference>("preferences");
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 09bcd18bb5..6a72f3d7c5 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -61,6 +61,7 @@ private:
     void setFPSText();
 
     void onClickAdvanced();
+    void onClickDefaults();
     void onChangeQuality(const LLSD& data);
     void onClickHideAvatars();
     void onClickExceptions();
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 76633a46a9..bb4ddf5969 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -788,6 +788,12 @@ void LLFloaterPreference::setHardwareDefaults()
 		saveGraphicsPreset(preset_graphic_active);
 		saveSettings(); // save here to be able to return to the previous preset by Cancel
 	}
+    setRecommendedSettings();
+}
+
+void LLFloaterPreference::setRecommendedSettings()
+{
+    gSavedSettings.setBOOL("AutoTuneFPS", FALSE);
 
 	LLFeatureManager::getInstance()->applyRecommendedSettings();
 
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index d5d0aca939..32a55a2948 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -199,6 +199,8 @@ public:
 	void saveCameraPreset(std::string& preset);
 	void saveGraphicsPreset(std::string& preset);
 
+    void setRecommendedSettings();
+
 private:
 
 	void onDeleteTranscripts();
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index 9c1a3ebd9e..b52c19d5e3 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -47,14 +47,23 @@
     Graphics settings
   </text>
   <button
-    follows="top|left"
-    height="23"
-    label="Open Advanced Settings"
-    layout="topleft"
-    left="360"
-    name="advanced_btn"
-    top_delta="0"
-    width="200"/>
+   follows="top|left"
+   height="23"
+   label="Open Advanced Settings"
+   layout="topleft"
+   left="360"
+   name="advanced_btn"
+   top_delta="-35"
+   width="200"/>
+  <button
+   follows="top|left"
+   height="23"
+   label="Reset to recommended settings"
+   layout="topleft"
+   left="350"
+   name="defaults_btn"
+   top_pad="10"
+   width="210"/>
   <view_border
    bevel_style="in"
    height="0"
-- 
cgit v1.2.3


From 005b29b89f7a3cbe54d37b53c0061ee36c80d871 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Wed, 11 Jan 2023 19:34:04 +0200
Subject: SL-18933 FIXED Maximum render time cycles if the Desired framerate is
 much lower than current framerate

---
 indra/newview/llperfstats.cpp |  2 +-
 indra/newview/llperfstats.h   |  2 +-
 indra/newview/llvoavatar.cpp  | 14 +++++++++++++-
 indra/newview/llvoavatar.h    |  2 ++
 4 files changed, 17 insertions(+), 3 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 3bf88bb2a6..f3d433a622 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -446,7 +446,7 @@ namespace LLPerfStats
                     // turn off if we are not locked.
                     tunables.updateUserAutoTuneEnabled(false);
                 }
-                if( LLPerfStats::tunedAvatars > 0 )
+                if(renderAvatarMaxART_ns != 0 && LLPerfStats::tunedAvatars > 0 )
                 {
                     // if we have more time to spare let's shift up little in the hope we'll restore an avatar.
                     renderAvatarMaxART_ns += LLPerfStats::ART_MIN_ADJUST_UP_NANOS;
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index ac44afe5db..7aa3e1491c 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -45,7 +45,7 @@ namespace LLPerfStats
 // Note if changing these, they should correspond with the log range of the correpsonding sliders
     static constexpr U64 ART_UNLIMITED_NANOS{50000000};
     static constexpr U64 ART_MINIMUM_NANOS{100000};
-    static constexpr U64 ART_MIN_ADJUST_UP_NANOS{10000};
+    static constexpr U64 ART_MIN_ADJUST_UP_NANOS{20000};
     static constexpr U64 ART_MIN_ADJUST_DOWN_NANOS{10000}; 
 
     static constexpr F32 PREFERRED_DD{180};
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 9c74323f99..dbfd47d2fa 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -816,6 +816,12 @@ LLVOAvatar::~LLVOAvatar()
 		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
 	}
 
+    if(mTuned)
+    {
+        LLPerfStats::tunedAvatars--;
+        mTuned = false;
+    }
+
 	logPendingPhases();
 	
 	LL_DEBUGS("Avatar") << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << LL_ENDL;
@@ -8382,9 +8388,15 @@ void LLVOAvatar::updateTooSlow()
         mTooSlow = false;
         mTooSlowWithoutShadows = false;	
     }
-    if(mTooSlow)
+    if(mTooSlow && !mTuned)
     {
         LLPerfStats::tunedAvatars++; // increment the number of avatars that have been tweaked.
+        mTuned = true;
+    }
+    else if(!mTooSlow && mTuned)
+    {
+        LLPerfStats::tunedAvatars--;
+        mTuned = false;
     }
 }
 
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index bdc3d98e21..e07ead9d46 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -410,6 +410,8 @@ private:
     bool			mTooSlow{false};
     bool			mTooSlowWithoutShadows{false};
 
+    bool            mTuned{false};
+
 private:
 	LLViewerStats::PhaseMap mPhases;
 
-- 
cgit v1.2.3


From 1ecb7186fb33e8cf2d9598e5c3c3d0a8041ab1d2 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Fri, 13 Jan 2023 15:34:59 +0200
Subject: SL-18973 Wait a bit after viewer regains focus before engaging the
 Preferred frame rate

---
 indra/newview/llperfstats.cpp     | 24 +++++++++++++++++++++++-
 indra/newview/llperfstats.h       |  2 ++
 indra/newview/llviewercontrol.cpp |  1 +
 3 files changed, 26 insertions(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index f3d433a622..334fdbbb6e 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -29,7 +29,9 @@
 #include "llcontrol.h"
 #include "pipeline.h"
 #include "llagentcamera.h"
+#include "llviewerwindow.h"
 #include "llvoavatar.h"
+#include "llwindow.h"
 #include "llworld.h"
 #include <llthread.h>
 
@@ -41,9 +43,11 @@ namespace LLPerfStats
     std::atomic<U64> renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features
     bool belowTargetFPS{false};
     U32 lastGlobalPrefChange{0}; 
+    U32 lastSleepedFrame{0};
     std::mutex bufferToggleLock{};
 
     F64 cpu_hertz{0.0};
+    U32 vsync_max_fps{60};
 
     Tunables tunables;
 
@@ -115,6 +119,7 @@ namespace LLPerfStats
         LLPerfStats::tunables.userImpostorDistanceTuningEnabled = gSavedSettings.getBOOL("AutoTuneImpostorByDistEnabled");
         LLPerfStats::tunables.userFPSTuningStrategy = gSavedSettings.getU32("TuningFPSStrategy");
         LLPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("TargetFPS");
+        LLPerfStats::tunables.vsyncEnabled = gSavedSettings.getBOOL("RenderVSyncEnable");
         LLPerfStats::tunables.userTargetReflections = gSavedSettings.getS32("UserTargetReflections");
         LLPerfStats::tunables.userAutoTuneEnabled = gSavedSettings.getBOOL("AutoTuneFPS");
         LLPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("AutoTuneLock");
@@ -129,7 +134,7 @@ namespace LLPerfStats
         // create a thread to consume from the queue
         tunables.initialiseFromSettings();
         LLPerfStats::cpu_hertz = (F64)LLTrace::BlockTimer::countsPerSecond();
-
+        LLPerfStats::vsync_max_fps = gViewerWindow->getWindow()->getRefreshRate();
         t.detach();
     }
 
@@ -332,9 +337,26 @@ namespace LLPerfStats
             // if at some point we need to, the averaging will need to take this into account or 
             // we forever think we're in the background due to residuals.
             LL_DEBUGS() << "No tuning when not in focus" << LL_ENDL;
+            LLPerfStats::lastSleepedFrame = gFrameCount;
             return;
         }
 
+        U32 target_fps = tunables.vsyncEnabled ? std::min(LLPerfStats::vsync_max_fps, tunables.userTargetFPS) : tunables.userTargetFPS;
+
+        if(LLPerfStats::lastSleepedFrame != 0)
+        {
+            // wait a short time after viewer regains focus
+            if((gFrameCount - LLPerfStats::lastSleepedFrame) > target_fps * 5)
+            {
+                LLPerfStats::lastSleepedFrame = 0;
+            }
+            else
+            {
+                return;
+            }
+        }
+        
+
         // The frametime budget we have based on the target FPS selected
         auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz/(tunables.userTargetFPS==0?1:tunables.userTargetFPS));
         // LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL;
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index 7aa3e1491c..f00a28703c 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -61,6 +61,7 @@ namespace LLPerfStats
     extern std::atomic<U64> renderAvatarMaxART_ns;
     extern bool belowTargetFPS;
     extern U32 lastGlobalPrefChange;
+    extern U32 lastSleepedFrame;
     extern std::mutex bufferToggleLock;
 
     enum class ObjType_t{
@@ -133,6 +134,7 @@ namespace LLPerfStats
         U32 userTargetFPS{0};
         F32 userARTCutoffSliderValue{0};
         S32 userTargetReflections{0};
+        bool vsyncEnabled{true};
 
         void updateNonImposters(U32 nv){nonImpostors=nv; tuningFlag |= NonImpostors;};
         void updateReflectionDetail(S32 nv){reflectionDetail=nv; tuningFlag |= ReflectionDetail;};
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 407aacdd99..0bade93c45 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -267,6 +267,7 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)
 
 static bool handleVSyncChanged(const LLSD& newvalue)
 {
+    LLPerfStats::tunables.vsyncEnabled = newvalue.asBoolean();
     gViewerWindow->getWindow()->toggleVSync(newvalue.asBoolean());
 
     return true;
-- 
cgit v1.2.3


From 6c418060c183a40c9e7f56d1fcf81ac8308091a2 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Mon, 16 Jan 2023 19:12:42 +0200
Subject: SL-18979 FIXED "Reset to recommended settings" should reset Maximum
 render time of Avatars nearby

---
 indra/newview/llfloaterpreference.cpp | 24 +++++++++++++++++++++++-
 indra/newview/llfloaterpreference.h   |  1 +
 2 files changed, 24 insertions(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index bb4ddf5969..531270f936 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -793,7 +793,8 @@ void LLFloaterPreference::setHardwareDefaults()
 
 void LLFloaterPreference::setRecommendedSettings()
 {
-    gSavedSettings.setBOOL("AutoTuneFPS", FALSE);
+    resetAutotuneSettings();
+    gSavedSettings.getControl("RenderVSyncEnable")->resetToDefault(true);
 
 	LLFeatureManager::getInstance()->applyRecommendedSettings();
 
@@ -818,6 +819,27 @@ void LLFloaterPreference::setRecommendedSettings()
 	}
 }
 
+void LLFloaterPreference::resetAutotuneSettings()
+{
+    gSavedSettings.setBOOL("AutoTuneFPS", FALSE);
+
+    const std::string autotune_settings[] = {
+        "AutoTuneLock",
+        "TargetFPS",
+        "TuningFPSStrategy",
+        "AutoTuneImpostorByDistEnabled",
+        "AutoTuneImpostorFarAwayDistance" ,
+        "AutoTuneRenderFarClipMin",
+        "AutoTuneRenderFarClipTarget",
+        "RenderAvatarMaxART"
+    };
+
+    for (auto it : autotune_settings)
+    {
+        gSavedSettings.getControl(it)->resetToDefault(true);
+    }
+}
+
 void LLFloaterPreference::getControlNames(std::vector<std::string>& names)
 {
 	LLView* view = findChild<LLView>("display");
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 32a55a2948..2aa6ca87b7 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -200,6 +200,7 @@ public:
 	void saveGraphicsPreset(std::string& preset);
 
     void setRecommendedSettings();
+    void resetAutotuneSettings();
 
 private:
 
-- 
cgit v1.2.3


From a7280281a1dc8c7ff1ec5729ff77dbc5e8eb8e67 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Tue, 17 Jan 2023 20:25:32 +0200
Subject: SL-18934  Don't adjust settings if mean frame time still doesn't
 exceed expected

---
 indra/newview/llperfstats.cpp | 31 +++++++++++++++++++++++++++++--
 indra/newview/llperfstats.h   |  1 +
 2 files changed, 30 insertions(+), 2 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 334fdbbb6e..0e575f0626 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -302,6 +302,23 @@ namespace LLPerfStats
         return positions.size();
 	}
 
+    const U32 NUM_PERIODS = 50;
+    U64 StatsRecorder::getMeanTotalFrameTime(U64 cur_frame_time_raw)
+    {
+        static std::deque<U64> frame_time_deque;
+        frame_time_deque.push_front(cur_frame_time_raw);
+        if (frame_time_deque.size() > NUM_PERIODS)
+        {
+            frame_time_deque.pop_back();
+        }
+        
+        std::vector<U64> buf(frame_time_deque.begin(), frame_time_deque.end());
+        std::sort(buf.begin(), buf.end());
+
+        U64 mean = (buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2];
+        return mean;
+    }
+
     // static
     void StatsRecorder::updateAvatarParams()
     {
@@ -358,7 +375,7 @@ namespace LLPerfStats
         
 
         // The frametime budget we have based on the target FPS selected
-        auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz/(tunables.userTargetFPS==0?1:tunables.userTargetFPS));
+        auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz / (target_fps == 0 ? 1 : target_fps));
         // LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL;
         auto inferredFPS{1000/(U32)std::max(raw_to_ms(tot_frame_time_raw),1.0)};
         U32 settingsChangeFrequency{inferredFPS > 25?inferredFPS:25};
@@ -367,9 +384,19 @@ namespace LLPerfStats
             // This could be problematic.
             tot_frame_time_raw -= tot_limit_time_raw;
         }*/
+        
+        F64 time_buf = target_frame_time_raw * 0.1;
+
         // 1) Is the target frame time lower than current?
-        if( target_frame_time_raw <= tot_frame_time_raw )
+        if ((target_frame_time_raw + time_buf) <= tot_frame_time_raw)
         {
+            if (target_frame_time_raw - time_buf >= getMeanTotalFrameTime(tot_frame_time_raw))
+            {
+                belowTargetFPS = false;
+                LLPerfStats::lastGlobalPrefChange = gFrameCount;
+                return;
+            }
+
             if(belowTargetFPS == false)
             {
                 // this is the first frame under. hold fire to add a little hysteresis
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index f00a28703c..fb0b197f20 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -203,6 +203,7 @@ namespace LLPerfStats
         StatsRecorder();
 
         static int countNearbyAvatars(S32 distance);
+        static U64 getMeanTotalFrameTime(U64 tot_frame_time_raw);
 // StatsArray is a uint64_t for each possible statistic type.
         using StatsArray    = std::array<uint64_t, static_cast<size_t>(LLPerfStats::StatType_t::STATS_COUNT)>;
         using StatsMap      = std::unordered_map<LLUUID, StatsArray, boost::hash<LLUUID>>;
-- 
cgit v1.2.3


From cf2e153b7add9faefb3066051dbd971ab8f8dddb Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Wed, 18 Jan 2023 17:14:06 +0200
Subject: SL-18978 Avatars switch to/from impostored too quickly

---
 indra/newview/llperfstats.cpp | 19 ++++++++++++-------
 indra/newview/llperfstats.h   |  6 ++++--
 2 files changed, 16 insertions(+), 9 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 0e575f0626..234379a199 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -44,6 +44,7 @@ namespace LLPerfStats
     bool belowTargetFPS{false};
     U32 lastGlobalPrefChange{0}; 
     U32 lastSleepedFrame{0};
+    U64 meanFrameTime{0};
     std::mutex bufferToggleLock{};
 
     F64 cpu_hertz{0.0};
@@ -303,7 +304,7 @@ namespace LLPerfStats
 	}
 
     const U32 NUM_PERIODS = 50;
-    U64 StatsRecorder::getMeanTotalFrameTime(U64 cur_frame_time_raw)
+    void StatsRecorder::updateMeanFrameTime(U64 cur_frame_time_raw)
     {
         static std::deque<U64> frame_time_deque;
         frame_time_deque.push_front(cur_frame_time_raw);
@@ -315,8 +316,11 @@ namespace LLPerfStats
         std::vector<U64> buf(frame_time_deque.begin(), frame_time_deque.end());
         std::sort(buf.begin(), buf.end());
 
-        U64 mean = (buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2];
-        return mean;
+        LLPerfStats::meanFrameTime = (buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2];
+    }
+    U64 StatsRecorder::getMeanTotalFrameTime()
+    {
+        return LLPerfStats::meanFrameTime;
     }
 
     // static
@@ -372,13 +376,13 @@ namespace LLPerfStats
                 return;
             }
         }
-        
+        updateMeanFrameTime(tot_frame_time_raw);
 
         // The frametime budget we have based on the target FPS selected
         auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz / (target_fps == 0 ? 1 : target_fps));
         // LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL;
         auto inferredFPS{1000/(U32)std::max(raw_to_ms(tot_frame_time_raw),1.0)};
-        U32 settingsChangeFrequency{inferredFPS > 25?inferredFPS:25};
+        U32 settingsChangeFrequency{inferredFPS > 50?inferredFPS:50};
         /*if( tot_limit_time_raw != 0)
         {
             // This could be problematic.
@@ -390,7 +394,7 @@ namespace LLPerfStats
         // 1) Is the target frame time lower than current?
         if ((target_frame_time_raw + time_buf) <= tot_frame_time_raw)
         {
-            if (target_frame_time_raw - time_buf >= getMeanTotalFrameTime(tot_frame_time_raw))
+            if (target_frame_time_raw - time_buf >= getMeanTotalFrameTime())
             {
                 belowTargetFPS = false;
                 LLPerfStats::lastGlobalPrefChange = gFrameCount;
@@ -498,7 +502,8 @@ namespace LLPerfStats
                 if(renderAvatarMaxART_ns != 0 && LLPerfStats::tunedAvatars > 0 )
                 {
                     // if we have more time to spare let's shift up little in the hope we'll restore an avatar.
-                    renderAvatarMaxART_ns += LLPerfStats::ART_MIN_ADJUST_UP_NANOS;
+                    U64 up_step = LLPerfStats::tunedAvatars > 2 ? LLPerfStats::ART_MIN_ADJUST_UP_NANOS : LLPerfStats::ART_MIN_ADJUST_UP_NANOS * 2;
+                    renderAvatarMaxART_ns += up_step;
                     tunables.updateSettingsFromRenderCostLimit();
                     return;
                 }
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index fb0b197f20..17d936483f 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -45,7 +45,7 @@ namespace LLPerfStats
 // Note if changing these, they should correspond with the log range of the correpsonding sliders
     static constexpr U64 ART_UNLIMITED_NANOS{50000000};
     static constexpr U64 ART_MINIMUM_NANOS{100000};
-    static constexpr U64 ART_MIN_ADJUST_UP_NANOS{20000};
+    static constexpr U64 ART_MIN_ADJUST_UP_NANOS{5000};
     static constexpr U64 ART_MIN_ADJUST_DOWN_NANOS{10000}; 
 
     static constexpr F32 PREFERRED_DD{180};
@@ -62,6 +62,7 @@ namespace LLPerfStats
     extern bool belowTargetFPS;
     extern U32 lastGlobalPrefChange;
     extern U32 lastSleepedFrame;
+    extern U64 meanFrameTime;
     extern std::mutex bufferToggleLock;
 
     enum class ObjType_t{
@@ -203,7 +204,8 @@ namespace LLPerfStats
         StatsRecorder();
 
         static int countNearbyAvatars(S32 distance);
-        static U64 getMeanTotalFrameTime(U64 tot_frame_time_raw);
+        static U64 getMeanTotalFrameTime();
+        static void updateMeanFrameTime(U64 tot_frame_time_raw);
 // StatsArray is a uint64_t for each possible statistic type.
         using StatsArray    = std::array<uint64_t, static_cast<size_t>(LLPerfStats::StatType_t::STATS_COUNT)>;
         using StatsMap      = std::unordered_map<LLUUID, StatsArray, boost::hash<LLUUID>>;
-- 
cgit v1.2.3


From 6cbe17305c08646d571c90d7df6fc174db6f9aeb Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Thu, 19 Jan 2023 15:55:44 +0200
Subject: SL-18991 FIXED Autotune starts too early after login-in

---
 indra/newview/llagent.cpp     |  4 +++-
 indra/newview/llperfstats.cpp | 41 ++++++++++++++++++++++++-----------------
 indra/newview/llperfstats.h   |  3 +++
 indra/newview/llstartup.cpp   |  2 ++
 4 files changed, 32 insertions(+), 18 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index e5b3557a72..8cc9be7244 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -63,6 +63,7 @@
 #include "llnotificationsutil.h"
 #include "llpaneltopinfobar.h"
 #include "llparcel.h"
+#include "llperfstats.h"
 #include "llrendersphere.h"
 #include "llscriptruntimeperms.h"
 #include "llsdutil.h"
@@ -4102,7 +4103,7 @@ void LLAgent::handleTeleportFinished()
             mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));
         }
     }
-
+    LLPerfStats::tunables.autoTuneTimeout = true;
 }
 
 void LLAgent::handleTeleportFailed()
@@ -4135,6 +4136,7 @@ void LLAgent::handleTeleportFailed()
 
     mTPNeedsNeabyChatSeparator = false;
 
+    LLPerfStats::tunables.autoTuneTimeout = true;
 }
 
 /*static*/
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 234379a199..8d2f4e68ae 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -55,6 +55,7 @@ namespace LLPerfStats
     std::atomic<int> 	StatsRecorder::writeBuffer{0};
     bool 	            StatsRecorder::collectionEnabled{true};
     LLUUID              StatsRecorder::focusAv{LLUUID::null};
+    bool                StatsRecorder::autotuneInit{false};
 	std::array<StatsRecorder::StatsTypeMatrix,2>  StatsRecorder::statsDoubleBuffer{ {} };
     std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::max{ {} };
     std::array<StatsRecorder::StatsSummaryArray,2> StatsRecorder::sum{ {} };
@@ -239,7 +240,7 @@ namespace LLPerfStats
         }
 
         // and now adjust the proxy vars so that the main thread can adjust the visuals.
-        if(tunables.userAutoTuneEnabled)
+        if(autotuneInit && tunables.userAutoTuneEnabled)
         {
             updateAvatarParams();
         }
@@ -326,24 +327,13 @@ namespace LLPerfStats
     // static
     void StatsRecorder::updateAvatarParams()
     {
-
-        if(tunables.userImpostorDistanceTuningEnabled)
+        if(tunables.autoTuneTimeout)
         {
-            // if we have less than the user's "max Non-Impostors" avatars within the desired range then adjust the limit.
-            // also adjusts back up again for nearby crowds.
-            auto count = countNearbyAvatars(std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance));
-            if( count != tunables.nonImpostors )
-            {
-                tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER );
-                LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance) << "m of the camera" << LL_ENDL;
-            }
+            LLPerfStats::lastSleepedFrame = gFrameCount;
+            tunables.autoTuneTimeout = false;
+            return;
         }
-
-        auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
-        // Is our target frame time lower than current? If so we need to take action to reduce draw overheads.
-        // cumulative avatar time (includes idle processing, attachments and base av)
-        auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
-        // sleep time is basically forced sleep when window out of focus 
+        // sleep time is basically forced sleep when window out of focus
         auto tot_sleep_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_SLEEP);
         // similar to sleep time, induced by FPS limit
         //auto tot_limit_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FPSLIMIT);
@@ -378,6 +368,23 @@ namespace LLPerfStats
         }
         updateMeanFrameTime(tot_frame_time_raw);
 
+        if(tunables.userImpostorDistanceTuningEnabled)
+        {
+            // if we have less than the user's "max Non-Impostors" avatars within the desired range then adjust the limit.
+            // also adjusts back up again for nearby crowds.
+            auto count = countNearbyAvatars(std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance));
+            if( count != tunables.nonImpostors )
+            {
+                tunables.updateNonImposters( (count < LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER)?count : LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER );
+                LL_DEBUGS("AutoTune") << "There are " << count << "avatars within " << std::min(LLPipeline::RenderFarClip, tunables.userImpostorDistance) << "m of the camera" << LL_ENDL;
+            }
+        }
+
+        auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
+        // Is our target frame time lower than current? If so we need to take action to reduce draw overheads.
+        // cumulative avatar time (includes idle processing, attachments and base av)
+        auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
+
         // The frametime budget we have based on the target FPS selected
         auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz / (target_fps == 0 ? 1 : target_fps));
         // LL_INFOS() << "Effective FPS(raw):" << tot_frame_time_raw << " Target:" << target_frame_time_raw << LL_ENDL;
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index 17d936483f..200ff1f248 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -135,6 +135,7 @@ namespace LLPerfStats
         U32 userTargetFPS{0};
         F32 userARTCutoffSliderValue{0};
         S32 userTargetReflections{0};
+        bool autoTuneTimeout{true};
         bool vsyncEnabled{true};
 
         void updateNonImposters(U32 nv){nonImpostors=nv; tuningFlag |= NonImpostors;};
@@ -171,6 +172,7 @@ namespace LLPerfStats
         }
         static inline void setFocusAv(const LLUUID& avID){focusAv = avID;};
         static inline const LLUUID& getFocusAv(){return focusAv;};
+        static inline void setAutotuneInit(){autotuneInit = true;};
         static inline void send(StatsRecord && upd){StatsRecorder::getInstance().q.pushFront(std::move(upd));};
         static void endFrame(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 0});};
         static void clearStats(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 1});};
@@ -214,6 +216,7 @@ namespace LLPerfStats
 
         static std::atomic<int> writeBuffer;
         static LLUUID focusAv;
+        static bool autotuneInit;
         static std::array<StatsTypeMatrix,2> statsDoubleBuffer;
         static std::array<StatsSummaryArray,2> max;
         static std::array<StatsSummaryArray,2> sum;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index eaa1a0574b..83ab8ee7e8 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2351,6 +2351,8 @@ bool idle_startup()
 
 		LLUIUsage::instance().clear();
 
+        LLPerfStats::StatsRecorder::setAutotuneInit();
+
 		return TRUE;
 	}
 
-- 
cgit v1.2.3


From aac046c81e28725761876b40f5bf00e12daa9471 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 20 Jan 2023 18:47:17 +0200
Subject: SL-19004 FIXED Autotune doesn't try to improve settings with VSync on
 and target FPS 60

---
 indra/newview/llperfstats.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 8d2f4e68ae..cb5c674a32 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -488,7 +488,8 @@ namespace LLPerfStats
             }
             // LL_DEBUGS() << "AUTO_TUNE: Target frame time:"<< LLPerfStats::raw_to_us(target_frame_time_raw) << "usecs (non_avatar is " << LLPerfStats::raw_to_us(non_avatar_time_raw) << "usecs) Max cost limited=" << renderAvatarMaxART_ns << LL_ENDL;
         }
-        else if( LLPerfStats::raw_to_ns(target_frame_time_raw) > (LLPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns) )
+        else if(( LLPerfStats::raw_to_ns(target_frame_time_raw) > (LLPerfStats::raw_to_ns(tot_frame_time_raw) + renderAvatarMaxART_ns) ) ||
+                 (tunables.vsyncEnabled && (target_fps == LLPerfStats::vsync_max_fps) && (target_frame_time_raw > getMeanTotalFrameTime())))
         {
             if(belowTargetFPS == true)
             {
-- 
cgit v1.2.3


From 918efa36112a6cbaacb54a2eb9a43af859a09005 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Tue, 24 Jan 2023 20:06:21 +0200
Subject: SL-16683 Updated mac 'Low' preset to match Windows

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

(limited to 'indra/newview')

diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 28e4462c39..1281b77e45 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -93,7 +93,7 @@ RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
 RenderTransparentWater		1	0
 RenderTreeLODFactor			1	0
-RenderVolumeLODFactor		1	0.5
+RenderVolumeLODFactor		1	1.125
 WindLightUseAtmosShaders	1	0
 RenderDeferred				1	0
 RenderDeferredSSAO			1	0
-- 
cgit v1.2.3


From c43336d5ed211ab77f2dc12b6cb7442d7544a2f7 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Fri, 27 Jan 2023 01:33:11 +0200
Subject: SL-18930 Update Autotune panel

---
 indra/newview/app_settings/settings.xml            |  13 +-
 indra/newview/llfloaterperformance.cpp             |  38 ++++-
 indra/newview/llfloaterperformance.h               |   7 +
 indra/newview/llfloaterpreference.cpp              |   1 +
 indra/newview/llperfstats.cpp                      |  17 +-
 indra/newview/llstartup.cpp                        |   2 +
 indra/newview/llviewercontrol.cpp                  |  19 ++-
 .../xui/en/panel_performance_autoadjustments.xml   | 175 ++++++++++++++-------
 8 files changed, 203 insertions(+), 69 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index b220e2a8f5..569a838176 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16775,6 +16775,17 @@
     <key>Type</key>
     <string>Boolean</string>
     <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>KeepAutoTuneLock</key>
+  <map>
+    <key>Comment</key>
+    <string>When enabled the AutoTuneLock will be maintainted all following sessions.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
     <integer>1</integer>
   </map>
   <key>AllowSelfImpostor</key>
@@ -16885,7 +16896,7 @@
     <key>Type</key>
     <string>U32</string>
     <key>Value</key>
-    <integer>0</integer>
+    <integer>1</integer>
   </map>
   <key>CameraOpacity</key>
   <map>
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 88319b170f..ba45648bd9 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -148,6 +148,15 @@ BOOL LLFloaterPerformance::postBuild()
         gSavedSettings.setF32("AutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip);
     }
 
+    LLStringExplicit fps_limit(llformat("%d", gViewerWindow->getWindow()->getRefreshRate()));
+    mAutoadjustmentsPanel->getChild<LLTextBox>("vsync_desc_limit")->setTextArg("[FPS_LIMIT]", fps_limit);
+    mAutoadjustmentsPanel->getChild<LLTextBox>("display_desc")->setTextArg("[FPS_LIMIT]", fps_limit);
+
+    mStartAutotuneBtn = mAutoadjustmentsPanel->getChild<LLButton>("start_autotune");
+    mStopAutotuneBtn = mAutoadjustmentsPanel->getChild<LLButton>("stop_autotune");
+    mStartAutotuneBtn->setCommitCallback(boost::bind(&LLFloaterPerformance::startAutotune, this));
+    mStopAutotuneBtn->setCommitCallback(boost::bind(&LLFloaterPerformance::stopAutotune, this));
+
     return TRUE;
 }
 
@@ -195,14 +204,10 @@ void LLFloaterPerformance::draw()
             populateObjectList();
         }
 
-        auto button = getChild<LLButton>("AutoTuneFPS");
-        if((bool)button->getToggleState() != LLPerfStats::tunables.userAutoTuneEnabled)
-        {
-            button->toggleState();
-        }
-
         mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL);
     }
+    updateAutotuneCtrls(LLPerfStats::tunables.userAutoTuneEnabled);
+
     LLFloater::draw();
 }
 
@@ -645,4 +650,25 @@ void LLFloaterPerformance::onClickShadows()
     }
 
 }
+
+void LLFloaterPerformance::startAutotune()
+{
+    LLPerfStats::tunables.userAutoTuneEnabled = true;
+}
+
+void LLFloaterPerformance::stopAutotune()
+{
+    LLPerfStats::tunables.userAutoTuneEnabled = false;
+}
+
+void LLFloaterPerformance::updateAutotuneCtrls(bool autotune_enabled)
+{
+    static LLCachedControl<bool> auto_tune_locked(gSavedSettings, "AutoTuneLock");
+    mStartAutotuneBtn->setEnabled(!autotune_enabled && !auto_tune_locked);
+    mStopAutotuneBtn->setEnabled(autotune_enabled && !auto_tune_locked);
+    getChild<LLCheckBoxCtrl>("AutoTuneContinuous")->setEnabled(!autotune_enabled || (autotune_enabled && auto_tune_locked));
+
+    getChild<LLTextBox>("wip_desc")->setVisible(autotune_enabled && !auto_tune_locked);
+    getChild<LLTextBox>("display_desc")->setVisible(LLPerfStats::tunables.vsyncEnabled);
+}
 // EOF
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 6a72f3d7c5..648e5902b6 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -68,6 +68,10 @@ private:
     void onClickShadows();
     void onClickAdvancedLighting();
 
+    void startAutotune();
+    void stopAutotune();
+    void updateAutotuneCtrls(bool autotune_enabled);
+
     void updateMaxRenderTime();
 
     static void changeQualityLevel(const std::string& notif);
@@ -82,6 +86,9 @@ private:
     LLNameListCtrl* mObjectList;
     LLNameListCtrl* mNearbyList;
 
+    LLButton* mStartAutotuneBtn;
+    LLButton* mStopAutotuneBtn;
+
     LLListContextMenu* mContextMenu;
 
     LLTimer* mUpdateTimer;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 531270f936..9476a0f6a3 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -825,6 +825,7 @@ void LLFloaterPreference::resetAutotuneSettings()
 
     const std::string autotune_settings[] = {
         "AutoTuneLock",
+        "KeepAutoTuneLock",
         "TargetFPS",
         "TuningFPSStrategy",
         "AutoTuneImpostorByDistEnabled",
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index cb5c674a32..959e0afbdf 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -123,8 +123,21 @@ namespace LLPerfStats
         LLPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("TargetFPS");
         LLPerfStats::tunables.vsyncEnabled = gSavedSettings.getBOOL("RenderVSyncEnable");
         LLPerfStats::tunables.userTargetReflections = gSavedSettings.getS32("UserTargetReflections");
-        LLPerfStats::tunables.userAutoTuneEnabled = gSavedSettings.getBOOL("AutoTuneFPS");
-        LLPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("AutoTuneLock");
+
+        LLPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("AutoTuneLock") && gSavedSettings.getU32("KeepAutoTuneLock");
+
+        if(gSavedSettings.getBOOL("AutoTuneLock") && !gSavedSettings.getU32("KeepAutoTuneLock"))
+        {
+            gSavedSettings.setBOOL("AutoTuneLock", FALSE);
+        }
+
+        LLPerfStats::tunables.userAutoTuneEnabled = LLPerfStats::tunables.userAutoTuneLock;
+
+        if (LLPerfStats::tunables.userAutoTuneEnabled && !gSavedSettings.getBOOL("AutoTuneFPS"))
+        {
+            gSavedSettings.setBOOL("AutoTuneFPS", TRUE);
+        }
+
         // Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value
         updateRenderCostLimitFromSettings();
         resetChanges();
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 83ab8ee7e8..26c4f1b639 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2262,6 +2262,8 @@ bool idle_startup()
 	{
         if (gAgent.isFirstLogin())
         {
+            gSavedSettings.setBOOL("AutoTuneLock", TRUE);
+            gSavedSettings.setBOOL("KeepAutoTuneLock", TRUE);
             gSavedSettings.setBOOL("AutoTuneFPS", TRUE);
         }
         set_startup_status(1.0, "", "");
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 0bade93c45..50d48987ed 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -270,6 +270,12 @@ static bool handleVSyncChanged(const LLSD& newvalue)
     LLPerfStats::tunables.vsyncEnabled = newvalue.asBoolean();
     gViewerWindow->getWindow()->toggleVSync(newvalue.asBoolean());
 
+    if(newvalue.asBoolean() == true)
+    {
+        U32 current_target = gSavedSettings.getU32("TargetFPS");
+        gSavedSettings.setU32("TargetFPS", std::min((U32)gViewerWindow->getWindow()->getRefreshRate(), current_target));
+    }
+
     return true;
 }
 
@@ -649,13 +655,24 @@ void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);
 void handleTargetFPSChanged(const LLSD& newValue)
 {
     const auto targetFPS = gSavedSettings.getU32("TargetFPS");
-    LLPerfStats::tunables.userTargetFPS = targetFPS;
+
+    U32 frame_rate_limit = gViewerWindow->getWindow()->getRefreshRate();
+    if(LLPerfStats::tunables.vsyncEnabled && (targetFPS > frame_rate_limit))
+    {
+        gSavedSettings.setU32("TargetFPS", std::min(frame_rate_limit, targetFPS));
+    }
+    else
+    {
+        LLPerfStats::tunables.userTargetFPS = targetFPS;
+    }
 }
 
 void handleAutoTuneLockChanged(const LLSD& newValue)
 {
     const auto newval = gSavedSettings.getBOOL("AutoTuneLock");
     LLPerfStats::tunables.userAutoTuneLock = newval;
+
+    gSavedSettings.setBOOL("AutoTuneFPS", newval);
 }
 
 void handleAutoTuneFPSChanged(const LLSD& newValue)
diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
index ab7b4d3ee7..24611c94d6 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
@@ -63,7 +63,7 @@
    left="20"
    name="targetfps_desc"
    wrap="true"
-   width="140"
+   width="115"
    top_pad="20">
     Desired frame rate
   </text>
@@ -73,8 +73,8 @@
    font="SansSerifLarge"
    tool_tip="The viewer will attempt to achieve this by adjusting your graphics settings."
    layout="topleft"
-   follows="right|top"
-   left_pad="5"
+   follows="left|top"
+   left_pad="25"
    top_delta="0"
    height="25"
    visible="true"
@@ -85,41 +85,18 @@
    min_val="1"
    width="48"
    label_width="0" />
-  <button
-   control_name="AutoTuneFPS"
-   follows="top|right"
-   height="24"
-   initial_value="false"
-   image_pressed="PushButton_Press"
-   image_pressed_selected="PushButton_Selected_Press"
-   image_selected="PushButton_Selected_Press"
-   is_toggle="true"
-   label="Start"
-   label_selected="Stop"
-   layout="topleft"
-   left_pad="10"
-   name="AutoTuneFPS"
-   top_delta="-1"
-   tool_tip="The viewer will attempt to adjust settings to meet the target FPS."
-   width="72">
-  </button>
-  <check_box
-   control_name="AutoTuneLock"
-   follows="top|right"
+ <text
+   follows="left|top"
+   text_color="White"
    height="20"
-   initial_value="true"
-   image_pressed="PushButton_Press"
-   image_pressed_selected="PushButton_Selected_Press"
-   image_selected="PushButton_Selected_Press"
-   is_toggle="true"
-   label="Continuous"
    layout="topleft"
-   left_pad="10"
-   name="AutoTuneContinuous"
-   top_delta="0"
-   tool_tip="The viewer will continually adapt the settings to meet the target FPS until stopped even with the floater closed. When disabled clicking the Start button will adjust for the current settings then stop."
-   width="64">
-  </check_box>
+   name="display_desc"
+   top_delta="5"
+   left_pad="15"
+   wrap="true"
+   width="225">
+  Your display supports up to [FPS_LIMIT] fps.
+  </text>
   <text
    follows="left|top"
    font="SansSerif"
@@ -128,9 +105,9 @@
    layout="topleft"
    left="20"
    name="settings_desc"
-   top_pad="20"
+   top_pad="15"
    wrap="true"
-   width="150">
+   width="115">
     Settings affect
   </text>
   <combo_box
@@ -138,27 +115,118 @@
    font="SansSerif"
    height="20"
    layout="topleft"
-   left_pad="15"
+   left_pad="25"
    control_name="TuningFPSStrategy"
    name="TuningFPSStrategy"
-   width="130">
+   width="160">
     <combo_box.item
      label="Avatars Only"
      name="av_only"
      value="0" />
     <combo_box.item
-     label="Avatars and Scene"
+     label="Avatars and World"
      name="av_and_scene"
      value="1" />
   </combo_box>
+  <button
+   follows="top|left"
+   height="22"
+   image_pressed="PushButton_Press"
+   image_pressed_selected="PushButton_Selected_Press"
+   image_selected="PushButton_Selected_Press"
+   label="Auto-adjust now"
+   layout="topleft"
+   top_pad="15"
+   left="20"
+   name="start_autotune"
+   tool_tip="The viewer will attempt to adjust settings to meet the target FPS then stop."
+   width="124"/>
+  <button
+   follows="top|left"
+   height="22"
+   image_pressed="PushButton_Press"
+   image_pressed_selected="PushButton_Selected_Press"
+   image_selected="PushButton_Selected_Press"
+   label="Cancel"
+   layout="topleft"
+   left_pad="15"
+   name="stop_autotune"
+   tool_tip="Stop adjusting settings."
+   width="90"/>
+  <text
+   follows="left|top"
+   text_color="Yellow"
+   height="20"
+   layout="topleft"
+   name="wip_desc"
+   top_delta="5"
+   left_pad="20"
+   wrap="true"
+   width="115">
+  Working on it...
+  </text>
+  <check_box
+   control_name="AutoTuneLock"
+   follows="top|left"
+   height="20"
+   initial_value="true"
+   image_pressed="PushButton_Press"
+   image_pressed_selected="PushButton_Selected_Press"
+   image_selected="PushButton_Selected_Press"
+   is_toggle="true"
+   label="Adjust continuously"
+   layout="topleft"
+   left="17"
+   top_pad="10"
+   name="AutoTuneContinuous"
+   tool_tip="The viewer will continually adapt the settings to meet the target FPS until stopped even with the floater closed."
+   width="64">
+  </check_box>
+  <radio_group
+   control_name="KeepAutoTuneLock"
+   enabled_control="AutoTuneLock"
+   height="50"
+   layout="topleft"
+   follows="top|left"
+   name="autotune_lock_type"
+   top_pad="5"
+   left_delta="15"
+   width="120">
+    <radio_item
+     height="16"
+     label="This login session only"
+     layout="topleft"
+     name="one_session_lock"
+     value="0"
+     width="120" />
+    <radio_item
+     height="16"
+     label="Future login sessions"
+     layout="topleft"
+     name="next_session_lock"
+     value="1"
+     width="120" />
+  </radio_group>
   <view_border
    bevel_style="in"
    height="0"
    layout="topleft"
    name="border_vsync"
-   top_pad="20"
+   top_pad="3"
    left="20"
    width="540"/>
+  <check_box
+   control_name="RenderVSyncEnable"
+   height="16"
+   left="17"
+   initial_value="true"
+   label="Enable VSync"
+   label_text.text_color="White"
+   layout="topleft"
+   top_pad="12"
+   name="vsync"
+   tool_tip="Enable Vertical synchronization to reduce screen tearing and stuttering."
+   width="315" />
   <text
    follows="left|top"
    font="SansSerifSmall"
@@ -166,10 +234,10 @@
    height="18"
    layout="topleft"
    left="20"
-   top_pad="20"
+   top_pad="15"
    name="vsync_desc"
    width="580">
-    Synchronize the refresh rate and frame rate of a monitor,
+    Matches monitor refresh rate with frame rate.
   </text>
   <text
    follows="left|top"
@@ -179,27 +247,16 @@
    layout="topleft"
    top_pad="3"
    left="20"
-   name="vsync_desc2"
+   name="vsync_desc_limit"
    width="580">
-    which can result in smoother performance.
+    Note: Turning on VSync limits frame rate to [FPS_LIMIT] fps.
   </text>
-  <check_box
-   control_name="RenderVSyncEnable"
-   height="16"
-   initial_value="true"
-   label="Enable VSync"
-   label_text.text_color="White"
-   layout="topleft"
-   top_pad="15"
-   name="vsync"
-   tool_tip="Enable Vertical synchronization to reduce screen tearing and stuttering."
-   width="315" />
   <view_border
    bevel_style="in"
    height="0"
    layout="topleft"
    name="border1"
-   top_pad="20"
+   top_pad="10"
    left="20"
    width="540"/>
   <text
@@ -263,7 +320,7 @@
    height="18"
    layout="topleft"
    left="20"
-   top_pad="20"
+   top_pad="15"
    name="dist_limits_desc"
    width="580">
     Choose the distance range that automatic settings will affect.
-- 
cgit v1.2.3


From 0169e8cc976bd261a1d02d248eeed21a3e607201 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Thu, 2 Feb 2023 13:43:11 +0200
Subject: SL-19126 Add a button to Graphics Presets fly-out to open Auto adjust
 settings

---
 indra/newview/llpanelpresetspulldown.cpp                  | 12 ++++++++++++
 indra/newview/llpanelpresetspulldown.h                    |  1 +
 .../skins/default/xui/en/panel_presets_pulldown.xml       | 15 +++++++++++++--
 3 files changed, 26 insertions(+), 2 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp
index 23e4fa8887..f6e501f147 100644
--- a/indra/newview/llpanelpresetspulldown.cpp
+++ b/indra/newview/llpanelpresetspulldown.cpp
@@ -34,6 +34,7 @@
 #include "llbutton.h"
 #include "lltabcontainer.h"
 #include "llfloater.h"
+#include "llfloaterperformance.h"
 #include "llfloaterreg.h"
 #include "llpresetsmanager.h"
 #include "llsliderctrl.h"
@@ -50,6 +51,7 @@ LLPanelPresetsPulldown::LLPanelPresetsPulldown()
 	mHoverTimer.stop();
 
 	mCommitCallbackRegistrar.add("Presets.GoGraphicsPrefs", boost::bind(&LLPanelPresetsPulldown::onGraphicsButtonClick, this, _2));
+    mCommitCallbackRegistrar.add("Presets.GoAutofpsPrefs", boost::bind(&LLPanelPresetsPulldown::onAutofpsButtonClick, this, _2));
 	mCommitCallbackRegistrar.add("Presets.RowClick", boost::bind(&LLPanelPresetsPulldown::onRowClick, this, _2));
 
 	buildFromFile( "panel_presets_pulldown.xml");
@@ -157,3 +159,13 @@ void LLPanelPresetsPulldown::onGraphicsButtonClick(const LLSD& user_data)
 		}
 	}
 }
+
+void LLPanelPresetsPulldown::onAutofpsButtonClick(const LLSD& user_data)
+{
+    setVisible(FALSE);
+    LLFloaterPerformance* performance_floater = LLFloaterReg::showTypedInstance<LLFloaterPerformance>("performance");
+    if (performance_floater)
+    {
+        performance_floater->showAutoadjustmentsPanel();
+    }
+}
diff --git a/indra/newview/llpanelpresetspulldown.h b/indra/newview/llpanelpresetspulldown.h
index c0d32b9b21..79bd6886b1 100644
--- a/indra/newview/llpanelpresetspulldown.h
+++ b/indra/newview/llpanelpresetspulldown.h
@@ -41,6 +41,7 @@ class LLPanelPresetsPulldown : public LLPanelPulldown
 	
  private:
 	void onGraphicsButtonClick(const LLSD& user_data);
+    void onAutofpsButtonClick(const LLSD& user_data);
 	void onRowClick(const LLSD& user_data);
 
 	std::list<std::string> mPresetNames;
diff --git a/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml b/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml
index b87dda2315..b3d165c4fd 100644
--- a/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml
+++ b/indra/newview/skins/default/xui/en/panel_presets_pulldown.xml
@@ -8,7 +8,7 @@
  border="false"
  chrome="true"
  follows="bottom"
- height="155"
+ height="185"
  layout="topleft"
  name="presets_pulldown"
  width="225">
@@ -57,7 +57,7 @@
     width="215" />
   <button
     name="open_prefs_btn"
-    label="Open Graphics Preferences"
+    label="Graphics Preferences"
     tool_tip = "Bring up graphics prefs"
     top_delta="5"
     left="15"
@@ -66,4 +66,15 @@
     <button.commit_callback
       function="Presets.GoGraphicsPrefs" />
   </button>
+  <button
+    name="open_autofps_btn"
+    label="Auto-FPS settings"
+    tool_tip = "Bring up auto-adjust settings"
+    top_pad="5"
+    left="15"
+    height="20"
+    width="200">
+    <button.commit_callback
+     function="Presets.GoAutofpsPrefs" />
+  </button>
 </panel>
-- 
cgit v1.2.3


From 788ba76bdf5dcc0a018a6b53bc1cc8f359e85f34 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Thu, 2 Feb 2023 16:17:09 +0200
Subject: SL-19094 Move Desired frame rate button to top level

---
 indra/newview/llfloaterperformance.cpp             |  1 +
 .../skins/default/xui/en/floater_performance.xml   | 95 +++++++++++-----------
 .../xui/en/panel_performance_autoadjustments.xml   | 11 ++-
 3 files changed, 59 insertions(+), 48 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index ba45648bd9..5eb58b9482 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -151,6 +151,7 @@ BOOL LLFloaterPerformance::postBuild()
     LLStringExplicit fps_limit(llformat("%d", gViewerWindow->getWindow()->getRefreshRate()));
     mAutoadjustmentsPanel->getChild<LLTextBox>("vsync_desc_limit")->setTextArg("[FPS_LIMIT]", fps_limit);
     mAutoadjustmentsPanel->getChild<LLTextBox>("display_desc")->setTextArg("[FPS_LIMIT]", fps_limit);
+    mAutoadjustmentsPanel->getChild<LLButton>("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickDefaults, this));
 
     mStartAutotuneBtn = mAutoadjustmentsPanel->getChild<LLButton>("start_autotune");
     mStopAutotuneBtn = mAutoadjustmentsPanel->getChild<LLButton>("stop_autotune");
diff --git a/indra/newview/skins/default/xui/en/floater_performance.xml b/indra/newview/skins/default/xui/en/floater_performance.xml
index ee88701037..d1a1119f77 100644
--- a/indra/newview/skins/default/xui/en/floater_performance.xml
+++ b/indra/newview/skins/default/xui/en/floater_performance.xml
@@ -4,6 +4,7 @@
  layout="topleft"
  name="performance"
  save_rect="true"
+ reuse_instance="true"
  title="IMPROVE GRAPHICS SPEED"
  width="580">
   <string
@@ -101,10 +102,56 @@
      follows="left|top"
      height="50"
      width="560"
-     name="settings_subpanel"
+     name="autoadjustments_subpanel"
      layout="topleft"
      left="10"
      top="5">
+        <text
+         follows="left|top"
+         font="SansSerifBoldLarge"
+         text_color="White"
+         height="20"
+         layout="topleft"
+         left="10"
+         name="auto_adj_lbl"
+         top="7"
+         width="375">
+         Auto-adjust settings (recommended)
+        </text>
+        <text
+         follows="left|top"
+         font="SansSerif"
+         text_color="White"
+         height="20"
+         layout="topleft"
+         left="10"
+         name="auto_adj_desc"
+         top_pad="0"
+         width="485">
+         Allow automatic adjustments to reach your preferred frame rate.
+        </text>
+        <icon
+         height="16"
+         width="16"
+         image_name="Arrow_Right_Off"
+         mouse_opaque="true"
+         name="icon_arrow4"
+         follows="right|top"
+         top="19"
+         right="-20"/>
+    </panel>
+    <panel
+     bg_alpha_color="PanelGray"
+     background_visible="true"
+     background_opaque="false"
+     border="true"
+     bevel_style="none"
+     follows="left|top"
+     height="50"
+     width="560"
+     name="settings_subpanel"
+     layout="topleft"
+     top_pad="10">
         <text
          follows="left|top"
          font="SansSerifLarge"
@@ -277,52 +324,6 @@
        top="19"
        right="-20"/>
     </panel>
-    <panel
-     bg_alpha_color="PanelGray"
-     background_visible="true"
-     background_opaque="false"
-     border="true"
-     bevel_style="none"
-     follows="left|top"
-     height="50"
-     width="560"
-     name="autoadjustments_subpanel"
-     layout="topleft"
-     top_pad="10">
-      <text
-       follows="left|top"
-       font="SansSerifLarge"
-       text_color="White"
-       height="20"
-       layout="topleft"
-       left="10"
-       name="auto_adj_lbl"
-       top="7"
-       width="175">
-        Preferred frame rate
-      </text>
-      <text
-       follows="left|top"
-       font="SansSerif"
-       text_color="White"
-       height="20"
-       layout="topleft"
-       left="10"
-       name="auto_adj_desc"
-       top_pad="0"
-       width="485">
-        Allow automatic adjustments to reach your preferred frame rate (advanced).
-      </text>
-      <icon
-       height="16"
-       width="16"
-       image_name="Arrow_Right_Off"
-       mouse_opaque="true"
-       name="icon_arrow4"
-       follows="right|top"
-       top="19"
-       right="-20"/>
-    </panel>
   </panel>
   <panel
     filename="panel_performance_nearby.xml"
diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
index 24611c94d6..c76d39201d 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
@@ -44,8 +44,17 @@
    top_pad="15"
    name="settings_title"
    width="300">
-    Preferred frame rate
+    Auto-adjust settings
   </text>
+  <button
+   follows="top|left"
+   height="23"
+   label="Reset to recommended settings"
+   layout="topleft"
+   left="360"
+   name="defaults_btn"
+   top_delta="0"
+   width="200"/>
   <view_border
    bevel_style="in"
    height="0"
-- 
cgit v1.2.3


From d6002da559bac486524491d72589ae03a947922e Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Sat, 5 Nov 2022 01:02:58 +0200
Subject: SL-18581 Don't show the starter avatar toolbar button for NUX

---
 indra/newview/lltoolbarview.cpp | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

(limited to 'indra/newview')

diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 01d799dcd5..752fc6f3f3 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -44,6 +44,7 @@
 #include "llagent.h"  // HACK for destinations guide on startup
 #include "llfloaterreg.h"  // HACK for destinations guide on startup
 #include "llviewercontrol.h"  // HACK for destinations guide on startup
+#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX
 
 #include <boost/foreach.hpp>
 
@@ -319,6 +320,22 @@ bool LLToolBarView::loadToolbars(bool force_default)
 			}
 		}
 	}
+
+    // SL-18581: Don't show the starter avatar toolbar button for NUX users
+    LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS));
+    if (gAgent.isFirstLogin()
+        && my_outfits_cat != NULL
+        && my_outfits_cat->getDescendentCount() > 0)
+    {
+        for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
+        {
+            if (mToolbars[i])
+            {
+                mToolbars[i]->removeCommand(LLCommandId("avatar"));
+            }
+        }
+    }
+
 	mToolbarsLoaded = true;
 	return true;
 }
-- 
cgit v1.2.3


From e1661fdcda074cfc9ef465c2c8cc729e9b894815 Mon Sep 17 00:00:00 2001
From: Maxim Nikolenko <maximnproductengine@lindenlab.com>
Date: Wed, 8 Feb 2023 01:39:56 +0200
Subject: SL-19160 Enable ALM ctrl when Atmospheric shaders are used

---
 indra/newview/llfloaterpreference.cpp | 17 +++++++++++++++++
 indra/newview/llfloaterpreference.h   |  2 ++
 2 files changed, 19 insertions(+)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 9476a0f6a3..9ea49e935f 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -317,6 +317,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));
 
 	gSavedSettings.getControl("AppearanceCameraMovement")->getCommitSignal()->connect(boost::bind(&handleAppearanceCameraMovementChanged,  _2));
+    gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::onAtmosShaderChange, this));
 
 	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
 
@@ -1729,6 +1730,22 @@ void LLFloaterPreference::onClickActionChange()
     updateClickActionControls();
 }
 
+void LLFloaterPreference::onAtmosShaderChange()
+{
+    LLCheckBoxCtrl* ctrl_alm = getChild<LLCheckBoxCtrl>("UseLightShaders");
+    if(ctrl_alm)
+    {
+        //Deferred/SSAO/Shadows
+        BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
+        BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+        BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+                        bumpshiny &&
+                        shaders;
+
+        ctrl_alm->setEnabled(enabled);
+    }
+}
+
 void LLFloaterPreference::onClickPermsDefault()
 {
 	LLFloaterReg::showInstance("perms_default");
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 2aa6ca87b7..6b23c4d4cd 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -139,6 +139,8 @@ protected:
 	// updates click/double-click action keybindngs depending on view values
 	void updateClickActionControls();
 
+    void onAtmosShaderChange();
+
 public:
 	// This function squirrels away the current values of the controls so that
 	// cancel() can restore them.	
-- 
cgit v1.2.3


From 53ebcc0ff3ee49f7e4b1a5faa71aaf32dafe23e5 Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Tue, 14 Feb 2023 01:30:22 +0200
Subject: SL-18581 Add more logging

---
 indra/newview/lltoolbarview.cpp | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 752fc6f3f3..4f47c465c4 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -323,15 +323,18 @@ bool LLToolBarView::loadToolbars(bool force_default)
 
     // SL-18581: Don't show the starter avatar toolbar button for NUX users
     LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS));
-    if (gAgent.isFirstLogin()
-        && my_outfits_cat != NULL
-        && my_outfits_cat->getDescendentCount() > 0)
+    if (gAgent.isFirstLogin())
     {
-        for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
+        LL_WARNS() << "First login: checking for NUX user." << LL_ENDL;
+        if (my_outfits_cat != NULL && my_outfits_cat->getDescendentCount() > 0)
         {
-            if (mToolbars[i])
+            LL_WARNS() << "First login: My Outfits folder is not empty, removing the avatar picker button." << LL_ENDL;
+            for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++)
             {
-                mToolbars[i]->removeCommand(LLCommandId("avatar"));
+                if (mToolbars[i])
+                {
+                    mToolbars[i]->removeCommand(LLCommandId("avatar"));
+                }
             }
         }
     }
-- 
cgit v1.2.3


From c582f67987a1e8fe9a00e733a8668defbf4dba55 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 27 Feb 2023 23:56:37 +0200
Subject: SL-19280 disable autofps for new users by default

---
 indra/newview/llstartup.cpp | 6 ------
 1 file changed, 6 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 82372e4732..bcb57d2237 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2258,12 +2258,6 @@ bool idle_startup()
 
 	if (STATE_CLEANUP == LLStartUp::getStartupState())
 	{
-        if (gAgent.isFirstLogin())
-        {
-            gSavedSettings.setBOOL("AutoTuneLock", TRUE);
-            gSavedSettings.setBOOL("KeepAutoTuneLock", TRUE);
-            gSavedSettings.setBOOL("AutoTuneFPS", TRUE);
-        }
         set_startup_status(1.0, "", "");
 		display_startup();
 
-- 
cgit v1.2.3


From 7298a049a7e45f3cf2e78fa0aabc4c52ad6b2187 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Thu, 2 Mar 2023 18:00:11 +0200
Subject: SL-19317 fix for avatar attachment accounting

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

(limited to 'indra/newview')

diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 3f15385ba3..51925b4129 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -5437,7 +5437,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 			}
 		}
 		
-		if (type == LLRenderPass::PASS_ALPHA)
+		// if (type == LLRenderPass::PASS_ALPHA) // always populate the draw_info ptr
 		{ //for alpha sorting
 			facep->setDrawInfo(draw_info);
 		}
-- 
cgit v1.2.3


From 464c2b393e5aa940cbba079c976a65961de08bf9 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Sun, 19 Mar 2023 21:02:46 +0200
Subject: SL-19424 Set default auto FPS to 15

---
 indra/newview/app_settings/settings.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 615f72f7b6..97bd60277a 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16753,7 +16753,7 @@
     <key>Type</key>
     <string>U32</string>
     <key>Value</key>
-    <integer>30</integer>
+    <integer>15</integer>
   </map>
   <key>AutoTuneFPS</key>
   <map>
-- 
cgit v1.2.3


From 5b7137f9aa75061fa21ad5def4af8ef673842486 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Sun, 19 Mar 2023 22:07:17 +0200
Subject: SL-19425 add third option to Settings affect: World Only

---
 indra/newview/app_settings/settings.xml                           | 2 +-
 indra/newview/llperfstats.cpp                                     | 8 ++++----
 indra/newview/llperfstats.h                                       | 1 +
 .../skins/default/xui/en/panel_performance_autoadjustments.xml    | 4 ++++
 4 files changed, 10 insertions(+), 5 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 97bd60277a..9fffab70f4 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16890,7 +16890,7 @@
   <key>TuningFPSStrategy</key>
   <map>
     <key>Comment</key>
-    <string>Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings.</string>
+    <string>Strategy to use when tuning FPS. 0=Tune avatar rendering only, 1=Tune both avatar and global scene settings, 2=Tune only global scene.</string>
     <key>Persist</key>
     <integer>1</integer>
     <key>Type</key>
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 959e0afbdf..7ff363c3c1 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -439,7 +439,7 @@ namespace LLPerfStats
                 // we cannnot do this by avatar adjustment alone.
                 if((gFrameCount - LLPerfStats::lastGlobalPrefChange) > settingsChangeFrequency) // give  changes a short time to take effect.
                 {
-                    if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS)
+                    if(tunables.userFPSTuningStrategy != TUNE_AVATARS_ONLY)
                     {
                         // 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit.
                         // the other reflection options make comparatively little change and if this overshoots we'll be stepping back up later
@@ -477,7 +477,7 @@ namespace LLPerfStats
                 target_avatar_time_raw =  target_frame_time_raw - non_avatar_time_raw;
             }
 
-            if( target_avatar_time_raw < tot_avatar_time_raw )
+            if ((target_avatar_time_raw < tot_avatar_time_raw) && (tunables.userFPSTuningStrategy != TUNE_SCENE_ONLY))
             {
                 // we need to spend less time drawing avatars to meet our budget
                 auto new_render_limit_ns {LLPerfStats::raw_to_ns(av_render_max_raw)};
@@ -520,7 +520,7 @@ namespace LLPerfStats
                     // turn off if we are not locked.
                     tunables.updateUserAutoTuneEnabled(false);
                 }
-                if(renderAvatarMaxART_ns != 0 && LLPerfStats::tunedAvatars > 0 )
+                if(renderAvatarMaxART_ns != 0 && LLPerfStats::tunedAvatars > 0 && (tunables.userFPSTuningStrategy != TUNE_SCENE_ONLY) )
                 {
                     // if we have more time to spare let's shift up little in the hope we'll restore an avatar.
                     U64 up_step = LLPerfStats::tunedAvatars > 2 ? LLPerfStats::ART_MIN_ADJUST_UP_NANOS : LLPerfStats::ART_MIN_ADJUST_UP_NANOS * 2;
@@ -528,7 +528,7 @@ namespace LLPerfStats
                     tunables.updateSettingsFromRenderCostLimit();
                     return;
                 }
-                if(tunables.userFPSTuningStrategy == TUNE_SCENE_AND_AVATARS)
+                if(tunables.userFPSTuningStrategy != TUNE_AVATARS_ONLY)
                 {
                     if( LLPipeline::RenderFarClip < tunables.userTargetDrawDistance ) 
                     {
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index 200ff1f248..48ac483ce7 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -54,6 +54,7 @@ namespace LLPerfStats
 
     static constexpr U32 TUNE_AVATARS_ONLY{0};
     static constexpr U32 TUNE_SCENE_AND_AVATARS{1};
+    static constexpr U32 TUNE_SCENE_ONLY{2};
 
     extern F64 cpu_hertz;
 
diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
index c76d39201d..56b032d683 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
@@ -136,6 +136,10 @@
      label="Avatars and World"
      name="av_and_scene"
      value="1" />
+	<combo_box.item
+     label="World only"
+     name="scene_only"
+     value="2" />
   </combo_box>
   <button
    follows="top|left"
-- 
cgit v1.2.3


From 87ecafd7b4b2d6f33c54547e561b0594ae742f8a Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Mon, 20 Mar 2023 20:08:40 +0200
Subject: SL-19426 AutoFPS - when enabled always render at least 5 avatars

---
 indra/newview/llvoavatar.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++--
 indra/newview/llvoavatar.h   |  5 +++
 2 files changed, 93 insertions(+), 3 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index dbfd47d2fa..772abfc6a1 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -207,6 +207,8 @@ const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024;
 
 const F32 MAX_TEXTURE_WAIT_TIME_SEC = 60;
 
+const S32 MIN_NONTUNED_AVS = 5;
+
 enum ERenderName
 {
 	RENDER_NAME_NEVER,
@@ -618,6 +620,8 @@ F32 LLVOAvatar::sUnbakedUpdateTime = 0.f;
 F32 LLVOAvatar::sGreyTime = 0.f;
 F32 LLVOAvatar::sGreyUpdateTime = 0.f;
 LLPointer<LLViewerTexture> LLVOAvatar::sCloudTexture = NULL;
+std::vector<LLUUID> LLVOAvatar::sAVsIgnoringARTLimit;
+S32 LLVOAvatar::sAvatarsNearby = 0;
 
 //-----------------------------------------------------------------------------
 // Helper functions
@@ -821,6 +825,8 @@ LLVOAvatar::~LLVOAvatar()
         LLPerfStats::tunedAvatars--;
         mTuned = false;
     }
+    sAVsIgnoringARTLimit.erase(std::remove(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID), sAVsIgnoringARTLimit.end());
+
 
 	logPendingPhases();
 	
@@ -8359,8 +8365,24 @@ void LLVOAvatar::updateTooSlow()
         render_time_raw = mRenderTime;
         render_geom_time_raw = mGeomTime;		
     }
-    if( (LLPerfStats::renderAvatarMaxART_ns > 0) && 
-        (LLPerfStats::raw_to_ns(render_time_raw) >= LLPerfStats::renderAvatarMaxART_ns) ) 
+
+	bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
+
+	bool ignore_tune = false;
+    if (autotune && sAVsIgnoringARTLimit.size() > 0)
+    {
+        auto it = std::find(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID);
+        if (it != sAVsIgnoringARTLimit.end())
+        {
+            S32 index = it - sAVsIgnoringARTLimit.begin();
+            ignore_tune = (index < (MIN_NONTUNED_AVS - sAvatarsNearby + 1 + LLPerfStats::tunedAvatars));
+        }
+    }
+
+	bool exceeds_max_ART =
+        ((LLPerfStats::renderAvatarMaxART_ns > 0) && (LLPerfStats::raw_to_ns(render_time_raw) >= LLPerfStats::renderAvatarMaxART_ns));
+
+    if (exceeds_max_ART && !ignore_tune)
     {
         if( !mTooSlow ) // if we were previously not slow (with or without shadows.)
         {			
@@ -8386,7 +8408,12 @@ void LLVOAvatar::updateTooSlow()
     {
         // LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") good render time = " << LLPerfStats::raw_to_ns(render_time_raw) << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL;
         mTooSlow = false;
-        mTooSlowWithoutShadows = false;	
+        mTooSlowWithoutShadows = false;
+
+		if (ignore_tune)
+		{
+            return;
+		}
     }
     if(mTooSlow && !mTuned)
     {
@@ -10661,6 +10688,64 @@ void LLVOAvatar::idleUpdateRenderComplexity()
 
     // Render Complexity
     calculateUpdateRenderComplexity(); // Update mVisualComplexity if needed	
+
+	bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
+    if (autotune && !isDead())
+    {
+        static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
+        F32 radius = render_far_clip * render_far_clip;
+
+        bool is_nearby = true;
+        if ((dist_vec_squared(getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
+            (dist_vec_squared(getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius))
+        {
+            is_nearby = false;
+        }
+
+        if (is_nearby && (sAVsIgnoringARTLimit.size() < MIN_NONTUNED_AVS))
+        {
+            if (std::count(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID) == 0)
+            {
+                sAVsIgnoringARTLimit.push_back(mID);
+            }
+        }
+        else if (!is_nearby)
+        {
+            sAVsIgnoringARTLimit.erase(std::remove(sAVsIgnoringARTLimit.begin(), sAVsIgnoringARTLimit.end(), mID),
+                                       sAVsIgnoringARTLimit.end());
+        }
+        updateNearbyAvatarCount();
+    }
+}
+
+void LLVOAvatar::updateNearbyAvatarCount()
+{
+    static LLFrameTimer agent_update_timer;
+
+	if (agent_update_timer.getElapsedTimeF32() > 1.0f)
+    {
+        S32 avs_nearby = 0;
+        static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
+        F32 radius = render_far_clip * render_far_clip;
+        std::vector<LLCharacter *>::iterator char_iter = LLCharacter::sInstances.begin();
+        while (char_iter != LLCharacter::sInstances.end())
+        {
+            LLVOAvatar *avatar = dynamic_cast<LLVOAvatar *>(*char_iter);
+            if (avatar && !avatar->isDead() && !avatar->isControlAvatar())
+            {
+                if ((dist_vec_squared(avatar->getPositionGlobal(), gAgent.getPositionGlobal()) > radius) &&
+                    (dist_vec_squared(avatar->getPositionGlobal(), gAgentCamera.getCameraPositionGlobal()) > radius))
+                {
+                    char_iter++;
+                    continue;
+                }
+                avs_nearby++;
+            }
+            char_iter++;
+        }
+        sAvatarsNearby = avs_nearby;
+        agent_update_timer.reset();
+    }
 }
 
 void LLVOAvatar::idleUpdateDebugInfo()
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index e07ead9d46..970ca523a5 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -315,6 +315,8 @@ public:
 
 	void 			idleUpdateBelowWater();
 
+	static void updateNearbyAvatarCount();
+
 	//--------------------------------------------------------------------
 	// Static preferences (controlled by user settings/menus)
 	//--------------------------------------------------------------------
@@ -339,6 +341,9 @@ public:
 
     static LLPointer<LLViewerTexture>  sCloudTexture;
 
+	static std::vector<LLUUID> sAVsIgnoringARTLimit;
+    static S32 sAvatarsNearby;
+
 	//--------------------------------------------------------------------
 	// Region state
 	//--------------------------------------------------------------------
-- 
cgit v1.2.3


From 561f5f57c297c124950c49fb66e949d641064a97 Mon Sep 17 00:00:00 2001
From: Mnikolenko Productengine <mnikolenko@productengine.com>
Date: Fri, 31 Mar 2023 17:05:34 +0300
Subject: SL-19425 capitalization fix

---
 .../newview/skins/default/xui/en/panel_performance_autoadjustments.xml  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
index 56b032d683..904ce1cc52 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_autoadjustments.xml
@@ -137,7 +137,7 @@
      name="av_and_scene"
      value="1" />
 	<combo_box.item
-     label="World only"
+     label="World Only"
      name="scene_only"
      value="2" />
   </combo_box>
-- 
cgit v1.2.3


From 82fb4a08ec469cc2c44833d2240564e3f9045d03 Mon Sep 17 00:00:00 2001
From: Andrey Lihatskiy <alihatskiy@productengine.com>
Date: Thu, 13 Apr 2023 07:05:05 +0300
Subject: SL-19591 Prompt user to save current settings as Graphics Preset
 before enabling AutoFPS

---
 indra/newview/llfloaterperformance.cpp             | 26 +++++++++++++++++++++-
 indra/newview/llfloaterperformance.h               |  1 +
 .../newview/skins/default/xui/en/notifications.xml | 14 ++++++++++++
 3 files changed, 40 insertions(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index 5eb58b9482..e35fa55564 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -39,6 +39,7 @@
 #include "llnamelistctrl.h"
 #include "llnotificationsutil.h"
 #include "llperfstats.h"
+#include "llpresetsmanager.h"
 #include "llradiogroup.h"
 #include "llsliderctrl.h"
 #include "lltextbox.h"
@@ -158,6 +159,8 @@ BOOL LLFloaterPerformance::postBuild()
     mStartAutotuneBtn->setCommitCallback(boost::bind(&LLFloaterPerformance::startAutotune, this));
     mStopAutotuneBtn->setCommitCallback(boost::bind(&LLFloaterPerformance::stopAutotune, this));
 
+    gSavedPerAccountSettings.declareBOOL("HadEnabledAutoFPS", FALSE, "User had enabled AutoFPS at least once", LLControlVariable::PERSIST_ALWAYS);
+
     return TRUE;
 }
 
@@ -188,7 +191,10 @@ void LLFloaterPerformance::showAutoadjustmentsPanel()
 
 void LLFloaterPerformance::draw()
 {
-    if (mUpdateTimer->hasExpired())
+    enableAutotuneWarning();
+
+    if (mUpdateTimer->hasExpired() && 
+        !LLFloaterReg::instanceVisible("save_pref_preset", PRESETS_GRAPHIC)) // give user a chance to save the graphics settings before updating them
     {
         setFPSText();
         if (mHUDsPanel->getVisible())
@@ -672,4 +678,22 @@ void LLFloaterPerformance::updateAutotuneCtrls(bool autotune_enabled)
     getChild<LLTextBox>("wip_desc")->setVisible(autotune_enabled && !auto_tune_locked);
     getChild<LLTextBox>("display_desc")->setVisible(LLPerfStats::tunables.vsyncEnabled);
 }
+
+void LLFloaterPerformance::enableAutotuneWarning()
+{
+    if (!gSavedPerAccountSettings.getBOOL("HadEnabledAutoFPS") && LLPerfStats::tunables.userAutoTuneEnabled)
+    {
+        gSavedPerAccountSettings.setBOOL("HadEnabledAutoFPS", TRUE);
+
+        LLNotificationsUtil::add("EnableAutoFPSWarning", LLSD(), LLSD(),
+            [](const LLSD& notif, const LLSD& resp)
+            {
+                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+                if (opt == 0)
+                { // offer user to save current graphics settings as a preset
+                    LLFloaterReg::showInstance("save_pref_preset", PRESETS_GRAPHIC);
+                }
+            });
+    }
+}
 // EOF
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 648e5902b6..00f904f6d6 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -71,6 +71,7 @@ private:
     void startAutotune();
     void stopAutotune();
     void updateAutotuneCtrls(bool autotune_enabled);
+    void enableAutotuneWarning();
 
     void updateMaxRenderTime();
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 067e5c23c9..f9211600ea 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11965,4 +11965,18 @@ If you want others to see this object, remove it and re-attach it to an avatar a
         yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="EnableAutoFPSWarning"
+   type="alertmodal">
+You are about to enable AutoFPS. All unsaved graphics settings will be lost.
+
+Would you like to save them first?
+      <tag>confirm</tag>
+      <usetemplate
+       name="okcancelbuttons"
+       notext="No"
+       yestext="Yes"/>
+  </notification>
+    
 </notifications>
-- 
cgit v1.2.3


From 9f3f23ffa2ac487741be305068002536b872b015 Mon Sep 17 00:00:00 2001
From: Brad Linden <brad@lindenlab.com>
Date: Wed, 26 Apr 2023 14:35:27 -0700
Subject: Temporarily moving new DRTVWR-559 LLDrawPool functions to someplace
 less likely to conflict with upcoming DRTVWR-539 merge

---
 indra/newview/lldrawpool.cpp | 168 +++++++++++++++++++++----------------------
 1 file changed, 84 insertions(+), 84 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 3de0e8a7c4..15a07ce3d1 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -420,90 +420,6 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool textu
     }
 }
 
-void setup_texture_matrix(LLDrawInfo& params)
-{
-    if (params.mTextureMatrix)
-    { //special case implementation of texture animation here because of special handling of textures for PBR batches
-        gGL.getTexUnit(0)->activate();
-        gGL.matrixMode(LLRender::MM_TEXTURE);
-        gGL.loadMatrix((GLfloat*)params.mTextureMatrix->mMatrix);
-        gPipeline.mTextureMatrixOps++;
-    }
-}
-
-void teardown_texture_matrix(LLDrawInfo& params)
-{
-    if (params.mTextureMatrix)
-    {
-        gGL.matrixMode(LLRender::MM_TEXTURE0);
-        gGL.loadIdentity();
-        gGL.matrixMode(LLRender::MM_MODELVIEW);
-    }
-}
-
-void LLRenderPass::pushGLTFBatches(U32 type)
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
-    auto* begin = gPipeline.beginRenderMap(type);
-    auto* end = gPipeline.endRenderMap(type);
-    for (LLCullResult::drawinfo_iterator i = begin; i != end; )
-    {
-        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushGLTFBatch");
-        LLDrawInfo& params = **i;
-        LLCullResult::increment_iterator(i, end);
-
-        pushGLTFBatch(params);
-    }
-}
-
-void LLRenderPass::pushGLTFBatch(LLDrawInfo& params)
-{
-    auto& mat = params.mGLTFMaterial;
-
-    mat->bind(params.mTexture);
-
-    LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
-
-    setup_texture_matrix(params);
-    
-    applyModelMatrix(params);
-
-    params.mVertexBuffer->setBuffer();
-    params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
-
-    teardown_texture_matrix(params);
-}
-
-void LLRenderPass::pushRiggedGLTFBatches(U32 type)
-{
-    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
-    LLVOAvatar* lastAvatar = nullptr;
-    U64 lastMeshId = 0;
-
-    auto* begin = gPipeline.beginRenderMap(type);
-    auto* end = gPipeline.endRenderMap(type);
-    for (LLCullResult::drawinfo_iterator i = begin; i != end; )
-    {
-        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushRiggedGLTFBatch");
-        LLDrawInfo& params = **i;
-        LLCullResult::increment_iterator(i, end);
-
-        pushRiggedGLTFBatch(params, lastAvatar, lastMeshId);
-    }
-}
-
-void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
-{
-    if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
-    {
-        uploadMatrixPalette(params);
-        lastAvatar = params.mAvatar;
-        lastMeshId = params.mSkinInfo->mHash;
-    }
-
-    pushGLTFBatch(params);
-}
-
 void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures, bool reset_gltf)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
@@ -702,3 +618,87 @@ bool LLRenderPass::uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinI
     return true;
 }
 
+void setup_texture_matrix(LLDrawInfo& params)
+{
+    if (params.mTextureMatrix)
+    { //special case implementation of texture animation here because of special handling of textures for PBR batches
+        gGL.getTexUnit(0)->activate();
+        gGL.matrixMode(LLRender::MM_TEXTURE);
+        gGL.loadMatrix((GLfloat*)params.mTextureMatrix->mMatrix);
+        gPipeline.mTextureMatrixOps++;
+    }
+}
+
+void teardown_texture_matrix(LLDrawInfo& params)
+{
+    if (params.mTextureMatrix)
+    {
+        gGL.matrixMode(LLRender::MM_TEXTURE0);
+        gGL.loadIdentity();
+        gGL.matrixMode(LLRender::MM_MODELVIEW);
+    }
+}
+
+void LLRenderPass::pushGLTFBatches(U32 type)
+{
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+    auto* begin = gPipeline.beginRenderMap(type);
+    auto* end = gPipeline.endRenderMap(type);
+    for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+    {
+        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushGLTFBatch");
+        LLDrawInfo& params = **i;
+        LLCullResult::increment_iterator(i, end);
+
+        pushGLTFBatch(params);
+    }
+}
+
+void LLRenderPass::pushGLTFBatch(LLDrawInfo& params)
+{
+    auto& mat = params.mGLTFMaterial;
+
+    mat->bind(params.mTexture);
+
+    LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
+
+    setup_texture_matrix(params);
+
+    applyModelMatrix(params);
+
+    params.mVertexBuffer->setBuffer();
+    params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+
+    teardown_texture_matrix(params);
+}
+
+void LLRenderPass::pushRiggedGLTFBatches(U32 type)
+{
+    LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+    LLVOAvatar* lastAvatar = nullptr;
+    U64 lastMeshId = 0;
+
+    auto* begin = gPipeline.beginRenderMap(type);
+    auto* end = gPipeline.endRenderMap(type);
+    for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+    {
+        LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushRiggedGLTFBatch");
+        LLDrawInfo& params = **i;
+        LLCullResult::increment_iterator(i, end);
+
+        pushRiggedGLTFBatch(params, lastAvatar, lastMeshId);
+    }
+}
+
+void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
+{
+    if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
+    {
+        uploadMatrixPalette(params);
+        lastAvatar = params.mAvatar;
+        lastMeshId = params.mSkinInfo->mHash;
+    }
+
+    pushGLTFBatch(params);
+}
+
-- 
cgit v1.2.3


From e2dc40a76e1a6e191443c213d0f0474d36c83413 Mon Sep 17 00:00:00 2001
From: Brad Linden <brad@lindenlab.com>
Date: Wed, 26 Apr 2023 17:16:28 -0700
Subject: SL-19656 disabling trackAttachments() code after DRTVWR-559 &
 DRTVWR-539 merge

---
 indra/newview/lldrawpool.cpp      | 12 ++++++++++++
 indra/newview/lldrawpoolalpha.cpp |  6 ++++++
 indra/newview/lldrawpoolbump.cpp  |  7 ++++++-
 3 files changed, 24 insertions(+), 1 deletion(-)

(limited to 'indra/newview')

diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 0e050c6f31..edabb55cc3 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -393,6 +393,7 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, bool texture)
 		LLDrawInfo *pparams = *k;
 		if (pparams) 
         {
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
             if(pparams->mFace)
             {
                 LLViewerObject* vobj = pparams->mFace->getViewerObject();
@@ -401,6 +402,7 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, bool texture)
                     trackAttachments(vobj, false, &ratPtr);
                 }
             }
+#endif
             pushBatch(*pparams, texture);
 		}
 	}
@@ -419,6 +421,7 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool textu
         LLDrawInfo* pparams = *k;
         if (pparams) 
         {
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
             if(pparams->mFace)
             {
                 LLViewerObject* vobj = pparams->mFace->getViewerObject();
@@ -427,6 +430,7 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool textu
                     trackAttachments( vobj, true ,&ratPtr);
                 }
             }
+#endif
 
             if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
             {
@@ -451,6 +455,7 @@ void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures, bool
         LLDrawInfo* pparams = *i;
         LLCullResult::increment_iterator(i, end);
 
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
             if(pparams->mFace)
             {
                 LLViewerObject* vobj = pparams->mFace->getViewerObject();
@@ -459,6 +464,7 @@ void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures, bool
                     trackAttachments( vobj, false, &ratPtr);
                 }
             }
+#endif
             pushBatch(*pparams, texture, batch_textures, reset_gltf);
 	}
 }
@@ -476,6 +482,7 @@ void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures
         LLDrawInfo* pparams = *i;
         LLCullResult::increment_iterator(i, end);
 
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
             if(pparams->mFace)
             {
                 LLViewerObject* vobj = pparams->mFace->getViewerObject();
@@ -484,6 +491,7 @@ void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures
                     trackAttachments( vobj, true, &ratPtr);
                 }
             }
+#endif
 
         if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
         {
@@ -507,6 +515,7 @@ void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures,
 	{
         LLDrawInfo* pparams = *i;
         LLCullResult::increment_iterator(i, end);
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
             if((*pparams).mFace)
             {
                 LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
@@ -515,6 +524,7 @@ void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures,
                     trackAttachments( vobj, false, &ratPtr);
                 }
             }
+#endif
 		LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
 		pushBatch(*pparams, texture, batch_textures, reset_gltf);
         reset_gltf = false;
@@ -536,6 +546,7 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text
         LLCullResult::increment_iterator(i, end);
 
         llassert(pparams);
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
         if((*pparams).mFace)
         {
             LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
@@ -544,6 +555,7 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text
                 trackAttachments( vobj, true, &ratPtr);
             }
         }
+#endif
 
         if (LLGLSLShader::sCurBoundShaderPtr)
         {
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index dd6cfab52c..da4c963a97 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -354,6 +354,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
                 {
                     LLDrawInfo& params = **k;
 
+# if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
                     if(params.mFace)
                     {
                         LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
@@ -362,6 +363,7 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
                             trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
                         }
                     }
+#endif
 
                     bool rigged = (params.mAvatar != nullptr);
                     gHighlightProgram.bind(rigged);
@@ -550,11 +552,13 @@ void LLDrawPoolAlpha::renderRiggedEmissives(std::vector<LLDrawInfo*>& emissives)
     for (LLDrawInfo* draw : emissives)
     {
         LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives");
+# if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
         auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
         if(vobj && vobj->isAttachment())
         {
             trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
         }
+#endif
 
         bool tex_setup = TexSetup(draw, false);
         if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)
@@ -696,6 +700,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
 
                 LLRenderPass::applyModelMatrix(params);
 
+# if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
                 if(params.mFace)
                 {
                     LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
@@ -705,6 +710,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
                         trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
                     }
                 }
+#endif
 
                 LLMaterial* mat = NULL;
                 LLGLTFMaterial *gltf_mat = params.mGLTFMaterial; 
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 439b893e0e..75b47b2c22 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -411,12 +411,13 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture =
 	{
 		LLDrawInfo& params = **k;
 		
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
         LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
-
         if( vobj && vobj->isAttachment() )
         {
             trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
         }
+#endif
 
 		applyModelMatrix(params);
 
@@ -574,6 +575,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
 
             LLCullResult::increment_iterator(i, end);
 
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
             if(params.mFace)
             {
                 LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
@@ -583,6 +585,7 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
                     trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
                 }
             }
+#endif
 
             LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
             LLDrawPoolBump::bindBumpMap(params, bump_channel);
@@ -1217,6 +1220,7 @@ void LLDrawPoolBump::pushBumpBatches(U32 type)
 	{
 		LLDrawInfo& params = **i;
 
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
         if(params.mFace)
         {
             LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
@@ -1226,6 +1230,7 @@ void LLDrawPoolBump::pushBumpBatches(U32 type)
                 trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
             }
         }
+#endif
 
 		if (LLDrawPoolBump::bindBumpMap(params))
 		{
-- 
cgit v1.2.3


From 513ac361b13b081a13f1f6dde1c0c34c4eb41b3a Mon Sep 17 00:00:00 2001
From: Brad Linden <brad@lindenlab.com>
Date: Wed, 26 Apr 2023 17:32:19 -0700
Subject: Got things to compile again after DRTVWR-559 & DRTVWR-539 merge.

removing dead code and references to members that don't exist anymore
---
 indra/newview/llfeaturemanager.cpp                 |  2 +-
 indra/newview/llfloaterperformance.cpp             |  4 +--
 indra/newview/llfloaterpreference.cpp              |  7 +++--
 .../llfloaterpreferencesgraphicsadvanced.cpp       | 31 +++++++++++++++-------
 indra/newview/llperfstats.cpp                      |  4 +++
 indra/newview/llperfstats.h                        |  4 ---
 indra/newview/llviewercontrol.cpp                  |  6 -----
 7 files changed, 31 insertions(+), 27 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index c5d64b87b9..3d941b5547 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -408,7 +408,7 @@ bool LLFeatureManager::loadGPUClass()
 {
 	if (!gSavedSettings.getBOOL("SkipBenchmark"))
 	{
-        F32 class0_gbps = gSavedSettings.getF32("RenderClass0MemoryBandwidth");  // TODO merge brad - figure out what to do with this setting and the below gbps constant comparisons
+        //F32 class0_gbps = gSavedSettings.getF32("RenderClass0MemoryBandwidth");  // TODO merge brad - figure out what to do with this setting and the below gbps constant comparisons
 		//get memory bandwidth from benchmark
 		F32 gbps;
 		try
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index e35fa55564..c221da539c 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -143,7 +143,7 @@ BOOL LLFloaterPerformance::postBuild()
     mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
 
     // store the current setting as the users desired reflection detail and DD
-    gSavedSettings.setS32("UserTargetReflections", LLPipeline::RenderReflectionDetail);
+    //gSavedSettings.setS32("UserTargetReflections", LLPipeline::RenderReflectionDetail);
     if(!LLPerfStats::tunables.userAutoTuneEnabled)
     {
         gSavedSettings.setF32("AutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip);
@@ -633,7 +633,7 @@ void LLFloaterPerformance::changeQualityLevel(const std::string& notif)
 
 bool is_ALM_available()
 {
-    bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
+    bool bumpshiny = LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
     bool shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
     
     return LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 030711ca66..d4e40ff103 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1200,8 +1200,7 @@ void LLFloaterPreference::refreshEnabledState()
 
 	getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
 }
-// TODO merge brad figure out where LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() went and port over changes
-// static
+
 void LLAvatarComplexityControls::setIndirectControls()
 {
 	/*
@@ -1242,7 +1241,7 @@ void LLAvatarComplexityControls::setIndirectMaxArc()
 	}
 	gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc);
 }
-// TODO merge brad figure out where LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() went and port over changes
+
 void LLFloaterPreference::refresh()
 {
 	LLPanel::refresh();
@@ -1726,7 +1725,7 @@ void LLFloaterPreference::onAtmosShaderChange()
     if(ctrl_alm)
     {
         //Deferred/SSAO/Shadows
-        BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
+        BOOL bumpshiny = LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
         BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
         BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
                         bumpshiny &&
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index a976b97831..d251c72672 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -354,13 +354,13 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
     LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
 
     // Reflections
-    BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
+    BOOL reflections = LLCubeMap::sUseCubeMaps;
     ctrl_reflections->setEnabled(reflections);
     reflections_text->setEnabled(reflections);
 
     // Bump & Shiny	
     LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
-    bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
+    bool bumpshiny = LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
     bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
 
     // Avatar Mode
@@ -396,21 +396,29 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
     terrain_text->setEnabled(FALSE);
 
     // WindLight
-    LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
+    //LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
+    //ctrl_wind_light->setEnabled(TRUE);
     LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
     LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
-    ctrl_wind_light->setEnabled(TRUE);
     sky->setEnabled(TRUE);
     sky_text->setEnabled(TRUE);
 
+    BOOL enabled = TRUE;
+#if 0 // deferred always on now
     //Deferred/SSAO/Shadows
     LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
 
-    BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+    enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
         ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
         (ctrl_wind_light->get()) ? TRUE : FALSE;
 
     ctrl_deferred->setEnabled(enabled);
+#endif
+    
+    LLCheckBoxCtrl* ctrl_pbr = getChild<LLCheckBoxCtrl>("UsePBRShaders");
+
+    //PBR
+    ctrl_pbr->setEnabled(TRUE);
 
     LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
     LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
@@ -418,9 +426,9 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
     LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText");
 
     // note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
-    enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
+    enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO");// && (ctrl_deferred->get() ? TRUE : FALSE);
 
-    ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
+    //ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
 
     ctrl_ssao->setEnabled(enabled);
     ctrl_dof->setEnabled(enabled);
@@ -431,20 +439,23 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
     shadow_text->setEnabled(enabled);
 
     // Hardware settings
+# if 0 // TODO merge brad VRAM is rewritten
     F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
     S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
     S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
     getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value());
     getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
-
+#endif
+    
+#if 0 // cannot turn off VBOs anymore
     if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
         !gGLManager.mHasVertexBufferObject)
     {
         getChildView("vbo")->setEnabled(FALSE);
     }
+#endif
 
-    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
-        !gGLManager.mHasVertexBufferObject)
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures"))
     {
         getChildView("texture compression")->setEnabled(FALSE);
     }
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 7ff363c3c1..e37c2a4479 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -443,6 +443,7 @@ namespace LLPerfStats
                     {
                         // 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit.
                         // the other reflection options make comparatively little change and if this overshoots we'll be stepping back up later
+# if 0 // TODO RenderReflectionDetail went away
                         if(LLPipeline::RenderReflectionDetail != -2)
                         {
                             LLPerfStats::tunables.updateReflectionDetail(-2);
@@ -450,6 +451,7 @@ namespace LLPerfStats
                             return;
                         }
                         else // deliberately "else" here so we only do one of these in any given frame
+#endif
                         {
                             // step down the DD by 10m per update
                             auto new_dd = (LLPipeline::RenderFarClip - DD_STEP > tunables.userMinDrawDistance)?(LLPipeline::RenderFarClip - DD_STEP) : tunables.userMinDrawDistance;
@@ -539,7 +541,9 @@ namespace LLPerfStats
                     if( (tot_frame_time_raw * 1.5) < target_frame_time_raw )
                     {
                         // if everything else is "max" and we have >50% headroom let's knock the water quality up a notch at a time.
+# if 0 // RenderReflectionDetail went away
                         LLPerfStats::tunables.updateReflectionDetail( std::min(LLPipeline::RenderReflectionDetail + 1, tunables.userTargetReflections) );
+#endif
                     }
                 }
             }
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index 48ac483ce7..3289f396f1 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -229,10 +229,6 @@ namespace LLPerfStats
             LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
             // LL_INFOS("perfstats") << "processing update:" << LL_ENDL;
             // Note: nullptr is used as the key for global stats
-            #ifdef TRACY_ENABLE
-            static char avstr[36];
-            static char obstr[36];
-            #endif
 
             if (upd.statType == StatType_t::RENDER_DONE && upd.objType == ObjType_t::OT_GENERAL && upd.time == 0)
             {
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 5c486dbbac..f197722698 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -158,12 +158,6 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
 	return true;
 }
 
-static bool handleShadowDetailChanged(const LLSD& newvalue)
-{
-    gPipeline.handleShadowDetailChanged();
-    return true;
-}
-
 static bool handleRenderPerfTestChanged(const LLSD& newvalue)
 {
        bool status = !newvalue.asBoolean();
-- 
cgit v1.2.3


From dc813181a51ad2c22264e93a3c235cbf796b24ed Mon Sep 17 00:00:00 2001
From: Brad Linden <brad@lindenlab.com>
Date: Thu, 27 Apr 2023 12:25:50 -0700
Subject: More post-merge fixes after DRTVWR-559 & DRTVWR-539 merge

---
 indra/newview/app_settings/settings.xml            | 11 -----------
 indra/newview/featuretable_linux.txt               |  1 -
 indra/newview/lldrawpoolmaterials.cpp              | 23 +++++++++++-----------
 indra/newview/llfeaturemanager.cpp                 |  1 -
 .../llfloaterpreferencesgraphicsadvanced.cpp       | 12 +----------
 5 files changed, 13 insertions(+), 35 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 66c615b6c6..d21b686ec8 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8839,17 +8839,6 @@
     <key>Value</key>
     <real>0.1</real>
   </map>
-  <key>RenderClass0MemoryBandwidth</key>
-  <map>
-    <key>Comment</key>
-    <string>Memory bandwidth at which to default to Class 0 in gigabytes per second.  Used as basis for other classes.</string>
-    <key>Persist</key>
-    <integer>1</integer>
-    <key>Type</key>
-    <string>F32</string>
-    <key>Value</key>
-    <real>16.0</real>
-  </map>
   <key>RenderCPUBasis</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 66197e6484..4bcefc1546 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -59,7 +59,6 @@ WindLightUseAtmosShaders	1	1
 WLSkyDetail					1	128
 Disregard128DefaultDrawDistance	1	1
 Disregard96DefaultDrawDistance	1	1
-RenderTextureMemoryMultiple		1	1.0
 RenderCompressTextures		1	1
 RenderShaderLightingMaxLevel	1	3
 RenderDeferred				1	1
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index 3144f9a2fa..e025651cce 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -156,17 +156,6 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
     F32 lastFullbright = 0.f;
     F32 lastMinimumAlpha = 0.f;
     LLVector4 lastSpecular = LLVector4(0, 0, 0, 0);
-    #if 0 // TODO merge brad move this down into LLCullResult begin/end loop
-        if(params.mFace)
-        {
-            LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
-
-            if( vobj && vobj->isAttachment() )
-            {
-                trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
-            }
-        }
-    #endif
 
     GLint intensity = mShader->getUniformLocation(LLShaderMgr::ENVIRONMENT_INTENSITY);
     GLint brightness = mShader->getUniformLocation(LLShaderMgr::EMISSIVE_BRIGHTNESS);
@@ -212,6 +201,18 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
 		
         LLCullResult::increment_iterator(i, end);
 
+#if 0 // TODO SL-19656 figure out how to reenable trackAttachments()
+        if(params.mFace)
+        {
+            LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
+
+            if( vobj && vobj->isAttachment() )
+            {
+                trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
+            }
+        }
+#endif
+
         if (specular > -1 && params.mSpecColor != lastSpecular)
         {
             lastSpecular = params.mSpecColor;
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index 3d941b5547..b8143eb545 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -408,7 +408,6 @@ bool LLFeatureManager::loadGPUClass()
 {
 	if (!gSavedSettings.getBOOL("SkipBenchmark"))
 	{
-        //F32 class0_gbps = gSavedSettings.getF32("RenderClass0MemoryBandwidth");  // TODO merge brad - figure out what to do with this setting and the below gbps constant comparisons
 		//get memory bandwidth from benchmark
 		F32 gbps;
 		try
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index d251c72672..a91f0ec060 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -439,21 +439,11 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
     shadow_text->setEnabled(enabled);
 
     // Hardware settings
-# if 0 // TODO merge brad VRAM is rewritten
-    F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
-    S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
-    S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
-    getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value());
-    getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
-#endif
     
-#if 0 // cannot turn off VBOs anymore
-    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
-        !gGLManager.mHasVertexBufferObject)
+    if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable"))
     {
         getChildView("vbo")->setEnabled(FALSE);
     }
-#endif
 
     if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures"))
     {
-- 
cgit v1.2.3


From 10b2ec92ec74176422fa8c6013dee1036eed57c5 Mon Sep 17 00:00:00 2001
From: Brad Linden <brad@lindenlab.com>
Date: Thu, 27 Apr 2023 18:02:48 -0700
Subject: More merge cleanup after DRTVWR-559 & DRTVWR-539 merge. (thanks
 Ansariel)

---
 indra/newview/app_settings/settings.xml | 11 -----------
 indra/newview/featuretable.txt          |  5 -----
 indra/newview/featuretable_mac.txt      |  5 -----
 indra/newview/llappviewer.cpp           |  2 ++
 indra/newview/llfloaterperformance.cpp  |  2 --
 indra/newview/llperfstats.cpp           |  2 --
 indra/newview/llperfstats.h             |  2 --
 indra/newview/llviewercontrol.cpp       |  8 +-------
 8 files changed, 3 insertions(+), 34 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index d21b686ec8..54246da92b 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -16953,17 +16953,6 @@
     <key>Value</key>
     <real>256.0</real>
   </map>
-  <key>UserTargetReflections</key>
-  <map>
-    <key>Comment</key>
-    <string>Set by auto tune floater on build</string>
-    <key>Persist</key>
-    <integer>0</integer>
-    <key>Type</key>
-    <string>S32</string>
-    <key>Value</key>
-    <integer>4</integer>
-  </map>
   <key>PerfStatsCaptureEnabled</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index a5b6b01d5a..79d92adcc2 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -113,7 +113,6 @@ RenderReflectionProbeLevel  1   0
 list LowMid
 RenderAnisotropic			1	0
 RenderAvatarLODFactor		1	0.5
-RenderAvatarMaxNonImpostors 1   5
 RenderAvatarMaxComplexity   1	100000
 RenderAvatarPhysicsLODFactor 1	0.75
 RenderAvatarMaxNonImpostors 1   5
@@ -144,7 +143,6 @@ RenderReflectionProbeLevel  1   1
 list Mid
 RenderAnisotropic			1	1
 RenderAvatarLODFactor		1	1.0
-RenderAvatarMaxNonImpostors 1   7
 RenderAvatarMaxComplexity   1	200000
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   7
@@ -175,7 +173,6 @@ RenderReflectionProbeLevel  1   2
 list MidHigh
 RenderAnisotropic			1	1
 RenderAvatarLODFactor		1	1.0
-RenderAvatarMaxNonImpostors 1   9
 RenderAvatarMaxComplexity   1	250000
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   9
@@ -206,7 +203,6 @@ RenderReflectionProbeLevel  1   2
 list High
 RenderAnisotropic			1	1
 RenderAvatarLODFactor		1	1.0
-RenderAvatarMaxNonImpostors 1   11
 RenderAvatarMaxComplexity   1	300000
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   11
@@ -237,7 +233,6 @@ RenderReflectionProbeLevel  1   3
 list HighUltra
 RenderAnisotropic			1	1
 RenderAvatarLODFactor		1	1.0
-RenderAvatarMaxNonImpostors 1   16
 RenderAvatarMaxComplexity   1	350000
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   16
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 56242ce23d..72deabd9f1 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -111,7 +111,6 @@ RenderReflectionProbeLevel  1   0
 list LowMid
 RenderAnisotropic			1	0
 RenderAvatarLODFactor		1	0.5
-RenderAvatarMaxNonImpostors 1   5
 RenderAvatarMaxComplexity   1	100000
 RenderAvatarPhysicsLODFactor 1	0.75
 RenderAvatarMaxNonImpostors 1   5
@@ -142,7 +141,6 @@ RenderReflectionProbeLevel  1   1
 list Mid
 RenderAnisotropic			1	1
 RenderAvatarLODFactor		1	1.0
-RenderAvatarMaxNonImpostors 1   7
 RenderAvatarMaxComplexity   1	200000
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   7
@@ -173,7 +171,6 @@ RenderReflectionProbeLevel  1   2
 list MidHigh
 RenderAnisotropic			1	1
 RenderAvatarLODFactor		1	1.0
-RenderAvatarMaxNonImpostors 1   9
 RenderAvatarMaxComplexity   1	250000
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   9
@@ -204,7 +201,6 @@ RenderReflectionProbeLevel  1   2
 list High
 RenderAnisotropic			1	1
 RenderAvatarLODFactor		1	1.0
-RenderAvatarMaxNonImpostors 1   11
 RenderAvatarMaxComplexity   1	300000
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   11
@@ -265,7 +261,6 @@ RenderReflectionProbeLevel  1   3
 list Ultra
 RenderAnisotropic			1	1
 RenderAvatarLODFactor		1	1.0
-RenderAvatarMaxNonImpostors 1   16
 RenderAvatarPhysicsLODFactor 1	1.0
 RenderAvatarMaxNonImpostors 1   16
 RenderFarClip				1	256
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index dc2ffdb26a..b2349e9f74 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1442,6 +1442,8 @@ bool LLAppViewer::doFrame()
                 LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df suspend")
                 // give listeners a chance to run
                 llcoro::suspend();
+                // if one of our coroutines threw an uncaught exception, rethrow it now
+                LLCoros::instance().rethrow();
             }
         }
 
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index c221da539c..3321374f65 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -142,8 +142,6 @@ BOOL LLFloaterPerformance::postBuild()
     mMaxARTChangedSignal = gSavedSettings.getControl("RenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
     mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
 
-    // store the current setting as the users desired reflection detail and DD
-    //gSavedSettings.setS32("UserTargetReflections", LLPipeline::RenderReflectionDetail);
     if(!LLPerfStats::tunables.userAutoTuneEnabled)
     {
         gSavedSettings.setF32("AutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip);
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index e37c2a4479..c63aae2089 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -75,7 +75,6 @@ namespace LLPerfStats
         if( tuningFlag & UserAutoTuneEnabled ){ gSavedSettings.setBOOL("AutoTuneFPS", userAutoTuneEnabled); };
         if( tuningFlag & UserAutoTuneLock ){ gSavedSettings.setBOOL("AutoTuneLock", userAutoTuneLock); };
         if( tuningFlag & UserTargetFPS ){ gSavedSettings.setU32("TargetFPS", userTargetFPS); };
-        if( tuningFlag & UserTargetReflections ){ gSavedSettings.setS32("UserTargetReflections", userTargetReflections); };
         // Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value
         if( tuningFlag & UserARTCutoff ){ gSavedSettings.setF32("RenderAvatarMaxART", userARTCutoffSliderValue); };
         resetChanges();
@@ -122,7 +121,6 @@ namespace LLPerfStats
         LLPerfStats::tunables.userFPSTuningStrategy = gSavedSettings.getU32("TuningFPSStrategy");
         LLPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("TargetFPS");
         LLPerfStats::tunables.vsyncEnabled = gSavedSettings.getBOOL("RenderVSyncEnable");
-        LLPerfStats::tunables.userTargetReflections = gSavedSettings.getS32("UserTargetReflections");
 
         LLPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("AutoTuneLock") && gSavedSettings.getU32("KeepAutoTuneLock");
 
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index 3289f396f1..dbb88a141d 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -117,7 +117,6 @@ namespace LLPerfStats
         static constexpr U32 UserAutoTuneEnabled{256};
         static constexpr U32 UserTargetFPS{512};
         static constexpr U32 UserARTCutoff{1024};
-        static constexpr U32 UserTargetReflections{2048};
         static constexpr U32 UserAutoTuneLock{4096};
 
         U32 tuningFlag{0}; // bit mask for changed settings
@@ -151,7 +150,6 @@ namespace LLPerfStats
         void updateUserARTCutoffSlider(F32 nv){userARTCutoffSliderValue=nv; tuningFlag |= UserARTCutoff;};
         void updateUserAutoTuneEnabled(bool nv){userAutoTuneEnabled=nv; tuningFlag |= UserAutoTuneEnabled;};
         void updateUserAutoTuneLock(bool nv){userAutoTuneLock=nv; tuningFlag |= UserAutoTuneLock;};
-        void updateUserTargetReflections(S32 nv){userTargetReflections=nv; tuningFlag |= UserTargetReflections;};
 
         void resetChanges(){tuningFlag=Nothing;};
         void initialiseFromSettings();
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index f197722698..faeebc33ee 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -638,12 +638,6 @@ void handleUserTargetDrawDistanceChanged(const LLSD& newValue)
     LLPerfStats::tunables.userTargetDrawDistance = newval;
 }
 
-void handleUserTargetReflectionsChanged(const LLSD& newValue)
-{
-    const auto newval = gSavedSettings.getS32("UserTargetReflections");
-    LLPerfStats::tunables.userTargetReflections = newval;
-}
-
 void handlePerformanceStatsEnabledChanged(const LLSD& newValue)
 {
     const auto newval = gSavedSettings.getBOOL("PerfStatsCaptureEnabled");
@@ -736,6 +730,7 @@ void settings_setup_listeners()
     setting_setup_signal_listener(gSavedSettings, "RenderReflectionProbeDetail", handleReflectionProbeDetailChanged);
     setting_setup_signal_listener(gSavedSettings, "RenderReflectionsEnabled", handleReflectionProbeDetailChanged);
     setting_setup_signal_listener(gSavedSettings, "RenderScreenSpaceReflections", handleReflectionProbeDetailChanged);
+    setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
     setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
     setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
     setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged);
@@ -838,7 +833,6 @@ void settings_setup_listeners()
     setting_setup_signal_listener(gSavedSettings, "AutoTuneLock", handleAutoTuneLockChanged);
     setting_setup_signal_listener(gSavedSettings, "RenderAvatarMaxART", handleRenderAvatarMaxARTChanged);
     setting_setup_signal_listener(gSavedSettings, "PerfStatsCaptureEnabled", handlePerformanceStatsEnabledChanged);
-    setting_setup_signal_listener(gSavedSettings, "UserTargetReflections", handleUserTargetReflectionsChanged);
     setting_setup_signal_listener(gSavedSettings, "AutoTuneRenderFarClipTarget", handleUserTargetDrawDistanceChanged);
     setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged);
     setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged);
-- 
cgit v1.2.3


From 97c6bf8f743ef4956d7d706e26f25ce6f32182b4 Mon Sep 17 00:00:00 2001
From: Brad Linden <brad@lindenlab.com>
Date: Thu, 27 Apr 2023 18:04:49 -0700
Subject: Readded RenderClass1MemoryBandwidth setting after DRTVWR-559 &
 DRTVWR-539 merge

Has to use class1 now since class0 shouldn't ever be in use on
end-user systems anymore.
---
 indra/newview/app_settings/settings.xml | 11 +++++++++++
 indra/newview/llfeaturemanager.cpp      |  9 +++++----
 2 files changed, 16 insertions(+), 4 deletions(-)

(limited to 'indra/newview')

diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 54246da92b..cda71dd9b0 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -8828,6 +8828,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+  <key>RenderClass1MemoryBandwidth</key>
+  <map>
+    <key>Comment</key>
+    <string>Memory bandwidth at which to default to Class 1 in gigabytes per second.  Used as basis for higher classes.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>F32</string>
+    <key>Value</key>
+    <real>32.0</real>
+  </map>
   <key>RenderCloudShadowAmbianceFactor</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index b8143eb545..a2aae91ae1 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -408,6 +408,7 @@ bool LLFeatureManager::loadGPUClass()
 {
 	if (!gSavedSettings.getBOOL("SkipBenchmark"))
 	{
+		F32 class1_gbps = gSavedSettings.getF32("RenderClass1MemoryBandwidth");
 		//get memory bandwidth from benchmark
 		F32 gbps;
 		try
@@ -442,19 +443,19 @@ bool LLFeatureManager::loadGPUClass()
 			mGPUClass = GPU_CLASS_0;
 	#endif
 		}
-		else if (gbps <= 32.0f)
+		else if (gbps <= class1_gbps)
 		{
 			mGPUClass = GPU_CLASS_1;
 		}
-		else if (gbps <= 64.0f)
+		else if (gbps <= class1_gbps *2.f)
 		{
 			mGPUClass = GPU_CLASS_2;
 		}
-		else if (gbps <= 128.0f)
+		else if (gbps <= class1_gbps*4.f)
 		{
 			mGPUClass = GPU_CLASS_3;
 		}
-		else if (gbps <= 256.0f)
+		else if (gbps <= class1_gbps*8.f)
 		{
 			mGPUClass = GPU_CLASS_4;
 		}
-- 
cgit v1.2.3