diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index d0b4a842a6..2af5273d70 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -580,6 +580,31 @@ namespace LLTrace return typename RelatedTypes::fractional_t(getPeriodMeanPerSec(static_cast&>(stat), num_periods)); } + template + typename RelatedTypes::fractional_t getPeriodMedianPerSec(const StatType& stat, S32 num_periods = S32_MAX) + { + num_periods = llmin(num_periods, getNumRecordedPeriods()); + + std::vector ::fractional_t> buf; + for (S32 i = 1; i <= num_periods; i++) + { + Recording& recording = getPrevRecording(i); + if (recording.getDuration() > (F32Seconds)0.f) + { + buf.push_back(recording.getPerSec(stat)); + } + } + std::sort(buf.begin(), buf.end()); + + return typename RelatedTypes::fractional_t((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]); + } + + template + typename RelatedTypes::fractional_t getPeriodMedianPerSec(const CountStatHandle& stat, S32 num_periods = S32_MAX) + { + return typename RelatedTypes::fractional_t(getPeriodMedianPerSec(static_cast&>(stat), num_periods)); + } + // // PERIODIC STANDARD DEVIATION // diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 13839da400..61470d1440 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -54,6 +54,10 @@ LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_ { cell = new LLScrollListIconText(cell_p); } + else if (cell_p.type() == "bar") + { + cell = new LLScrollListBar(cell_p); + } else // default is "text" { cell = new LLScrollListText(cell_p); @@ -165,6 +169,74 @@ void LLScrollListIcon::draw(const LLColor4& color, const LLColor4& highlight_col } } +// +// LLScrollListBar +// +LLScrollListBar::LLScrollListBar(const LLScrollListCell::Params& p) + : LLScrollListCell(p), + mRatio(0), + mColor(p.color), + mBottom(1), + mLeftPad(1), + mRightPad(1) +{} + +LLScrollListBar::~LLScrollListBar() +{ +} + +/*virtual*/ +S32 LLScrollListBar::getHeight() const +{ + return LLScrollListCell::getHeight(); +} + +/*virtual*/ +const LLSD LLScrollListBar::getValue() const +{ + return LLStringUtil::null; +} + +void LLScrollListBar::setValue(const LLSD& value) +{ + if (value.has("ratio")) + { + mRatio = value["ratio"].asReal(); + } + if (value.has("bottom")) + { + mBottom = value["bottom"].asInteger(); + } + if (value.has("left_pad")) + { + mLeftPad = value["left_pad"].asInteger(); + } + if (value.has("right_pad")) + { + mRightPad = value["right_pad"].asInteger(); + } +} + +void LLScrollListBar::setColor(const LLColor4& color) +{ + mColor = color; +} + +S32 LLScrollListBar::getWidth() const +{ + return LLScrollListCell::getWidth(); +} + + +void LLScrollListBar::draw(const LLColor4& color, const LLColor4& highlight_color) const +{ + S32 bar_width = getWidth() - mLeftPad - mRightPad; + S32 left = bar_width - bar_width * mRatio; + left = llclamp(left, mLeftPad, getWidth() - mRightPad - 1); + + gl_rect_2d(left, mBottom, getWidth() - mRightPad, mBottom - 1, mColor); +} + // // LLScrollListText // diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 19576fb247..9a659dfd0d 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -33,6 +33,7 @@ #include "lluistring.h" #include "v4color.h" #include "llui.h" +#include "llgltexture.h" class LLCheckBoxCtrl; class LLSD; @@ -153,6 +154,7 @@ public: void setText(const LLStringExplicit& text); void setFontStyle(const U8 font_style); + void setAlignment(LLFontGL::HAlign align) { mFontAlignment = align; } protected: LLUIString mText; @@ -192,6 +194,26 @@ private: LLFontGL::HAlign mAlignment; }; + +class LLScrollListBar : public LLScrollListCell +{ +public: + LLScrollListBar(const LLScrollListCell::Params& p); + /*virtual*/ ~LLScrollListBar(); + /*virtual*/ void draw(const LLColor4& color, const LLColor4& highlight_color) const; + /*virtual*/ S32 getWidth() const; + /*virtual*/ S32 getHeight() const; + /*virtual*/ const LLSD getValue() const; + /*virtual*/ void setColor(const LLColor4&); + /*virtual*/ void setValue(const LLSD& value); + +private: + LLColor4 mColor; + F32 mRatio; + S32 mBottom; + S32 mRightPad; + S32 mLeftPad; +}; /* * An interactive cell containing a check box. */ diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 9397168fe7..a9bb2bc0a9 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -397,9 +397,11 @@ set(viewer_SOURCE_FILES llfloaterpathfindinglinksets.cpp llfloaterpathfindingobjects.cpp llfloaterpay.cpp + llfloaterperformance.cpp llfloaterperms.cpp llfloaterpostprocess.cpp llfloaterpreference.cpp + llfloaterpreferencesgraphicsadvanced.cpp llfloaterpreferenceviewadvanced.cpp llfloaterpreviewtrash.cpp llfloaterproperties.cpp @@ -1176,9 +1178,11 @@ set(viewer_HEADER_FILES llfloaterpathfindinglinksets.h llfloaterpathfindingobjects.h llfloaterpay.h + llfloaterperformance.h llfloaterperms.h llfloaterpostprocess.h llfloaterpreference.h + # llfloaterpreferencesgraphicsadvanced.h llfloaterpreferenceviewadvanced.h llfloaterpreviewtrash.h llfloaterproperties.h diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml index a13da0b23a..057aa6cea6 100644 --- a/indra/newview/app_settings/commands.xml +++ b/indra/newview/app_settings/commands.xml @@ -638,4 +638,14 @@ is_running_function="Floater.IsOpen" is_running_parameters="my_environments" /> + diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp index b608646abd..697f8f8459 100644 --- a/indra/newview/llavatarrendernotifier.cpp +++ b/indra/newview/llavatarrendernotifier.cpp @@ -244,6 +244,12 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity) // save the value for use in following messages mLatestAgentComplexity = agentComplexity; + static LLCachedControl show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20); + if (!show_my_complexity_changes) + { + return; + } + if (!isAgentAvatarValid() || !gAgentWearables.areWearablesLoaded()) { // data not ready, nothing to show. @@ -291,7 +297,8 @@ static const char* e_hud_messages[] = }; LLHUDRenderNotifier::LLHUDRenderNotifier() : -mReportedHUDWarning(WARN_NONE) +mReportedHUDWarning(WARN_NONE), +mHUDsCount(0) { } @@ -307,6 +314,15 @@ void LLHUDRenderNotifier::updateNotificationHUD(hud_complexity_list_t complexity return; } + mHUDComplexityList = complexity; + mHUDsCount = mHUDComplexityList.size(); + + static LLCachedControl 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 ec17b3d9e6..37130bfcf6 100644 --- a/indra/newview/llavatarrendernotifier.h +++ b/indra/newview/llavatarrendernotifier.h @@ -63,6 +63,25 @@ struct LLHUDComplexity typedef std::list 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 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 @@ -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 @@ -121,6 +145,9 @@ public: void updateNotificationHUD(hud_complexity_list_t complexity); bool isNotificationVisible(); + hud_complexity_list_t getHUDComplexityList() { return mHUDComplexityList; } + S32 getHUDsCount() { return mHUDsCount; } + private: enum EWarnLevel { @@ -141,6 +168,8 @@ private: EWarnLevel mReportedHUDWarning; LLHUDComplexity mLatestHUDComplexity; LLFrameTimer mHUDPopUpDelayTimer; + hud_complexity_list_t mHUDComplexityList; + S32 mHUDsCount; }; #endif /* ! defined(LL_llavatarrendernotifier_H) */ diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp index ec05ba924c..d455b685fd 100644 --- a/indra/newview/llfloaterautoreplacesettings.cpp +++ b/indra/newview/llfloaterautoreplacesettings.cpp @@ -64,6 +64,7 @@ #include "llnotificationhandler.h" #include "llnotificationmanager.h" #include "llnotificationsutil.h" +#include "llviewercontrol.h" LLFloaterAutoReplaceSettings::LLFloaterAutoReplaceSettings(const LLSD& key) diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp index 15870faa62..1864612487 100644 --- a/indra/newview/llfloateravatarrendersettings.cpp +++ b/indra/newview/llfloateravatarrendersettings.cpp @@ -91,7 +91,6 @@ BOOL LLFloaterAvatarRenderSettings::postBuild() LLFloater::postBuild(); mAvatarSettingsList = getChild("render_settings_list"); mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3)); - getChild("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2)); return TRUE; } @@ -135,37 +134,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); @@ -216,6 +191,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 af36b67bd0..d03f035b4d 100644 --- a/indra/newview/llfloateravatarrendersettings.h +++ b/indra/newview/llfloateravatarrendersettings.h @@ -50,7 +50,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); @@ -61,15 +60,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 new file mode 100644 index 0000000000..ad5cea14ae --- /dev/null +++ b/indra/newview/llfloaterperformance.cpp @@ -0,0 +1,568 @@ +/** + * @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 "llagent.h" +#include "llagentcamera.h" +#include "llappearancemgr.h" +#include "llavataractions.h" +#include "llavatarrendernotifier.h" +#include "llcheckboxctrl.h" +#include "llfeaturemanager.h" +#include "llfloaterpreference.h" // LLAvatarComplexityControls +#include "llfloaterreg.h" +#include "llnamelistctrl.h" +#include "llradiogroup.h" +#include "llsliderctrl.h" +#include "lltextbox.h" +#include "lltrans.h" +#include "llviewerobjectlist.h" +#include "llvoavatar.h" +#include "llvoavatarself.h" +#include "pipeline.h" +#include "llviewercontrol.h" +#include "llmutelist.h" +#include "fsavatarrenderpersistence.h" + +const F32 REFRESH_INTERVAL = 1.0f; +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("panel_performance_main"); + mNearbyPanel = getChild("panel_performance_nearby"); + mComplexityPanel = getChild("panel_performance_complexity"); + mSettingsPanel = getChild("panel_performance_preferences"); + mHUDsPanel = getChild("panel_performance_huds"); + + getChild("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel)); + getChild("complexity_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mComplexityPanel)); + getChild("settings_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel)); + getChild("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel)); + + initBackBtn(mNearbyPanel); + initBackBtn(mComplexityPanel); + initBackBtn(mSettingsPanel); + initBackBtn(mHUDsPanel); + + mHUDList = mHUDsPanel->getChild("hud_list"); + mHUDList->setNameListType(LLNameListCtrl::SPECIAL); + mHUDList->setHoverIconName("StopReload_Off"); + mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); + + mObjectList = mComplexityPanel->getChild("obj_list"); + mObjectList->setNameListType(LLNameListCtrl::SPECIAL); + mObjectList->setHoverIconName("StopReload_Off"); + mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); + + mSettingsPanel->getChild("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this)); + mSettingsPanel->getChild("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2)); + + mNearbyPanel->getChild("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); + mNearbyPanel->getChild("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this)); + mNearbyPanel->getChild("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR)); + mNearbyList = mNearbyPanel->getChild("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("IndirectMaxComplexity")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxComplexity, this)); + + LLAvatarComplexityControls::setIndirectMaxArc(); + + return TRUE; +} + +void LLFloaterPerformance::showSelectedPanel(LLPanel* selected_panel) +{ + hidePanels(); + mMainPanel->setVisible(FALSE); + selected_panel->setVisible(TRUE); + + if (mHUDsPanel == selected_panel) + { + populateHUDList(); + } + else if (mNearbyPanel == selected_panel) + { + populateNearbyList(); + } + else if (mComplexityPanel == selected_panel) + { + populateObjectList(); + } +} + +void LLFloaterPerformance::draw() +{ + const S32 NUM_PERIODS = 50; + + if (mUpdateTimer->hasExpired()) + { + getChild("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMedianPerSec(LLStatViewer::FPS, NUM_PERIODS))); + if (mHUDsPanel->getVisible()) + { + populateHUDList(); + } + else if (mNearbyPanel->getVisible()) + { + populateNearbyList(); + mNearbyPanel->getChild("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR)); + } + else if (mComplexityPanel->getVisible()) + { + populateObjectList(); + } + + mUpdateTimer->setTimerExpirySec(REFRESH_INTERVAL); + } + LLFloater::draw(); +} + +void LLFloaterPerformance::showMainPanel() +{ + hidePanels(); + mMainPanel->setVisible(TRUE); +} + +void LLFloaterPerformance::hidePanels() +{ + mNearbyPanel->setVisible(FALSE); + mComplexityPanel->setVisible(FALSE); + mHUDsPanel->setVisible(FALSE); + mSettingsPanel->setVisible(FALSE); +} + +void LLFloaterPerformance::initBackBtn(LLPanel* panel) +{ + panel->getChild("back_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::showMainPanel, this)); + + panel->getChild("back_lbl")->setShowCursorHand(false); + panel->getChild("back_lbl")->setSoundFlags(LLView::MOUSE_UP); + panel->getChild("back_lbl")->setClickedCallback(boost::bind(&LLFloaterPerformance::showMainPanel, this)); +} + +void LLFloaterPerformance::populateHUDList() +{ + S32 prev_pos = mHUDList->getScrollPos(); + LLUUID prev_selected_id = mHUDList->getSelectedSpecialId(); + 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(); + + 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; + 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; + 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; + + row[1]["column"] = "complex_value"; + row[1]["type"] = "text"; + row[1]["value"] = std::to_string(obj_cost_short); + 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"; + + LLScrollListItem* obj = mHUDList->addElement(item); + if (obj) + { + LLScrollListText* value_text = dynamic_cast(obj->getColumn(1)); + if (value_text) + { + value_text->setAlignment(LLFontGL::HCENTER); + } + } + } + mHUDList->sortByColumnIndex(1, FALSE); + mHUDList->setScrollPos(prev_pos); + mHUDList->selectItemBySpecialId(prev_selected_id); +} + +void LLFloaterPerformance::populateObjectList() +{ + S32 prev_pos = mObjectList->getScrollPos(); + LLUUID prev_selected_id = mObjectList->getSelectedSpecialId(); + 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(); + + 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; + 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; + + row[1]["column"] = "complex_value"; + row[1]["type"] = "text"; + row[1]["value"] = std::to_string(obj_cost_short); + row[1]["font"]["name"] = "SANSSERIF"; + + 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) + { + LLScrollListText* value_text = dynamic_cast(obj->getColumn(1)); + if (value_text) + { + value_text->setAlignment(LLFontGL::HCENTER); + } + } + } + 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); + + static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); + std::vector valid_nearby_avs; + getNearbyAvatars(valid_nearby_avs); + + std::vector::iterator char_iter = valid_nearby_avs.begin(); + while (char_iter != valid_nearby_avs.end()) + { + LLVOAvatar* avatar = dynamic_cast(*char_iter); + if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance())) + { + S32 complexity_short = llmax((S32)avatar->getVisualComplexity() / 1000, 1);; + 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; + 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); + row[1]["font"]["name"] = "SANSSERIF"; + + row[2]["column"] = "name"; + row[2]["type"] = "text"; + row[2]["value"] = avatar->getFullname(); + row[2]["font"]["name"] = "SANSSERIF"; + + LLScrollListItem* av_item = mNearbyList->addElement(item); + if(av_item) + { + LLScrollListText* value_text = dynamic_cast(av_item->getColumn(1)); + if (value_text) + { + value_text->setAlignment(LLFontGL::HCENTER); + } + LLScrollListText* name_text = dynamic_cast(av_item->getColumn(2)); + if (name_text) + { + if (avatar->isSelf()) + { + name_text->setColor(LLUIColorTable::instance().getColor("DrYellow")); + } + else + { + std::string color = "white"; + if (LLVOAvatar::AOA_JELLYDOLL == avatar->getOverallAppearance()) + { + color = "LabelDisabledColor"; + LLScrollListBar* bar = dynamic_cast(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)); + } + } + } + } + char_iter++; + } + mNearbyList->sortByColumnIndex(1, FALSE); + mNearbyList->setScrollPos(prev_pos); + mNearbyList->selectByID(prev_selected_id); +} + +void LLFloaterPerformance::getNearbyAvatars(std::vector &valid_nearby_avs) +{ + static LLCachedControl render_far_clip(gSavedSettings, "RenderFarClip", 64); + mNearbyMaxComplexity = 0; + F32 radius = render_far_clip * render_far_clip; + std::vector::iterator char_iter = LLCharacter::sInstances.begin(); + while (char_iter != LLCharacter::sInstances.end()) + { + LLVOAvatar* avatar = dynamic_cast(*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); +} + +void LLFloaterPerformance::onClickAdvanced() +{ + LLFloaterPreference* instance = LLFloaterReg::getTypedInstance("preferences"); + if (instance) + { + instance->saveSettings(); + } + LLFloaterReg::showInstance("prefs_graphics_advanced"); +} + +void LLFloaterPerformance::onChangeQuality(const LLSD& data) +{ + LLFloaterPreference* instance = LLFloaterReg::getTypedInstance("preferences"); + if (instance) + { + instance->onChangeQuality(data); + } +} + +void LLFloaterPerformance::onClickHideAvatars() +{ + LLPipeline::toggleRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR); +} + +void LLFloaterPerformance::onClickExceptions() +{ + LLFloaterReg::showInstance("avatar_render_settings"); +} + +void LLFloaterPerformance::updateMaxComplexity() +{ + LLAvatarComplexityControls::updateMax( + mNearbyPanel->getChild("IndirectMaxComplexity"), + mNearbyPanel->getChild("IndirectMaxComplexityText"), + true); +} + +void LLFloaterPerformance::updateComplexityText() +{ + LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), + mNearbyPanel->getChild("IndirectMaxComplexityText", true), + 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(); + + LLVOAvatar::VisualMuteSettings new_setting = LLVOAvatar::AV_RENDER_NORMALLY; + if ("default" == command_name) + { + new_setting = LLVOAvatar::AV_RENDER_NORMALLY; + } + else if ("never" == command_name) + { + new_setting = LLVOAvatar::AV_DO_NOT_RENDER; + } + else if ("always" == command_name) + { + new_setting = LLVOAvatar::AV_ALWAYS_RENDER; + } + + LLVOAvatar *avatarp = find_avatar(av_id); + if (avatarp) + { + avatarp->setVisualMuteSettings(new_setting); + } + else + { + FSAvatarRenderPersistence::instance().setAvatarRenderSettings(av_id, new_setting); + } +} + + +bool LLFloaterPerformance::isActionChecked(const LLSD& userdata, const LLUUID& av_id) +{ + const std::string command_name = userdata.asString(); + + auto visual_setting = FSAvatarRenderPersistence::instance().getAvatarRenderSettings(av_id); + + if ("default" == command_name) + { + return (visual_setting == LLVOAvatar::AV_RENDER_NORMALLY); + } + else if ("non_default" == command_name) + { + return (visual_setting != LLVOAvatar::AV_RENDER_NORMALLY); + } + else if ("never" == command_name) + { + return (visual_setting == LLVOAvatar::AV_DO_NOT_RENDER); + } + else if ("always" == command_name) + { + return (visual_setting == LLVOAvatar::AV_ALWAYS_RENDER); + } + return false; +} + +void LLFloaterPerformance::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y) +{ + LLNameListCtrl* list = dynamic_cast(ctrl); + if (!list) return; + list->selectItemAt(x, y, MASK_NONE); + uuid_vec_t selected_uuids; + + if((list->getCurrentID().notNull()) && (list->getCurrentID() != gAgentID)) + { + 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 new file mode 100644 index 0000000000..a5549685f6 --- /dev/null +++ b/indra/newview/llfloaterperformance.h @@ -0,0 +1,89 @@ +/** + * @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" +#include "lllistcontextmenu.h" + +class LLCharacter; +class LLNameListCtrl; + +class LLFloaterPerformance : public LLFloater +{ +public: + LLFloaterPerformance(const LLSD& key); + virtual ~LLFloaterPerformance(); + + /*virtual*/ BOOL postBuild(); + /*virtual*/ void draw(); + + void showSelectedPanel(LLPanel* selected_panel); + void showMainPanel(); + void hidePanels(); + + 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(); + void populateObjectList(); + void populateNearbyList(); + + void onClickAdvanced(); + void onChangeQuality(const LLSD& data); + void onClickHideAvatars(); + void onClickExceptions(); + + void updateMaxComplexity(); + void updateComplexityText(); + + void getNearbyAvatars(std::vector &valid_nearby_avs); + + LLPanel* mMainPanel; + LLPanel* mNearbyPanel; + LLPanel* mComplexityPanel; + LLPanel* mHUDsPanel; + LLPanel* mSettingsPanel; + LLNameListCtrl* mHUDList; + LLNameListCtrl* mObjectList; + LLNameListCtrl* mNearbyList; + + LLListContextMenu* mContextMenu; + + LLTimer* mUpdateTimer; + + S32 mNearbyMaxComplexity; + + boost::signals2::connection mComplexityChangedSignal; +}; + +#endif // LL_LLFLOATERPERFORMANCE_H diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 8a63756457..42593589e9 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -53,6 +53,7 @@ #include "llfloaterreg.h" #include "llfloaterabout.h" #include "llfavoritesbar.h" +#include "llfloaterpreferencesgraphicsadvanced.h" #include "llfloatersidepanelcontainer.h" // [FS communication UI] //#include "llfloaterimsession.h" @@ -84,7 +85,6 @@ #include "llviewereventrecorder.h" #include "llviewermessage.h" #include "llviewerwindow.h" -#include "llviewershadermgr.h" #include "llviewerthrottle.h" #include "llvoavatarself.h" #include "llvotree.h" @@ -108,11 +108,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" @@ -128,8 +126,6 @@ #include "llpresetsmanager.h" #include "llviewercontrol.h" #include "llpresetsmanager.h" -#include "llfeaturemanager.h" -#include "llviewertexturelist.h" #include "llsearchableui.h" @@ -170,7 +166,7 @@ // FIRE-19539 - Include the alert messages in Prefs>Notifications>Alerts in preference Search. #include "llfiltereditor.h" - +#include "llviewershadermgr.h" // FIRE-6340, FIRE-6567 - Setting Bandwidth issues //const F32 BANDWIDTH_UPDATER_TIMEOUT = 0.5f; char const* const VISIBILITY_DEFAULT = "default"; @@ -507,6 +503,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)); // Hook up for filtering @@ -892,6 +890,7 @@ void LLFloaterPreference::onDoNotDisturbResponseChanged() LLFloaterPreference::~LLFloaterPreference() { LLConversationLog::instance().removeObserver(this); + mComplexityChangedSignal.disconnect(); } // FIRE-19539 - Include the alert messages in Prefs>Notifications>Alerts in preference Search. @@ -1276,33 +1275,6 @@ void LLFloaterPreference::onRenderOptionEnable() refreshEnabledGraphics(); } -void LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable() -{ - LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); - if (instance) - { - instance->refresh(); - } - - refreshEnabledGraphics(); -} - -void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable() -{ - LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); - if (instance) - { - instance->refresh(); - } - - refreshEnabledGraphics(); -} - -void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledGraphics() -{ - refreshEnabledState(); -} - void LLFloaterPreference::onAvatarImpostorsEnable() { refreshEnabledGraphics(); @@ -2730,32 +2702,6 @@ void LLFloaterPreference::refresh() updateClickActionViews(); } -void LLFloaterPreferenceGraphicsAdvanced::refresh() -{ - getChild("fsaa")->setValue((LLSD::Integer) gSavedSettings.getU32("RenderFSAASamples")); - - // sliders and their text boxes - // mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow"); - // slider text boxes - updateSliderText(getChild("ObjectMeshDetail", true), getChild("ObjectMeshDetailText", true)); - updateSliderText(getChild("FlexibleMeshDetail", true), getChild("FlexibleMeshDetailText", true)); - updateSliderText(getChild("TreeMeshDetail", true), getChild("TreeMeshDetailText", true)); - updateSliderText(getChild("AvatarMeshDetail", true), getChild("AvatarMeshDetailText", true)); - updateSliderText(getChild("AvatarPhysicsDetail", true), getChild("AvatarPhysicsDetailText", true)); - updateSliderText(getChild("TerrainMeshDetail", true), getChild("TerrainMeshDetailText", true)); - updateSliderText(getChild("RenderPostProcess", true), getChild("PostProcessText", true)); - updateSliderText(getChild("SkyMeshDetail", true), getChild("SkyMeshDetailText", true)); - updateSliderText(getChild("TerrainDetail", true), getChild("TerrainDetailText", true)); - LLAvatarComplexityControls::setIndirectControls(); - setMaxNonImpostorsText( - gSavedSettings.getU32("RenderAvatarMaxNonImpostors"), - getChild("IndirectMaxNonImpostorsText", true)); - LLAvatarComplexityControls::setText( - gSavedSettings.getU32("RenderAvatarMaxComplexity"), - getChild("IndirectMaxComplexityText", true)); - refreshEnabledState(); -} - void LLFloaterPreference::onCommitWindowedMode() { refresh(); @@ -3176,7 +3122,7 @@ void LLFloaterPreferenceGraphicsAdvanced::setMaxNonImpostorsText(U32 value, LLTe } } -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 @@ -3198,10 +3144,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) { @@ -3213,7 +3159,8 @@ void LLAvatarComplexityControls::setText(U32 value, LLTextBox* text_box) //text_box->setText(llformat("%d", value)); std::string output_string; LLLocale locale(""); - LLResMgr::getInstance()->getIntegerString(output_string, value); + + LLResMgr::getInstance()->getIntegerString(output_string, value/(short_val?1000:1)); text_box->setText(output_string); } } @@ -3224,14 +3171,12 @@ void LLFloaterPreference::updateMaxComplexity() LLAvatarComplexityControls::updateMax( getChild("IndirectMaxComplexity"), getChild("IndirectMaxComplexityText")); +} - LLFloaterPreferenceGraphicsAdvanced* floater_graphics_advanced = LLFloaterReg::findTypedInstance("prefs_graphics_advanced"); - if (floater_graphics_advanced) - { - LLAvatarComplexityControls::updateMax( - floater_graphics_advanced->getChild("IndirectMaxComplexity"), - floater_graphics_advanced->getChild("IndirectMaxComplexityText")); - } +void LLFloaterPreference::updateComplexityText() +{ + LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), + getChild("IndirectMaxComplexityText", true)); } bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map &label_map) @@ -3273,22 +3218,6 @@ bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map return true; } -void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity() -{ - // Called when the IndirectMaxComplexity control changes - LLAvatarComplexityControls::updateMax( - getChild("IndirectMaxComplexity"), - getChild("IndirectMaxComplexityText")); - - LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance("preferences"); - if (floater_preferences) - { - LLAvatarComplexityControls::updateMax( - floater_preferences->getChild("IndirectMaxComplexity"), - floater_preferences->getChild("IndirectMaxComplexityText")); - } -} - void LLFloaterPreference::onChangeMaturity() { U8 sim_access = gSavedSettings.getU32("PreferredMaturity"); @@ -5050,18 +4979,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) @@ -5071,41 +4988,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("fsaa"); - combo->remove("8x"); - combo->remove("16x"); - } - - LLCheckBoxCtrl *use_HiDPI = getChild("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("preferences"); - if (instance) - { - instance->cancel(); - } - updateMaxComplexity(); -} - LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy() { } diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 5722332a13..c73130a95e 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -120,12 +120,10 @@ public: // updates click/double-click action controls depending on values from settings.xml void updateClickActionViews(); -// Make onBtnOk() public for settings backup panel -//protected: - void onBtnOK(const LLSD& userdata); -protected: -// - void onBtnCancel(const LLSD& userdata); + void onBtnOK(const LLSD& userdata); + void onBtnCancel(const LLSD& userdata); + +protected: //void onClickClearCache(); // Clear viewer texture cache, file cache on next startup // AO: was protected, moved to public void onClickBrowserClearCache(); // Clear web history and caches as well as viewer caches above @@ -301,6 +299,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 &label_map); static std::string sSkin; @@ -321,6 +320,8 @@ private: LLSearchEditor *mFilterEdit; std::unique_ptr< ll::prefs::SearchData > mSearchData; + boost::signals2::connection mComplexityChangedSignal; + void onUpdateFilterTerm( bool force = false ); void collectSearchableItems(); @@ -473,37 +474,11 @@ 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: - 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/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp new file mode 100644 index 0000000000..3d3ee0c1bc --- /dev/null +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp @@ -0,0 +1,468 @@ +/** + * @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" +#include "llviewercontrol.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() +{ + mComplexityChangedSignal.disconnect(); +} + +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("fsaa"); + combo->remove("8x"); + combo->remove("16x"); + } + + LLCheckBoxCtrl *use_HiDPI = getChild("use HiDPI"); + use_HiDPI->setVisible(FALSE); +#endif + + mComplexityChangedSignal = gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreferenceGraphicsAdvanced::updateComplexityText, this)); + + return TRUE; +} + +void LLFloaterPreferenceGraphicsAdvanced::onOpen(const LLSD& key) +{ + refresh(); +} + +void LLFloaterPreferenceGraphicsAdvanced::onClickCloseBtn(bool app_quitting) +{ + LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); + if (instance) + { + instance->cancel(); + } + updateMaxComplexity(); +} + +void LLFloaterPreferenceGraphicsAdvanced::onRenderOptionEnable() +{ + LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); + if (instance) + { + instance->refresh(); + } + + refreshEnabledGraphics(); +} + +void LLFloaterPreferenceGraphicsAdvanced::onAdvancedAtmosphericsEnable() +{ + LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); + if (instance) + { + instance->refresh(); + } + + refreshEnabledGraphics(); +} + +void LLFloaterPreferenceGraphicsAdvanced::refresh() +{ + getChild("fsaa")->setValue((LLSD::Integer) gSavedSettings.getU32("RenderFSAASamples")); + + // sliders and their text boxes + // mPostProcess = gSavedSettings.getS32("RenderGlowResolutionPow"); + // slider text boxes + updateSliderText(getChild("ObjectMeshDetail", true), getChild("ObjectMeshDetailText", true)); + updateSliderText(getChild("FlexibleMeshDetail", true), getChild("FlexibleMeshDetailText", true)); + updateSliderText(getChild("TreeMeshDetail", true), getChild("TreeMeshDetailText", true)); + updateSliderText(getChild("AvatarMeshDetail", true), getChild("AvatarMeshDetailText", true)); + updateSliderText(getChild("AvatarPhysicsDetail", true), getChild("AvatarPhysicsDetailText", true)); + updateSliderText(getChild("TerrainMeshDetail", true), getChild("TerrainMeshDetailText", true)); + updateSliderText(getChild("RenderPostProcess", true), getChild("PostProcessText", true)); + updateSliderText(getChild("SkyMeshDetail", true), getChild("SkyMeshDetailText", true)); + updateSliderText(getChild("TerrainDetail", true), getChild("TerrainDetailText", true)); + LLAvatarComplexityControls::setIndirectControls(); + setMaxNonImpostorsText( + gSavedSettings.getU32("RenderAvatarMaxNonImpostors"), + getChild("IndirectMaxNonImpostorsText", true)); + LLAvatarComplexityControls::setText( + gSavedSettings.getU32("RenderAvatarMaxComplexity"), + getChild("IndirectMaxComplexityText", true)); + refreshEnabledState(); +} + +void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledGraphics() +{ + refreshEnabledState(); +} + +void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity() +{ + // Called when the IndirectMaxComplexity control changes + LLAvatarComplexityControls::updateMax( + getChild("IndirectMaxComplexity"), + getChild("IndirectMaxComplexityText")); +} + +void LLFloaterPreferenceGraphicsAdvanced::updateComplexityText() +{ + LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), + getChild("IndirectMaxComplexityText", true)); +} + +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("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("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("Reflections"); + LLTextBox* reflections_text = getChild("ReflectionsText"); + LLCheckBoxCtrl* ctrl_avatar_vp = getChild("AvatarVertexProgram"); + LLCheckBoxCtrl* ctrl_avatar_cloth = getChild("AvatarCloth"); + LLCheckBoxCtrl* ctrl_wind_light = getChild("WindLightUseAtmosShaders"); + LLCheckBoxCtrl* ctrl_deferred = getChild("UseLightShaders"); + LLComboBox* ctrl_shadows = getChild("ShadowDetail"); + LLTextBox* shadows_text = getChild("RenderShadowDetailText"); + LLCheckBoxCtrl* ctrl_ssao = getChild("UseSSAO"); + LLCheckBoxCtrl* ctrl_dof = getChild("UseDoF"); + LLSliderCtrl* sky = getChild("SkyMeshDetail"); + LLTextBox* sky_text = getChild("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("Reflections"); + LLTextBox* reflections_text = getChild("ReflectionsText"); + + // Reflections + BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps; + ctrl_reflections->setEnabled(reflections); + reflections_text->setEnabled(reflections); + + // Transparent Water + LLCheckBoxCtrl* transparent_water_ctrl = getChild("TransparentWater"); + + // Bump & Shiny + LLCheckBoxCtrl* bumpshiny_ctrl = getChild("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("AvatarVertexProgram"); + // Avatar Render Mode + LLCheckBoxCtrl* ctrl_avatar_cloth = getChild("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("TerrainDetail"); // can be linked with control var + LLTextBox* terrain_text = getChild("TerrainDetailText"); + + terrain_detail->setEnabled(FALSE); + terrain_text->setEnabled(FALSE); + + // WindLight + LLCheckBoxCtrl* ctrl_wind_light = getChild("WindLightUseAtmosShaders"); + LLSliderCtrl* sky = getChild("SkyMeshDetail"); + LLTextBox* sky_text = getChild("SkyMeshDetailText"); + ctrl_wind_light->setEnabled(TRUE); + sky->setEnabled(TRUE); + sky_text->setEnabled(TRUE); + + //Deferred/SSAO/Shadows + LLCheckBoxCtrl* ctrl_deferred = getChild("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("UseSSAO"); + LLCheckBoxCtrl* ctrl_dof = getChild("UseDoF"); + LLComboBox* ctrl_shadow = getChild("ShadowDetail"); + LLTextBox* shadow_text = getChild("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("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value()); + getChild("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("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("preferences"); + if (instance) + { + instance->onBtnOK(userdata); + } +} + +void LLFloaterPreferenceGraphicsAdvanced::onBtnCancel(const LLSD& userdata) +{ + LLFloaterPreference* instance = LLFloaterReg::getTypedInstance("preferences"); + if (instance) + { + instance->onBtnCancel(userdata); + } +} diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.h b/indra/newview/llfloaterpreferencesgraphicsadvanced.h new file mode 100644 index 0000000000..c5d21ba35b --- /dev/null +++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.h @@ -0,0 +1,65 @@ +/** + * @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 updateComplexityText(); + 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); + + boost::signals2::connection mComplexityChangedSignal; +}; + +#endif //LLFLOATERPREFERENCEGRAPHICSADVANCED_H + diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp index f82595097c..b728d3f03d 100644 --- a/indra/newview/llnamelistctrl.cpp +++ b/indra/newview/llnamelistctrl.cpp @@ -71,9 +71,11 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p) mNameColumnIndex(p.name_column.column_index), mNameColumn(p.name_column.column_name), mAllowCallingCardDrop(p.allow_calling_card_drop), - mShortNames(p.short_names) + mShortNames(p.short_names), // Fix Baker's NameListCtrl un-fix - //mPendingLookupsRemaining(0) + // mPendingLookupsRemaining(0), + mHoverIconName("Info_Small"), + mNameListType(INDIVIDUAL) {} // public @@ -140,7 +142,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; @@ -224,14 +231,16 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask) S32 column_index = getColumnIndexFromOffset(x); LLNameListItem* hit_item = dynamic_cast(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 @@ -239,13 +248,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 icon = LLUI::getUIImage("Info_Small"); + LLPointer 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); @@ -259,7 +268,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(""); @@ -336,6 +345,7 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow( // use supplied name by default std::string fullname = name_item.name; + switch(name_item.target) { case GROUP: @@ -354,8 +364,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; @@ -366,7 +378,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(); } @@ -437,7 +449,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(item)->getSpecialID() : item->getUUID(); + if (cur_id == agent_id) { idx = getItemIndex(item); break; @@ -469,6 +482,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(*it); + if (item && item->getSpecialID() == special_id) + { + item->setSelected(TRUE); + break; + } + } +} + +LLUUID LLNameListCtrl::getSelectedSpecialId() +{ + LLNameListItem* item = dynamic_cast(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 e7c11a343b..fbc86e6ab9 100644 --- a/indra/newview/llnamelistctrl.h +++ b/indra/newview/llnamelistctrl.h @@ -52,6 +52,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; @@ -74,6 +76,8 @@ protected: private: bool mIsGroup; bool mIsExperience; + + LLUUID mSpecialID; }; @@ -104,10 +108,12 @@ public: { Optional name; Optional target; + Optional special_id; NameItem() : name("name"), - target("target", INDIVIDUAL) + target("target", INDIVIDUAL), + special_id("special_id", LLUUID()) {} }; @@ -168,6 +174,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, @@ -182,6 +191,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 item); @@ -199,14 +214,24 @@ private: // Fix Baker's NameListCtrl un-fix // S32 mPendingLookupsRemaining; // namelist_complete_signal_t mNameListCompleteSignal; -// -//public: +// + std::string mHoverIconName; + e_name_type mNameListType; + + boost::signals2::signal mIconClickedSignal; + +public: +// Fix Baker's NameListCtrl un-fix // boost::signals2::connection setOnNameListCompleteCallback(boost::function onNameListCompleteCallback) // { // return mNameListCompleteSignal.connect(onNameListCompleteCallback); // } // + boost::signals2::connection setIconClickedCallback(boost::function cb) + { + return mIconClickedSignal.connect(cb); + } }; diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 393b62d61a..05abf31171 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -105,9 +105,11 @@ #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindinglinksets.h" #include "llfloaterpay.h" +#include "llfloaterperformance.h" #include "llfloaterperms.h" #include "llfloaterpostprocess.h" #include "llfloaterpreference.h" +#include "llfloaterpreferencesgraphicsadvanced.h" #include "llfloaterpreferenceviewadvanced.h" #include "llfloaterpreviewtrash.h" #include "llfloaterproperties.h" @@ -379,6 +381,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("pathfinding_linksets", "floater_pathfinding_linksets.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("pathfinding_console", "floater_pathfinding_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("people", "floater_people.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("performance", "floater_performance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("perms_default", "floater_perms_default.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("places", "floater_places.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index a39cdf709e..d96e3e1cb3 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -3868,6 +3868,8 @@ bool check_avatar_render_mode(U32 mode) return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_ALWAYS_RENDER; // [/RLVa:KB] // return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER); + case 4: + return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_RENDER_NORMALLY; default: return false; } diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index f930646d63..266ad30852 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2704,7 +2704,11 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time) && !(disable_all_render_types) && !isSelf()) // { - return; + if (!mIsControlAvatar) + { + idleUpdateNameTag( mLastRootPos ); + } + return; } // Update should be happening max once per frame. @@ -11608,8 +11612,9 @@ void LLVOAvatar::accountRenderComplexityForObject( hud_complexity_list_t& hud_complexity_list, // Show per-item complexity in COF std::map& item_complexity, - std::map& temp_item_complexity) + std::map& temp_item_complexity, // + object_complexity_list_t& object_complexity_list) { if (attached_object && !attached_object->isHUDAttachment()) { @@ -11628,12 +11633,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(); @@ -11679,8 +11684,13 @@ void LLVOAvatar::accountRenderComplexityForObject( { temp_item_complexity.insert(std::make_pair(attached_object->getID(), (U32)attachment_total_cost)); } - } // + 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); + } } } } @@ -11775,6 +11785,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; // BOM constrain number of bake requests when BOM not supported // for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++) for (U8 baked_index = 0; baked_index < getNumBakes(); baked_index++) @@ -11822,8 +11833,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity() { accountRenderComplexityForObject(volp, max_attachment_complexity, // Show per-item complexity in COF - //textures, cost, hud_complexity_list); - textures, cost, hud_complexity_list, item_complexity, temp_item_complexity); + // textures, cost, hud_complexity_list, object_complexity_list); + textures, cost, hud_complexity_list, item_complexity, temp_item_complexity, object_complexity_list); // } } @@ -11849,8 +11860,8 @@ void LLVOAvatar::calculateUpdateRenderComplexity() const LLViewerObject* attached_object = attachment_iter->get(); accountRenderComplexityForObject(attached_object, max_attachment_complexity, // Show per-item complexity in COF - //textures, cost, hud_complexity_list); - textures, cost, hud_complexity_list, item_complexity, temp_item_complexity); + // textures, cost, hud_complexity_list, object_complexity_list); + textures, cost, hud_complexity_list, item_complexity, temp_item_complexity, object_complexity_list); // } } @@ -11912,13 +11923,13 @@ void LLVOAvatar::calculateUpdateRenderComplexity() mVisualComplexity = cost; mVisualComplexityStale = false; - static LLCachedControl 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 078473be92..e2cefa9fe6 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -313,8 +313,9 @@ public: hud_complexity_list_t& hud_complexity_list, // Show per-item complexity in COF std::map& item_complexity, - std::map& temp_item_complexity); + std::map& temp_item_complexity, // + object_complexity_list_t& object_complexity_list); void calculateUpdateRenderComplexity(); static const U32 VISUAL_COMPLEXITY_UNKNOWN; void updateVisualComplexity(); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 712438cdfd..03b8ad8567 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -1270,7 +1270,7 @@ name="OutfitGalleryItemUnselected" value="0.4 0.4 0.4 1" /> @@ -1348,4 +1348,7 @@ + diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index bde3278ada..4d2154940c 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -158,6 +158,7 @@ with the same filename but different name + 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/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 @@ - - + top="0"> + relative_width="0.65" /> - + relative_width="0.35" /> + + + 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..84ee9d3c00 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_performance.xml @@ -0,0 +1,307 @@ + + + + + + 167 + + + frames per second + + + Allow 5-10 seconds for + + + changes to take full effect. + + + + + + + Graphics settings + + + Choose settings for distance, water, lighting and more. + + + + + + Avatars nearby + + + Manage which nearby avatars are fully displayed. + + + + + + Your avatar complexity + + + Reduce the complexity of your avatar if you aren't satisfied with current FPS. + + + + + + Your active HUDs + + + Removing HUDs you are not using can improve speed. + + + + + + + + + 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 bcb916ff46..403e32daab 100644 --- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml +++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml @@ -167,20 +167,13 @@ - + - - - - + name="AlwaysRenderFully" + label="Always full detail"> @@ -189,8 +182,8 @@ parameter="1" /> + name="DoNotRender" + label="Never full detail"> @@ -198,7 +191,20 @@ function="Avatar.SetImpostorMode" parameter="2" /> - + function="Avatar.CheckImpostorMode" + parameter="4" /> + function="Avatar.SetImpostorMode" + parameter="0" /> + + + + + + - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + - - - - - + - - + + + + + + + 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 a9d4c6a47b..d4f77108ab 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"> diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 0c26664b04..66c0833be8 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -1198,7 +1198,16 @@ parameter="UseDebugMenus" /> - + + + + + + + + Back + + + Your avatar complexity + + + Attachments make your avatar more complex. If your avatar is very complex, some other + + + people may not see you in full detail, and your graphics speed may be reduced. Removing + + + heavy attachments that you don’t need can help. + + + + + + + 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..eea6b79e30 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_performance_huds.xml @@ -0,0 +1,93 @@ + + + + + Back + + + Your active HUDs + + + Detaching HUDs you aren't using saves memory and can make Second Life run faster. + + + Note: Using a HUD's minimize button does not detach it. + + + + + + + + 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..e1aef13717 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_performance_nearby.xml @@ -0,0 +1,214 @@ + + + + + Back + + + Avatars nearby + + + Hide the most complex avatars to boost speed. + + + + + 0 + + + + + + + + You can also right-click on an avatar in-world to control display. + + + + + + + + + Name tags: + + + + + + + + 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..221dfa0222 --- /dev/null +++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml @@ -0,0 +1,553 @@ + + + + + Back + + + Graphics settings + +