From 10a770047d90045e882a65e5347da3530b189c42 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine 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 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("panel_performance_main"); + mTroubleshootingPanel = getChild("panel_performance_troubleshooting"); + mNearbyPanel = getChild("panel_performance_nearby"); + mScriptsPanel = getChild("panel_performance_scripts"); + mPreferencesPanel = getChild("panel_performance_preferences"); + mHUDsPanel = getChild("panel_performance_huds"); + + getChild("troubleshooting_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mTroubleshootingPanel)); + getChild("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel)); + getChild("scripts_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mScriptsPanel)); + getChild("preferences_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mPreferencesPanel)); + getChild("huds_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mHUDsPanel)); + + initBackBtn(mTroubleshootingPanel); + initBackBtn(mNearbyPanel); + initBackBtn(mScriptsPanel); + initBackBtn(mPreferencesPanel); + initBackBtn(mHUDsPanel); + + + mHUDsPanel->getChild("refresh_list_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::populateHUDList, this)); + + mHUDList = mHUDsPanel->getChild("hud_list"); + mHUDList->setNameListType(LLNameListCtrl::SPECIAL); + mHUDList->setHoverIconName("StopReload_Off"); + mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); + + mPreferencesPanel->getChild("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this)); + mPreferencesPanel->getChild("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickRecommended, this)); + + mNearbyPanel->getChild("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); + mNearbyList = mNearbyPanel->getChild("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("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() +{ + 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("huds_value")->setValue(std::to_string(complexity_list.size())); +} + +void LLFloaterPerformance::populateNearbyList() +{ + mNearbyList->clearRows(); + mNearbyList->updateColumns(true); + + 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()) + { + 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(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 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); @@ -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(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 name; Optional target; + Optional 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 item); @@ -186,6 +198,11 @@ private: S32 mPendingLookupsRemaining; namelist_complete_signal_t mNameListCompleteSignal; + + std::string mHoverIconName; + e_name_type mNameListType; + + boost::signals2::signal mIconClickedSignal; public: boost::signals2::connection setOnNameListCompleteCallback(boost::function onNameListCompleteCallback) @@ -193,6 +210,10 @@ public: 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 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); 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/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 @@ + + 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 + + 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 @@ + + + + + Current FPS + + + 75.2 + + + + + + + + Client: + + + Network: + + + Server: + + + Normal + + + Normal + + + Normal + + + + General troubleshooting + + + Choose among common problems and see what you can do. + + + + + + Avatars nearby: + + + 42 (very high) + + + Click to review avatars and choose a complexity limit. + + + + + + This location is + + + very complex + + + Try changing graphics quality or draw distance. + + + + + + Your avatar: + + + 12 scripts + + + Removing high-impact attachments may improve graphics speed. + + + + + + Your HUDs: + + + 7 + + + Removing HUDs you are not using can improve graphics speed. + + + + + + + + + + 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 @@ + + + + + + + Back + + + HUDs displayed: + + + 7 + + + If there are any you don't need, detaching them may improve graphics speed. + + + Note: Using a HUD's minimize button does not save memory. + + + + + + + + + Back + + + Avatars within draw distance: + + + 42 (very high) + + + Some avatars nearby are slow to display. Choosing complexity limit may help graphics speed. + + + + + + 0 + + + + + + + + You can also right-click on an avatar to control display. + + + + + + + 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 @@ + + + + + Back + + + This location is very complex + + + While you are here, you may want to reduce graphics quality or draw distance. + + + + Graphics quality + + + Fastest + + + + + Best quality + + + Enhancements + + + + + + + Draw distance + + + Faster + + + + m + + + Farther + + + Regions are 256 m x 256 m. + + + To zoom out and see long distances, increase the draw distance. + + + If you are socializing in a small area, decrease the draw distance. + + + + + Back + + + Avatar attachment scripts: + + + 12 + + + These attachments contain scripts (embedded apps) that use memory. + + + If there are any you don't need, detaching them may improve graphics speed. + + 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 @@ + + + + + Back + + + Fixes for common problems + + + Some problems result from the complexity of the location where you are. All you can do is leave. + + + Rubberbanding + + + When you walk, your avatar may be pulled backward again and again. + + + Fix: XXXXXXX + + + Texture thrashing + + + On objects near you, you may see their surfaces get blurry, then sharp, then blurry again. + + + Fix: XXXXXXX + + + Avatars are not moving smoothly + + + Lorem ipsum dolor sit amet. + + + Fix: XXXXXXX + + + Will a better graphics card or new computer help? + + + Lorem ipsum dolor sit amet. + + + Fix: XXXXXXX + + -- cgit v1.2.3 From 0914f5c48f777705bdc57188e7372707f7977e5a Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine 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 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("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); mNearbyList = mNearbyPanel->getChild("nearby_list"); - + + updateComplexityText(); + mComplexityChangedSignal = gSavedSettings.getControl("IndirectMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this)); + mNearbyPanel->getChild("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("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(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("IndirectMaxComplexity"), + mNearbyPanel->getChild("IndirectMaxComplexityText")); +} + +void LLFloaterPerformance::updateComplexityText() +{ + LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), + mNearbyPanel->getChild("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("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(); @@ -1216,124 +1185,6 @@ void LLFloaterPreference::refreshEnabledState() getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess()); } -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(); -} - // static void LLAvatarComplexityControls::setIndirectControls() { @@ -1376,118 +1227,6 @@ void LLAvatarComplexityControls::setIndirectMaxArc() gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc); } -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 LLFloaterPreference::refresh() { LLPanel::refresh(); @@ -1503,32 +1242,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(); @@ -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("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 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("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"); @@ -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("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 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("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(); +} + +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")); + + LLFloaterPreference* floater_preferences = LLFloaterReg::findTypedInstance("preferences"); + if (floater_preferences) + { + LLAvatarComplexityControls::updateMax( + floater_preferences->getChild("IndirectMaxComplexity"), + floater_preferences->getChild("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("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..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"> - 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 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 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 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 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 @@ -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("panel_performance_main"); mTroubleshootingPanel = getChild("panel_performance_troubleshooting"); mNearbyPanel = getChild("panel_performance_nearby"); - mScriptsPanel = getChild("panel_performance_scripts"); - mPreferencesPanel = getChild("panel_performance_preferences"); + mComplexityPanel = getChild("panel_performance_complexity"); + mSettingsPanel = getChild("panel_performance_preferences"); mHUDsPanel = getChild("panel_performance_huds"); getChild("troubleshooting_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mTroubleshootingPanel)); getChild("nearby_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel)); - getChild("scripts_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mScriptsPanel)); - getChild("preferences_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mPreferencesPanel)); + 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(mTroubleshootingPanel); initBackBtn(mNearbyPanel); - initBackBtn(mScriptsPanel); - initBackBtn(mPreferencesPanel); + initBackBtn(mComplexityPanel); + initBackBtn(mSettingsPanel); initBackBtn(mHUDsPanel); - - mHUDsPanel->getChild("refresh_list_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::populateHUDList, this)); - mHUDList = mHUDsPanel->getChild("hud_list"); mHUDList->setNameListType(LLNameListCtrl::SPECIAL); mHUDList->setHoverIconName("StopReload_Off"); mHUDList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); - mPreferencesPanel->getChild("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this)); - mPreferencesPanel->getChild("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickRecommended, this)); + 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("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickRecommended, this)); mNearbyPanel->getChild("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); mNearbyList = mNearbyPanel->getChild("nearby_list"); @@ -89,6 +96,8 @@ BOOL LLFloaterPerformance::postBuild() mComplexityChangedSignal = gSavedSettings.getControl("IndirectMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this)); mNearbyPanel->getChild("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("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS))); + if (mMainPanel->getVisible()) + { + mMainPanel->getChild("huds_value")->setValue(LLHUDRenderNotifier::getInstance()->getHUDsCount()); + mMainPanel->getChild("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("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::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 (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::iterator char_iter = LLCharacter::sInstances.begin(); + while (char_iter != LLCharacter::sInstances.end()) + { + LLVOAvatar* avatar = dynamic_cast(*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("avatars_nearby_value")->setValue(desc); + } + mNearbyPanel->getChild("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 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 - - 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 @@ + + - - Current FPS - - - 75.2 - - - - - - - - Client: - - - Network: - - - Server: - - - Normal - - - Normal - - - Normal - - - - General troubleshooting - - - Choose among common problems and see what you can do. - - + top="5"> + + 75 + + + FPS -- 60 or more for the best experience + + - - Avatars nearby: - - - 42 (very high) - - - Click to review avatars and choose a complexity limit. - - - - - - This location is - - - very complex - - - Try changing graphics quality or draw distance. - - - - - + - Your avatar: - - + + Quick settings for common situations + + + Choose settings for parties, exploration, photography, and more. + + + + - 12 scripts - - + + Individual settings + + + More control over quality, visibility distance, and enhancements. + + + + - Removing high-impact attachments may improve graphics speed. - - - - - + + Nearby avatar complexity is + + + very high + + + Choose which avatars are not displayed in detail, to increase FPS. + + + + - Your HUDs: - - + + Your avatar complexity is + + + 275 + + + Reduce the complexity of your avatar if you aren't satisfied with current FPS. + + + + - 7 - - + + Your current HUDs: + + + 7 + + + Removing HUDs you are not using can improve speed. + + + + - Removing HUDs you are not using can improve graphics speed. - - + top_pad="20"> + + General troubleshooting + + + Choose among common problems and see what you can do. + + + - + top="55" /> + top="55" /> + top="55" /> + top="55" /> + top="55" /> 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 @@ + + + + + Back + + + My avatar complexity + + + Complex attachments require more time and memory to display. + + + While you are in this location, removing the most complex ones may increase speed. + + + + + + + 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 @@ - HUDs displayed: + width="135"> + Your current HUDs: - 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. - - - Back - - - Avatar attachment scripts: - - - 12 - - - These attachments contain scripts (embedded apps) that use memory. - - - If there are any you don't need, detaching them may improve graphics speed. - - 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 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 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("panel_performance_complexity"); mSettingsPanel = getChild("panel_performance_preferences"); mHUDsPanel = getChild("panel_performance_huds"); + mPresetsPanel = getChild("panel_performance_presets"); getChild("troubleshooting_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mTroubleshootingPanel)); 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)); + getChild("presets_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mPresetsPanel)); initBackBtn(mTroubleshootingPanel); initBackBtn(mNearbyPanel); initBackBtn(mComplexityPanel); initBackBtn(mSettingsPanel); initBackBtn(mHUDsPanel); + initBackBtn(mPresetsPanel); mHUDList = mHUDsPanel->getChild("hud_list"); mHUDList->setNameListType(LLNameListCtrl::SPECIAL); @@ -87,11 +90,13 @@ BOOL LLFloaterPerformance::postBuild() mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); mSettingsPanel->getChild("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this)); - mSettingsPanel->getChild("defaults_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickRecommended, this)); mNearbyPanel->getChild("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); mNearbyList = mNearbyPanel->getChild("nearby_list"); + mPresetsPanel->getChild("avatars_nearby_link")->setURLClickedCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel)); + mPresetsPanel->getChild("settings_link")->setURLClickedCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mSettingsPanel)); + updateComplexityText(); mComplexityChangedSignal = gSavedSettings.getControl("IndirectMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateComplexityText, this)); mNearbyPanel->getChild("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 max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); std::vector::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(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 max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); S32 max_complexity = 0; std::vector::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("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"/> + - This location is very complex + Individual settings + - While you are here, you may want to reduce graphics quality or draw distance. - - - Graphics quality +shortcuts - Enhancements + top_pad="15" + left="160" + name="quality_desc" + width="380"> + Choosing a shortcut will reset all manual changes you have made. - - - - + name="border2" + top_pad="15" + left="20" + width="540"/> - Draw distance + Visibility distance - Regions are 256 m x 256 m. + width="350"> + To zoom out and see long distances, increase the distance. - To zoom out and see long distances, increase the draw distance. + width="350"> + If you are indoors, decrease the distance to improve speed. + + Enhancements + + - 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. - + width="540"/> + + Back + + + Quick settings + + + Note: Quick settings will reset all manual changes you have made. + + + + + Tuned for many avatars in a room. + + + Nearby avatar complexity is high. + + + [secondlife:/// Choose avatars to show and hide] + + + + + Fewer avatars, higher visibility distance. + + + + + Good for zooming your camera far out and viewing large land areas. + + + + + Maximum quality, minimum visibility distance. + + + + For more control, try + + + [secondlife:/// Idividual Settings] + + + -- cgit v1.2.3 From f33605f8b113f1fed84564c7618630acd5c9427a Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 24 Jun 2021 16:17:04 +0300 Subject: SL-15297 WIP Implement performance floater - implement complexity bars --- indra/llui/llscrolllistcell.cpp | 73 +++++++++++++ indra/llui/llscrolllistcell.h | 21 ++++ indra/newview/llfloaterperformance.cpp | 118 ++++++++++++++++----- indra/newview/llfloaterperformance.h | 4 + .../skins/default/xui/en/floater_performance.xml | 3 + 5 files changed, 195 insertions(+), 24 deletions(-) diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 13839da400..50f0f5f820 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() == "image") + { + cell = new LLScrollListBar(cell_p); + } else // default is "text" { cell = new LLScrollListText(cell_p); @@ -165,6 +169,75 @@ 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_line_2d(left, mBottom, getWidth() - mRightPad, mBottom, mColor); + gl_line_2d(left, mBottom - 1, getWidth() - mRightPad, mBottom - 1, mColor); +} + // // LLScrollListText // diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 19576fb247..26a272b270 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; @@ -192,6 +193,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/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("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 max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); + std::vector valid_nearby_avs; + getNearbyAvatars(valid_nearby_avs); - std::vector::iterator char_iter = LLCharacter::sInstances.begin(); - while (char_iter != LLCharacter::sInstances.end()) + std::vector::iterator char_iter = valid_nearby_avs.begin(); + while (char_iter != valid_nearby_avs.end()) { LLVOAvatar* avatar = dynamic_cast(*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(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 &valid_nearby_avs) { - static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); - S32 max_complexity = 0; + static LLCachedControl render_far_clip(gSavedSettings, "RenderFarClip", 64); + 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() && !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 max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); + if (mMainPanel->getVisible()) + { + std::vector 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 &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 @@ + 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/llui/llscrolllistcell.cpp | 2 +- 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 +++++----- 7 files changed, 50 insertions(+), 16 deletions(-) diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index 50f0f5f820..c5f53823f3 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -54,7 +54,7 @@ LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_ { cell = new LLScrollListIconText(cell_p); } - else if (cell_p.type() == "image") + else if (cell_p.type() == "bar") { cell = new LLScrollListBar(cell_p); } 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("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(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 &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(*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 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" /> - 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(-) 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(*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(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 @@ Graphics quality @@ -74,21 +74,60 @@ shortcuts width="40"> Fastest - - + + + + + + + + + + + 1 + + + 2 + + + 3 + + + 4 + + + 5 + + + 6 + + + 7 + -- cgit v1.2.3 From 77aac9579170369a11f0884e16bd730f8cbb8bdb Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine 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 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("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; } @@ -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("panel_performance_main"); - mTroubleshootingPanel = getChild("panel_performance_troubleshooting"); mNearbyPanel = getChild("panel_performance_nearby"); mComplexityPanel = getChild("panel_performance_complexity"); mSettingsPanel = getChild("panel_performance_preferences"); mHUDsPanel = getChild("panel_performance_huds"); - mPresetsPanel = getChild("panel_performance_presets"); - getChild("troubleshooting_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mTroubleshootingPanel)); 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)); - getChild("presets_subpanel")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mPresetsPanel)); - initBackBtn(mTroubleshootingPanel); initBackBtn(mNearbyPanel); initBackBtn(mComplexityPanel); initBackBtn(mSettingsPanel); initBackBtn(mHUDsPanel); - initBackBtn(mPresetsPanel); mHUDList = mHUDsPanel->getChild("hud_list"); mHUDList->setNameListType(LLNameListCtrl::SPECIAL); @@ -96,12 +114,12 @@ BOOL LLFloaterPerformance::postBuild() mObjectList->setIconClickedCallback(boost::bind(&LLFloaterPerformance::detachItem, this, _1)); mSettingsPanel->getChild("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this)); + mSettingsPanel->getChild("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this)); + mSettingsPanel->getChild("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR)); mNearbyPanel->getChild("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); mNearbyList = mNearbyPanel->getChild("nearby_list"); - - mPresetsPanel->getChild("avatars_nearby_link")->setURLClickedCallback(boost::bind(&LLFloaterPerformance::showSelectedPanel, this, mNearbyPanel)); - mPresetsPanel->getChild("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("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS))); - if (mMainPanel->getVisible()) - { - mMainPanel->getChild("huds_value")->setValue(LLHUDRenderNotifier::getInstance()->getHUDsCount()); - mMainPanel->getChild("complexity_value")->setValue((S32)gAgentAvatarp->getVisualComplexity()); - updateNearbyComplexityDesc(); - } - else if (mHUDsPanel->getVisible()) + getChild("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("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("huds_value")->setValue(std::to_string(complexity_list.size())); } void LLFloaterPerformance::populateObjectList() @@ -384,32 +397,6 @@ void LLFloaterPerformance::getNearbyAvatars(std::vector &valid_nea } } -void LLFloaterPerformance::updateNearbyComplexityDesc() -{ - std::string desc = getString("low"); - - static LLCachedControl max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0); - if (mMainPanel->getVisible()) - { - std::vector 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("avatars_nearby_value")->setValue(desc); - } - mNearbyPanel->getChild("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("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(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 &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"> - - + 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 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 @@ - - - - FPS -- 60 or more for the best experience - - - - - + frames per second + - Quick settings for common situations + left="395" + top="7" + name="fps_desc1_lbl" + width="150"> + Allow 5-10 seconds for - Choose settings for parties, exploration, photography, and more. + top_pad="-3" + name="fps_desc2_lbl" + width="150"> + changes to take full effect. - + + + left="10" + top="5"> - Individual settings + Graphics settings - More control over quality, visibility distance, and enhancements. + Choose settings for distance, water, lighting and more. - Nearby avatar complexity is - - - very high + Avatars nearby - Choose which avatars are not displayed in detail, to increase FPS. + Manage which nearby avatars are fully displayed. - Your avatar complexity is - - - 275 + Your avatar complexity Reduce the complexity of your avatar if you aren't satisfied with current FPS. @@ -278,7 +222,7 @@ mouse_opaque="true" name="icon_arrow4" follows="right|top" - top="24" + top="29" right="-20"/> - Your current HUDs: - - - 7 + Your active HUDs Removing HUDs you are not using can improve speed. @@ -335,72 +268,10 @@ mouse_opaque="true" name="icon_arrow4" follows="right|top" - top="24" - right="-20"/> - - - - General troubleshooting - - - Choose among common problems and see what you can do. - - - - - - - - - + - - + + + + + + + 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"> 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 - 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 - While you are in this location, removing the most complex ones may increase speed. + your own graphics speed may be reduced. - Your current HUDs: - - - 7 + Your active HUDs - 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. - Note: Using a HUD's minimize button does not save memory. + Note: Using a HUD's minimize button does not detach it. - Nearby avatar complexity is - - - very high + Avatars nearby - 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. - Individual settings + Graphics settings - Graphics quality -shortcuts + Shortcuts - To zoom out and see long distances, increase the distance. - - - If you are indoors, decrease the distance to improve speed. + To see more land when you zoom out, increase the distance. - Enhancements + Environment - + + + Shadows: + + + + + + + + + Water + + + Reducing or turning off water effects can greatly improve frame rate. + - - Shadows: - - + - - - - + top_pad="20" + left="20" + name="photo_lbl" + width="100"> + Photography + - [secondlife:/// What do these settings mean?] + Maximum detail is good for photos, but can slow frame rate. + + + + (Enter value between 0.0 and 4.0) + + 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 @@ - - - - - Back - - - Quick settings - - - Note: Quick settings will reset all manual changes you have made. - - - - - Tuned for many avatars in a room. - - - Nearby avatar complexity is high. - - - [secondlife:/// Choose avatars to show and hide] - - - - - Fewer avatars, higher visibility distance. - - - - - Good for zooming your camera far out and viewing large land areas. - - - - - Maximum quality, minimum visibility distance. - - - - For more control, try - - - [secondlife:/// Idividual Settings] - - - 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 @@ - - - - - Back - - - Fixes for common problems - - - Some problems result from the complexity of the location where you are. All you can do is leave. - - - Rubberbanding - - - When you walk, your avatar may be pulled backward again and again. - - - Fix: XXXXXXX - - - Texture thrashing - - - On objects near you, you may see their surfaces get blurry, then sharp, then blurry again. - - - Fix: XXXXXXX - - - Avatars are not moving smoothly - - - Lorem ipsum dolor sit amet. - - - Fix: XXXXXXX - - - Will a better graphics card or new computer help? - - - Lorem ipsum dolor sit amet. - - - Fix: XXXXXXX - - -- cgit v1.2.3 From 84ae60a3b34d92930a74e9207bf39e6335e307a0 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 16 Jul 2021 16:32:12 +0300 Subject: SL-15581 Add the function to get median FPS --- indra/llcommon/lltracerecording.h | 25 +++++++++++++++++++++++++ indra/newview/llfloaterperformance.cpp | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) 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/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("fps_value")->setValue((S32)llround(LLTrace::get_frame_recording().getPeriodMeanPerSec(LLStatViewer::FPS, NUM_PERIODS))); + getChild("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 Date: Mon, 19 Jul 2021 20:07:03 +0300 Subject: SL-15297 performance floater UI update #2 --- indra/llui/llscrolllistcell.cpp | 3 +- indra/llui/llscrolllistcell.h | 1 + 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 +- 16 files changed, 249 insertions(+), 158 deletions(-) diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp index c5f53823f3..61470d1440 100644 --- a/indra/llui/llscrolllistcell.cpp +++ b/indra/llui/llscrolllistcell.cpp @@ -234,8 +234,7 @@ void LLScrollListBar::draw(const LLColor4& color, const LLColor4& highlight_colo S32 left = bar_width - bar_width * mRatio; left = llclamp(left, mLeftPad, getWidth() - mRightPad - 1); - gl_line_2d(left, mBottom, getWidth() - mRightPad, mBottom, mColor); - gl_line_2d(left, mBottom - 1, getWidth() - mRightPad, mBottom - 1, mColor); + gl_rect_2d(left, mBottom, getWidth() - mRightPad, mBottom - 1, mColor); } // diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h index 26a272b270..9a659dfd0d 100644 --- a/indra/llui/llscrolllistcell.h +++ b/indra/llui/llscrolllistcell.h @@ -154,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; 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("advanced_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickAdvanced, this)); - mSettingsPanel->getChild("hide_avatars")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickHideAvatars, this)); - mSettingsPanel->getChild("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR)); 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)); @@ -164,15 +164,12 @@ void LLFloaterPerformance::draw() else if (mNearbyPanel->getVisible()) { populateNearbyList(); + mNearbyPanel->getChild("hide_avatars")->set(!LLPipeline::hasRenderTypeControl(LLPipeline::RENDER_TYPE_AVATAR)); } else if (mComplexityPanel->getVisible()) { populateObjectList(); } - else if (mSettingsPanel->getVisible()) - { - mSettingsPanel->getChild("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(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(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(*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(av_item->getColumn(1)); + if (value_text) + { + value_text->setAlignment(LLFontGL::HCENTER); + } LLScrollListText* name_text = dynamic_cast(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(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(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 &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() && !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("IndirectMaxComplexity"), - mNearbyPanel->getChild("IndirectMaxComplexityText")); + mNearbyPanel->getChild("IndirectMaxComplexityText"), + true); } void LLFloaterPerformance::updateComplexityText() { LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), - mNearbyPanel->getChild("IndirectMaxComplexityText", true)); + mNearbyPanel->getChild("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 @@ @@ -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 @@ -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. @@ -130,7 +130,7 @@ mouse_opaque="true" name="icon_arrow3" follows="right|top" - top="29" + top="19" right="-20"/> + top_pad="10"> Avatars nearby @@ -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. @@ -176,7 +176,7 @@ mouse_opaque="true" name="icon_arrow2" follows="right|top" - top="29" + top="19" right="-20"/> + top_pad="10"> Your avatar complexity @@ -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. @@ -222,7 +222,7 @@ mouse_opaque="true" name="icon_arrow4" follows="right|top" - top="29" + top="19" right="-20"/> + top_pad="10"> Your active HUDs @@ -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. @@ -268,7 +268,7 @@ mouse_opaque="true" name="icon_arrow4" follows="right|top" - top="29" + top="19" right="-20"/> 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 @@ - - - - + name="Render Avatar"> + label="Always full detail"> @@ -156,7 +146,7 @@ + label="Never full detail"> @@ -164,6 +154,16 @@ function="Avatar.SetImpostorMode" parameter="1" /> + + + + - - - - - - - - - - - - + name="Render Avatar"> + + + + + + + + + + + + - - - - + + + Date: Wed, 19 Jan 2022 13:49:04 -0800 Subject: SL-16862: Adjust max zoom-in level on world map to match max zoom-in on minimap --- indra/newview/skins/default/xui/en/floater_world_map.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/skins/default/xui/en/floater_world_map.xml b/indra/newview/skins/default/xui/en/floater_world_map.xml index d7e4b88a21..eb633e50e7 100644 --- a/indra/newview/skins/default/xui/en/floater_world_map.xml +++ b/indra/newview/skins/default/xui/en/floater_world_map.xml @@ -685,7 +685,7 @@ initial_value="-2" left_pad="0" layout="topleft" - max_val="0" + max_val="4" min_val="-8" name="zoom slider" show_text="false" -- cgit v1.2.3 From 808684ee4fe0d9ed3868d0ee86d9cc28f32fcfcb Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine 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(-) 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 @@ Value 0.5 + RenderShadowSplits + + Comment + Amount of shadow map splits to render (0 - 3). + Persist + 1 + Type + S32 + Value + 3 + RenderSSAOScale Comment 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 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& 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 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(-) 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"> + Date: Tue, 22 Feb 2022 09:47:43 -0800 Subject: SL-9748 - Option to compute uploaded mesh physics shape from a cube. --- indra/newview/cube.dae | 103 +++++++++++++++++++++ indra/newview/llfloatermodelpreview.cpp | 23 +++-- indra/newview/llfloatermodelpreview.h | 1 + .../skins/default/xui/en/floater_model_preview.xml | 1 + indra/newview/viewer_manifest.py | 1 + 5 files changed, 121 insertions(+), 8 deletions(-) create mode 100644 indra/newview/cube.dae diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae new file mode 100644 index 0000000000..f9df955ff2 --- /dev/null +++ b/indra/newview/cube.dae @@ -0,0 +1,103 @@ + + + + + modified from https://gist.github.com/wtsnz/bfa11c40e04594b260255b5dc7956f26 + + 2018-10-25T16:29:03Z + 2022-02-18T00:00:00Z + + Y_UP + + + + + + + + + + + + + + + + 0 0 0 1 + + + 0.137255 0.403922 0.870588 1 + + + 0.5 0.5 0.5 1 + + + 16 + + + 0 0 0 1 + + + 1 + + + 1 + + + + + + + + + + + + + + -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 -0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 -0.5 -0.5 0.5 -0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 -0.5 -0.5 0.5 0.5 -0.5 0.5 0.5 0.5 0.5 0.5 -0.5 0.5 -0.5 -0.5 -0.5 -0.5 -0.5 -0.5 0.5 -0.5 + + + + + + + + + + + + + + + +

0 1 2 0 2 3 4 5 6 4 6 7 8 9 10 8 10 11 12 13 14 12 14 15 16 17 18 16 18 19 20 21 22 20 22 23

+
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 64b24d54c3..fe4deaa657 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -455,7 +455,7 @@ void LLFloaterModelPreview::loadHighLodModel() loadModel(3); } -void LLFloaterModelPreview::loadModel(S32 lod) +void LLFloaterModelPreview::prepareToLoadModel(S32 lod) { mModelPreview->mLoading = true; if (lod == LLModel::LOD_PHYSICS) @@ -463,14 +463,16 @@ void LLFloaterModelPreview::loadModel(S32 lod) // loading physics from file mModelPreview->mPhysicsSearchLOD = lod; } - +} +void LLFloaterModelPreview::loadModel(S32 lod) +{ + prepareToLoadModel(lod); (new LLMeshFilePicker(mModelPreview, lod))->getFile(); } void LLFloaterModelPreview::loadModel(S32 lod, const std::string& file_name, bool force_disable_slm) { - mModelPreview->mLoading = true; - + prepareToLoadModel(lod); mModelPreview->loadModel(file_name, lod, force_disable_slm); } @@ -1042,10 +1044,15 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) } S32 file_mode = iface->getItemCount() - 1; - if (which_mode < file_mode) + S32 cube_mode = file_mode - 1; + if (which_mode < cube_mode) { S32 which_lod = num_lods - which_mode; sInstance->mModelPreview->setPhysicsFromLOD(which_lod); + } else if (which_mode == cube_mode) { + std::string path = gDirUtilp->getAppRODataDir(); + gDirUtilp->append(path, "cube.dae"); + sInstance->loadModel(LLModel::LOD_PHYSICS, path); } LLModelPreview *model_preview = sInstance->mModelPreview; @@ -1641,15 +1648,15 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod) { if (lod == LLModel::LOD_PHYSICS) - { + { LLComboBox* lod_combo = findChild("physics_lod_combo"); if (lod_combo) { - lod_combo->setCurrentByIndex(5); + lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1); } } else -{ + { LLComboBox* lod_combo = findChild("lod_source_" + lod_name[lod]); if (lod_combo) { diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 8a01b0c307..db7e49fd9c 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -222,6 +222,7 @@ private: void resetUploadOptions(); void clearLogTab(); + void prepareToLoadModel(S32 lod); void createSmoothComboBox(LLComboBox* combo_box, float min, float max); diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 7f863756eb..64079d1d20 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -784,6 +784,7 @@ Medium Low Lowest + Bounding Box From file Date: Tue, 22 Feb 2022 10:51:18 -0800 Subject: SL-9748 - coding standard --- indra/newview/llfloatermodelpreview.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index fe4deaa657..4ea47c1bc7 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1049,7 +1049,9 @@ void LLFloaterModelPreview::onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata) { S32 which_lod = num_lods - which_mode; sInstance->mModelPreview->setPhysicsFromLOD(which_lod); - } else if (which_mode == cube_mode) { + } + else if (which_mode == cube_mode) + { std::string path = gDirUtilp->getAppRODataDir(); gDirUtilp->append(path, "cube.dae"); sInstance->loadModel(LLModel::LOD_PHYSICS, path); @@ -1652,7 +1654,7 @@ void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod) LLComboBox* lod_combo = findChild("physics_lod_combo"); if (lod_combo) { - lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1); + lod_combo->setCurrentByIndex(lod_combo->getItemCount() - 1); } } else -- cgit v1.2.3 From 1abc02ed6b5578f758e37abb5858a24408be4c68 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 22 Feb 2022 15:24:23 -0800 Subject: SL-9748 - Place cube.dae in ppRODataDir on all platforms. --- indra/newview/viewer_manifest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 7d059f08f4..3488e7550b 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -573,6 +573,7 @@ class WindowsManifest(ViewerManifest): self.path(src="licenses-win32.txt", dst="licenses.txt") self.path("featuretable.txt") + self.path("cube.dae") with self.prefix(src=pkgdir): self.path("ca-bundle.crt") @@ -959,8 +960,8 @@ class DarwinManifest(ViewerManifest): self.path("licenses-mac.txt", dst="licenses.txt") self.path("featuretable_mac.txt") - self.path("SecondLife.nib") self.path("cube.dae") + self.path("SecondLife.nib") with self.prefix(src=pkgdir,dst=""): self.path("ca-bundle.crt") @@ -1403,6 +1404,7 @@ class LinuxManifest(ViewerManifest): print "Skipping llcommon.so (assuming llcommon was linked statically)" self.path("featuretable_linux.txt") + self.path("cube.dae") with self.prefix(src=pkgdir): self.path("ca-bundle.crt") -- cgit v1.2.3 From 34a9e84cd89e9a5a748dd5aa0cc2666bf8f6c34a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 17 Feb 2022 12:56:40 -0800 Subject: SL-16917: Fix minimap cardinal direction text being offset slightly, and move cardinal directions to the edge of the minimap --- indra/newview/llfloatermap.cpp | 64 ++++++++++++++++------ indra/newview/skins/default/xui/en/floater_map.xml | 48 +++------------- 2 files changed, 55 insertions(+), 57 deletions(-) mode change 100644 => 100755 indra/newview/llfloatermap.cpp diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp old mode 100644 new mode 100755 index fc2da772f3..7a7ffb0c7e --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -51,7 +51,7 @@ // The minor cardinal direction labels are hidden if their height is more // than this proportion of the map. -const F32 MAP_MINOR_DIR_THRESHOLD = 0.07f; +const F32 MAP_MINOR_DIR_THRESHOLD = 0.035f; // // Member functions @@ -97,6 +97,15 @@ BOOL LLFloaterMap::postBuild() mTextBoxSouthWest = getChild ("floater_map_southwest"); mTextBoxNorthWest = getChild ("floater_map_northwest"); + mTextBoxNorth->reshapeToFitText(); + mTextBoxEast->reshapeToFitText(); + mTextBoxWest->reshapeToFitText(); + mTextBoxSouth->reshapeToFitText(); + mTextBoxSouthEast->reshapeToFitText(); + mTextBoxNorthEast->reshapeToFitText(); + mTextBoxSouthWest->reshapeToFitText(); + mTextBoxNorthWest->reshapeToFitText(); + updateMinorDirections(); // Get the drag handle all the way in back @@ -138,23 +147,44 @@ BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } -void LLFloaterMap::setDirectionPos( LLTextBox* text_box, F32 rotation ) +void LLFloaterMap::setDirectionPos(LLTextBox *text_box, F32 rotation) { - // Rotation is in radians. - // Rotation of 0 means x = 1, y = 0 on the unit circle. - - F32 map_half_height = (F32)(getRect().getHeight() / 2) - getHeaderHeight()/2; - F32 map_half_width = (F32)(getRect().getWidth() / 2) ; - F32 text_half_height = (F32)(text_box->getRect().getHeight() / 2); - F32 text_half_width = (F32)(text_box->getRect().getWidth() / 2); - F32 radius = llmin( map_half_height - text_half_height, map_half_width - text_half_width ); - - // Inset by a little to account for position display. - radius -= 8.f; - - text_box->setOrigin( - ll_round(map_half_width - text_half_width + radius * cos( rotation )), - ll_round(map_half_height - text_half_height + radius * sin( rotation )) ); + // Rotation is in radians. + // Rotation of 0 means x = 1, y = 0 on the unit circle. + + F32 map_half_height = (F32) (getRect().getHeight() / 2) - (getHeaderHeight() / 2); + F32 map_half_width = (F32) (getRect().getWidth() / 2); + F32 text_half_height = (F32) (text_box->getRect().getHeight() / 2); + F32 text_half_width = (F32) (text_box->getRect().getWidth() / 2); + F32 extra_padding = (F32) (mTextBoxNorth->getRect().getWidth() / 2); + F32 pos_half_height = map_half_height - text_half_height - extra_padding; + F32 pos_half_width = map_half_width - text_half_width - extra_padding; + + F32 corner_angle = atan2(pos_half_height, pos_half_width); + F32 rotation_mirrored_into_top = abs(fmodf(rotation, F_PI)); + if (rotation < 0) + { + rotation_mirrored_into_top = F_PI - rotation_mirrored_into_top; + } + F32 rotation_mirrored_into_top_right = (F_PI_BY_TWO - abs(rotation_mirrored_into_top - F_PI_BY_TWO)); + bool at_left_right_edge = rotation_mirrored_into_top_right < corner_angle; + + F32 part_x = cos(rotation); + F32 part_y = sin(rotation); + F32 y; + F32 x; + if (at_left_right_edge) + { + x = std::copysign(pos_half_width, part_x); + y = x * part_y / part_x; + } + else + { + y = std::copysign(pos_half_height, part_y); + x = y * part_x / part_y; + } + + text_box->setOrigin(ll_round(map_half_width + x - text_half_width), ll_round(map_half_height + y - text_half_height)); } void LLFloaterMap::updateMinorDirections() diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index b8893e11d9..18e7147136 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -37,105 +37,73 @@ + text_color="1 1 1 0.7"> N + text_color="1 1 1 0.7"> E + text_color="1 1 1 0.7"> W + text_color="1 1 1 0.7"> S + text_color="1 1 1 0.7"> SE + text_color="1 1 1 0.7"> NE + text_color="1 1 1 0.7"> SW + text_color="1 1 1 0.7"> NW -- cgit v1.2.3 From 898079a39bc86598d8e998a24845d0932c88cdca Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 25 Jan 2022 17:25:46 -0800 Subject: SL-16857: Display parcel borders on the minimap, enable by default, right click context menu option to disable --- indra/newview/app_settings/settings.xml | 11 ++++ indra/newview/llnetmap.cpp | 20 +++++-- indra/newview/llviewerparcelmgr.cpp | 2 + indra/newview/llviewerparceloverlay.cpp | 64 +++++++++++++++++++++- indra/newview/llviewerparceloverlay.h | 3 +- indra/newview/llviewerregion.cpp | 9 +++ indra/newview/llviewerregion.h | 2 + indra/newview/skins/default/colors.xml | 3 + .../newview/skins/default/xui/en/menu_mini_map.xml | 10 ++++ 9 files changed, 115 insertions(+), 9 deletions(-) mode change 100644 => 100755 indra/newview/llviewerparceloverlay.cpp mode change 100644 => 100755 indra/newview/llviewerregion.cpp diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 12f435f931..c170563cf7 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6821,6 +6821,17 @@ Value 128.0
+ MiniMapShowPropertyLines + + Comment + Whether or not to show parcel borders on the MiniMap. + Persist + 1 + Type + Boolean + Value + 1 + MouseSensitivity Comment diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 112da55682..80fac58a1e 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -154,6 +154,7 @@ void LLNetMap::draw() //static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); + static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f)); if (mObjectImagep.isNull()) { @@ -211,7 +212,8 @@ void LLNetMap::draw() } // figure out where agent is - S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters()); + const S32 region_width = ll_round(LLWorld::getInstance()->getRegionWidthInMeters()); + const F32 scale_pixels_per_meter = mScale / region_width; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -220,8 +222,8 @@ void LLNetMap::draw() // Find x and y position relative to camera's center. LLVector3 origin_agent = regionp->getOriginAgent(); LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); - F32 relative_x = (rel_region_pos.mV[0] / region_width) * mScale; - F32 relative_y = (rel_region_pos.mV[1] / region_width) * mScale; + F32 relative_x = rel_region_pos.mV[0] * scale_pixels_per_meter; + F32 relative_y = rel_region_pos.mV[1] * scale_pixels_per_meter; // background region rectangle F32 bottom = relative_y; @@ -244,6 +246,7 @@ void LLNetMap::draw() } + // Draw using texture. gGL.getTexUnit(0)->bind(regionp->getLand().getSTexture()); gGL.begin(LLRender::QUADS); @@ -305,8 +308,8 @@ void LLNetMap::draw() LLVector3 map_center_agent = gAgent.getPosAgentFromGlobal(mObjectImageCenterGlobal); LLVector3 camera_position = gAgentCamera.getCameraPositionAgent(); map_center_agent -= camera_position; - map_center_agent.mV[VX] *= mScale/region_width; - map_center_agent.mV[VY] *= mScale/region_width; + map_center_agent.mV[VX] *= scale_pixels_per_meter; + map_center_agent.mV[VY] *= scale_pixels_per_meter; gGL.getTexUnit(0)->bind(mObjectImagep); F32 image_half_width = 0.5f*mObjectMapPixels; @@ -322,6 +325,13 @@ void LLNetMap::draw() gGL.texCoord2f(1.f, 1.f); gGL.vertex2f(image_half_width + map_center_agent.mV[VX], image_half_height + map_center_agent.mV[VY]); gGL.end(); + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* regionp = *iter; + regionp->renderPropertyLinesOnMinimap(scale_pixels_per_meter, map_parcel_outline_color.get().mV); + } gGL.popMatrix(); diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 56370df751..a6f15489f4 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1591,6 +1591,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use else if (sequence_id == 0 || sequence_id > parcel_mgr.mAgentParcelSequenceID) { // new agent parcel + // *TODO: Does it really make sense to set the agent parcel to this + // parcel if the client doesn't know what kind of parcel data this is? parcel_mgr.mAgentParcelSequenceID = sequence_id; parcel = parcel_mgr.mAgentParcel; } diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp old mode 100644 new mode 100755 index 7c3dd00e1a..c170a240a8 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -907,8 +907,8 @@ S32 LLViewerParcelOverlay::renderPropertyLines () // Always fudge a little vertically. pull_toward_camera.mV[VZ] += 0.01f; - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); // Move to appropriate region coords LLVector3 origin = mRegion->getOriginAgent(); @@ -1013,7 +1013,65 @@ S32 LLViewerParcelOverlay::renderPropertyLines () } - gGL.popMatrix(); + gGL.popMatrix(); return drawn; } + +// Draw half of a single cell (no fill) in a grid drawn from left to right and from bottom to top +void grid_2d_part_lines(const F32 left, const F32 top, const F32 right, const F32 bottom, bool has_left, bool has_bottom) +{ + gGL.begin(LLRender::LINES); + + if (has_left) + { + gGL.vertex2f(left, bottom); + gGL.vertex2f(left, top); + } + if (has_bottom) + { + gGL.vertex2f(left, bottom); + gGL.vertex2f(right, bottom); + } + + gGL.end(); +} + +void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) +{ + if (!mOwnership) + { + return; + } + if (!gSavedSettings.getBOOL("MiniMapShowPropertyLines")) + { + return; + } + + LLVector3 origin_agent = mRegion->getOriginAgent(); + LLVector3 rel_region_pos = origin_agent - gAgentCamera.getCameraPositionAgent(); + F32 region_left = rel_region_pos.mV[0] * scale_pixels_per_meter; + F32 region_bottom = rel_region_pos.mV[1] * scale_pixels_per_meter; + F32 map_parcel_width = PARCEL_GRID_STEP_METERS * scale_pixels_per_meter; + const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + glLineWidth(1.0f); + gGL.color4fv(parcel_outline_color); + for (S32 i = 0; i < GRIDS_PER_EDGE + 1; i++) + { + F32 bottom = region_bottom + (i * map_parcel_width); + F32 top = bottom + map_parcel_width; + for (S32 j = 0; j < GRIDS_PER_EDGE + 1; j++) + { + F32 left = region_left + (j * map_parcel_width); + F32 right = left + map_parcel_width; + U8 overlay = mOwnership[(i * GRIDS_PER_EDGE) + j]; + // The property line vertices are three-dimensional, but here we only care about the x and y coordinates, as we are drawing on a + // 2D map + const bool has_left = i != GRIDS_PER_EDGE && (j == GRIDS_PER_EDGE || (overlay & PARCEL_WEST_LINE)); + const bool has_bottom = j != GRIDS_PER_EDGE && (i == GRIDS_PER_EDGE || (overlay & PARCEL_SOUTH_LINE)); + grid_2d_part_lines(left, top, right, bottom, has_left, has_bottom); + } + } +} diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index e30dbf17b3..053f69ba4c 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -69,6 +69,7 @@ public: // Returns the number of vertices drawn S32 renderPropertyLines(); + void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); U8 ownership( const LLVector3& pos) const; U8 parcelLineFlags( const LLVector3& pos) const; @@ -82,7 +83,7 @@ public: void idleUpdate(bool update_now = false); void updateGL(); - + private: // This is in parcel rows and columns, not grid rows and columns // Stored in bottom three bits. diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp old mode 100644 new mode 100755 index 0f409701d1..36b0bf44c3 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -1033,6 +1033,15 @@ S32 LLViewerRegion::renderPropertyLines() } } +void LLViewerRegion::renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32 *parcel_outline_color) +{ + if (mParcelOverlay) + { + mParcelOverlay->renderPropertyLinesOnMinimap(scale_pixels_per_meter, parcel_outline_color); + } +} + + // This gets called when the height field changes. void LLViewerRegion::dirtyHeights() { diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index fcbf56c81f..b6c8f5c583 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -154,6 +154,8 @@ public: // Draw lines in the dirt showing ownership. Return number of // vertices drawn. S32 renderPropertyLines(); + void renderPropertyLinesOnMinimap(F32 scale_pixels_per_meter, const F32* parcel_outline_color); + // Call this whenever you change the height data in the region. // (Automatically called by LLSurfacePatch's update routine) diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 7beb013fba..82e1942aa5 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -513,6 +513,9 @@ + diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml index ea263d05ce..c3899b35cd 100644 --- a/indra/newview/skins/default/xui/en/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml @@ -63,6 +63,16 @@ function="Minimap.Tracker" parameter="task_properties" />
+ + + + + Date: Fri, 25 Feb 2022 18:32:55 -0800 Subject: SL-9748 - Apply explicitly given physics shape only if the usual rules do not. --- indra/newview/llmodelpreview.cpp | 16 +++++++++++++++- indra/newview/llmodelpreview.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index a9e80ab5da..a1420fba17 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -529,6 +529,16 @@ void LLModelPreview::rebuildUploadData() LLFloaterModelPreview::addStringToLog(out, false); } } + if (!mLastSpecifiedPhysicsModelOriginalName.empty() && !lod_model && (i == LLModel::LOD_PHYSICS)) + { + // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition. + // That's ok, but in the case where someone supplied a physics file, that's probably not what they wanted. + std::ostringstream out; + out << "Reusing previously matched physics model " << mLastSpecifiedPhysicsModelOriginalName; + LL_INFOS() << out.str() << LL_ENDL; + LLFloaterModelPreview::addStringToLog(out, false); + lod_model = mLastSpecifiedPhysicsP; + } if (lod_model) { @@ -1185,7 +1195,11 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) LL_WARNS() << out.str() << LL_ENDL; LLFloaterModelPreview::addStringToLog(out, false); } - + if (loaded_lod == LLModel::LOD_PHYSICS) + { + mLastSpecifiedPhysicsModelOriginalName = loaded_name; + mLastSpecifiedPhysicsP = mModel[loaded_lod][idx]; + } mModel[loaded_lod][idx]->mLabel = name; } } diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 3664a27a72..5a9fc93879 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -217,6 +217,8 @@ private: LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; } // Count amount of original models, excluding sub-models static U32 countRootModels(LLModelLoader::model_list models); + LLModel* mLastSpecifiedPhysicsP{}; // As opposed to being found by name or LOD; + std::string mLastSpecifiedPhysicsModelOriginalName{""}; // Since the above will have it's label bashed. protected: friend class LLModelLoader; -- cgit v1.2.3 From 932b7de5309bc8599655ebb77666c41f5a81cfa9 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 28 Feb 2022 15:47:56 -0800 Subject: SL-9748 - Handle submesh case of resuseable physics model. --- indra/newview/llmodelpreview.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index a1420fba17..f3b6207488 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -529,12 +529,12 @@ void LLModelPreview::rebuildUploadData() LLFloaterModelPreview::addStringToLog(out, false); } } - if (!mLastSpecifiedPhysicsModelOriginalName.empty() && !lod_model && (i == LLModel::LOD_PHYSICS)) + if (mLastSpecifiedPhysicsP && !lod_model && (i == LLModel::LOD_PHYSICS)) { // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition. // That's ok, but in the case where someone supplied a physics file, that's probably not what they wanted. std::ostringstream out; - out << "Reusing previously matched physics model " << mLastSpecifiedPhysicsModelOriginalName; + out << "Reusing physics model " << mLastSpecifiedPhysicsModelOriginalName << " for " << instance.mLabel; LL_INFOS() << out.str() << LL_ENDL; LLFloaterModelPreview::addStringToLog(out, false); lod_model = mLastSpecifiedPhysicsP; @@ -1204,6 +1204,11 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) } } } + else if ((loaded_lod == LLModel::LOD_PHYSICS) && (mModel[loaded_lod].size() == 1)) + { + mLastSpecifiedPhysicsModelOriginalName = stripSuffix(mModel[loaded_lod][0]->mLabel); + mLastSpecifiedPhysicsP = mModel[loaded_lod][0]; + } } } } -- cgit v1.2.3 From 064f28b290026be0e77cd38de78b06477a9c0876 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 2 Mar 2022 00:47:02 +0200 Subject: merge fix --- indra/newview/llmodelpreview.cpp | 2 -- 1 file changed, 2 deletions(-) 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 239a29ab5c67bef8ffc773b0f405d8cc4542cf34 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Wed, 2 Mar 2022 17:39:12 -0800 Subject: SL-9748 - more cases --- indra/newview/llfloatermodelpreview.cpp | 1 + indra/newview/llmodelpreview.cpp | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 71ae31e665..4a51533a57 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -483,6 +483,7 @@ void LLFloaterModelPreview::prepareToLoadModel(S32 lod) { // loading physics from file mModelPreview->mPhysicsSearchLOD = lod; + mModelPreview->mLastSpecifiedPhysicsP = NULL; } } void LLFloaterModelPreview::loadModel(S32 lod) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 54a0c1a5bb..4e3b4c5c41 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -470,8 +470,8 @@ void LLModelPreview::rebuildUploadData() // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition. // That's ok, but in the case where someone supplied a physics file, that's probably not what they wanted. std::ostringstream out; - out << "Reusing physics model " << mLastSpecifiedPhysicsModelOriginalName << " for " << instance.mLabel; - LL_INFOS() << out.str() << LL_ENDL; + out << "No physics model specified for " << instance.mLabel << ". Reusing physics model " << mLastSpecifiedPhysicsModelOriginalName << "."; + LL_WARNS() << out.str() << LL_ENDL; LLFloaterModelPreview::addStringToLog(out, false); lod_model = mLastSpecifiedPhysicsP; } @@ -1140,7 +1140,7 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) } } } - else if ((loaded_lod == LLModel::LOD_PHYSICS) && (mModel[loaded_lod].size() == 1)) + else if ((loaded_lod == LLModel::LOD_PHYSICS) && !mLastSpecifiedPhysicsP) { mLastSpecifiedPhysicsModelOriginalName = stripSuffix(mModel[loaded_lod][0]->mLabel); mLastSpecifiedPhysicsP = mModel[loaded_lod][0]; -- cgit v1.2.3 From 81da0dd2db7261e402c53445efa1d012177a4cfe Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 9 Feb 2022 18:03:52 -0800 Subject: SL-16824: Change minimap hover tooltip. Show parcel name, owner name, and/or for sale info when available. Remove "shift-drag to pan" hint. --- indra/newview/llfloatermap.cpp | 56 ++++---- indra/newview/llnetmap.cpp | 152 +++++++++++++++------ indra/newview/llnetmap.h | 20 ++- indra/newview/skins/default/xui/en/floater_map.xml | 30 +++- 4 files changed, 188 insertions(+), 70 deletions(-) diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 7a7ffb0c7e..ab39d08830 100755 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -77,25 +77,31 @@ LLFloaterMap::~LLFloaterMap() BOOL LLFloaterMap::postBuild() { - mMap = getChild("Net Map"); - if (gSavedSettings.getBOOL("DoubleClickTeleport")) - { - mMap->setToolTipMsg(getString("AltToolTipMsg")); - } - else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) - { - mMap->setToolTipMsg(getString("ToolTipMsg")); - } - sendChildToBack(mMap); - - mTextBoxNorth = getChild ("floater_map_north"); - mTextBoxEast = getChild ("floater_map_east"); - mTextBoxWest = getChild ("floater_map_west"); - mTextBoxSouth = getChild ("floater_map_south"); - mTextBoxSouthEast = getChild ("floater_map_southeast"); - mTextBoxNorthEast = getChild ("floater_map_northeast"); - mTextBoxSouthWest = getChild ("floater_map_southwest"); - mTextBoxNorthWest = getChild ("floater_map_northwest"); + mMap = getChild("Net Map"); + mMap->setToolTipMsg(getString("ToolTipMsg")); + mMap->setParcelNameMsg(getString("ParcelNameMsg")); + mMap->setParcelSalePriceMsg(getString("ParcelSalePriceMsg")); + mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg")); + mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg")); + mMap->setRegionNameMsg(getString("RegionNameMsg")); + if (gSavedSettings.getBOOL("DoubleClickTeleport")) + { + mMap->setToolTipHintMsg(getString("AltToolTipHintMsg")); + } + else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) + { + mMap->setToolTipHintMsg(getString("ToolTipHintMsg")); + } + sendChildToBack(mMap); + + mTextBoxNorth = getChild("floater_map_north"); + mTextBoxEast = getChild("floater_map_east"); + mTextBoxWest = getChild("floater_map_west"); + mTextBoxSouth = getChild("floater_map_south"); + mTextBoxSouthEast = getChild("floater_map_southeast"); + mTextBoxNorthEast = getChild("floater_map_northeast"); + mTextBoxSouthWest = getChild("floater_map_southwest"); + mTextBoxNorthWest = getChild("floater_map_northwest"); mTextBoxNorth->reshapeToFitText(); mTextBoxEast->reshapeToFitText(); @@ -106,15 +112,15 @@ BOOL LLFloaterMap::postBuild() mTextBoxSouthWest->reshapeToFitText(); mTextBoxNorthWest->reshapeToFitText(); - updateMinorDirections(); + updateMinorDirections(); - // Get the drag handle all the way in back - sendChildToBack(getDragHandle()); + // Get the drag handle all the way in back + sendChildToBack(getDragHandle()); - // keep onscreen - gFloaterView->adjustToFitScreen(this, FALSE); + // keep onscreen + gFloaterView->adjustToFitScreen(this, false); - return TRUE; + return true; } BOOL LLFloaterMap::handleDoubleClick(S32 x, S32 y, MASK mask) diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 80fac58a1e..e87ec10e5d 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -37,6 +37,7 @@ #include "llfocusmgr.h" #include "lllocalcliprect.h" #include "llrender.h" +#include "llresmgr.h" #include "llui.h" #include "lltooltip.h" @@ -48,10 +49,14 @@ #include "llappviewer.h" // for gDisconnected #include "llcallingcard.h" // LLAvatarTracker #include "llfloaterworldmap.h" +#include "llparcel.h" #include "lltracker.h" #include "llsurface.h" +#include "llurlmatch.h" +#include "llurlregistry.h" #include "llviewercamera.h" #include "llviewercontrol.h" +#include "llviewerparcelmgr.h" #include "llviewertexture.h" #include "llviewertexturelist.h" #include "llviewermenu.h" @@ -603,47 +608,116 @@ BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) return TRUE; } -BOOL LLNetMap::handleToolTip( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask) { - if (gDisconnected) - { - return FALSE; - } - - // If the cursor is near an avatar on the minimap, a mini-inspector will be - // shown for the avatar, instead of the normal map tooltip. - if (handleToolTipAgent(mClosestAgentToCursor)) - { - return TRUE; - } - - LLRect sticky_rect; - std::string region_name; - LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) ); - if(region) - { - // set sticky_rect - S32 SLOP = 4; - localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); - sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; - sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; - - region_name = region->getName(); - if (!region_name.empty()) - { - region_name += "\n"; - } - } + if (gDisconnected) + { + return false; + } + + // If the cursor is near an avatar on the minimap, a mini-inspector will be + // shown for the avatar, instead of the normal map tooltip. + if (handleToolTipAgent(mClosestAgentToCursor)) + { + return true; + } + + LLRect sticky_rect; + S32 SLOP = 4; + localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); + sticky_rect.mRight = sticky_rect.mLeft + 2 * SLOP; + sticky_rect.mTop = sticky_rect.mBottom + 2 * SLOP; + + std::string parcel_name_msg; + std::string parcel_sale_price_msg; + std::string parcel_sale_area_msg; + std::string parcel_owner_msg; + std::string region_name_msg; + + LLVector3d posGlobal = viewPosToGlobal(x, y); + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(posGlobal); + if (region) + { + std::string region_name = region->getName(); + if (!region_name.empty()) + { + region_name_msg = mRegionNameMsg; + LLStringUtil::format(region_name_msg, {{"[REGION_NAME]", region_name}}); + } - LLStringUtil::format_map_t args; - args["[REGION]"] = region_name; - std::string msg = mToolTipMsg; - LLStringUtil::format(msg, args); - LLToolTipMgr::instance().show(LLToolTip::Params() - .message(msg) - .sticky_rect(sticky_rect)); - - return TRUE; + // Only show parcel information in the tooltip if property lines are visible. Otherwise, the parcel the tooltip is referring to is + // ambiguous. + if (gSavedSettings.getBOOL("MiniMapShowPropertyLines")) + { + LLViewerParcelMgr::getInstance()->setHoverParcel(posGlobal); + LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); + if (hover_parcel) + { + std::string parcel_name = hover_parcel->getName(); + if (!parcel_name.empty()) + { + parcel_name_msg = mParcelNameMsg; + LLStringUtil::format(parcel_name_msg, {{"[PARCEL_NAME]", parcel_name}}); + } + + const LLUUID parcel_owner = hover_parcel->getOwnerID(); + std::string parcel_owner_name_url = LLSLURL("agent", parcel_owner, "inspect").getSLURLString(); + static LLUrlMatch parcel_owner_name_url_match; + LLUrlRegistry::getInstance()->findUrl(parcel_owner_name_url, parcel_owner_name_url_match); + if (!parcel_owner_name_url_match.empty()) + { + parcel_owner_msg = mParcelOwnerMsg; + std::string parcel_owner_name = parcel_owner_name_url_match.getLabel(); + LLStringUtil::format(parcel_owner_msg, {{"[PARCEL_OWNER]", parcel_owner_name}}); + } + + if (hover_parcel->getForSale()) + { + const LLUUID auth_buyer_id = hover_parcel->getAuthorizedBuyerID(); + const LLUUID agent_id = gAgent.getID(); + bool show_for_sale = auth_buyer_id.isNull() || auth_buyer_id == agent_id || parcel_owner == agent_id; + if (show_for_sale) + { + S32 price = hover_parcel->getSalePrice(); + S32 area = hover_parcel->getArea(); + F32 cost_per_sqm = 0.0f; + if (area > 0) + { + cost_per_sqm = F32(price) / area; + } + std::string formatted_price = LLResMgr::getInstance()->getMonetaryString(price); + std::string formatted_cost_per_meter = llformat("%.1f", cost_per_sqm); + parcel_sale_price_msg = mParcelSalePriceMsg; + LLStringUtil::format(parcel_sale_price_msg, + {{"[PRICE]", formatted_price}, {"[PRICE_PER_SQM]", formatted_cost_per_meter}}); + std::string formatted_area = llformat("%d", area); + parcel_sale_area_msg = mParcelSaleAreaMsg; + LLStringUtil::format(parcel_sale_area_msg, {{"[AREA]", formatted_area}}); + } + } + } + } + } + + std::string tool_tip_hint_msg = mToolTipHintMsg; + + LLStringUtil::format_map_t args; + args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n'; + args["[PARCEL_SALE_PRICE_MSG]"] = parcel_sale_price_msg.empty() ? "" : parcel_sale_price_msg + '\n'; + args["[PARCEL_SALE_AREA_MSG]"] = parcel_sale_area_msg.empty() ? "" : parcel_sale_area_msg + '\n'; + args["[PARCEL_OWNER_MSG]"] = parcel_owner_msg.empty() ? "" : parcel_owner_msg + '\n'; + args["[REGION_NAME_MSG]"] = region_name_msg.empty() ? "" : region_name_msg + '\n'; + args["[TOOL_TIP_HINT_MSG]"] = tool_tip_hint_msg.empty() ? "" : tool_tip_hint_msg + '\n'; + + std::string msg = mToolTipMsg; + LLStringUtil::format(msg, args); + if (msg.back() == '\n') + { + msg.resize(msg.size() - 1); + } + LLToolTipMgr::instance().show(LLToolTip::Params().message(msg).sticky_rect(sticky_rect)); + + return true; } BOOL LLNetMap::handleToolTipAgent(const LLUUID& avatar_id) diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 1f7e7d68c6..e7eeda7dcc 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -79,8 +79,16 @@ public: /*virtual*/ BOOL handleClick(S32 x, S32 y, MASK mask); /*virtual*/ BOOL handleDoubleClick( S32 x, S32 y, MASK mask ); - void setScale( F32 scale ); - void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; } + void setScale(F32 scale); + + void setToolTipMsg(const std::string& msg) { mToolTipMsg = msg; } + void setParcelNameMsg(const std::string& msg) { mParcelNameMsg = msg; } + void setParcelSalePriceMsg(const std::string& msg) { mParcelSalePriceMsg = msg; } + void setParcelSaleAreaMsg(const std::string& msg) { mParcelSaleAreaMsg = msg; } + void setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; } + void setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; } + void setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; } + void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius ); private: @@ -125,7 +133,13 @@ private: LLUUID mClosestAgentToCursor; LLUUID mClosestAgentAtLastRightClick; - std::string mToolTipMsg; + std::string mToolTipMsg; + std::string mParcelNameMsg; + std::string mParcelSalePriceMsg; + std::string mParcelSaleAreaMsg; + std::string mParcelOwnerMsg; + std::string mRegionNameMsg; + std::string mToolTipHintMsg; public: void setSelected(uuid_vec_t uuids) { gmSelected=uuids; }; diff --git a/indra/newview/skins/default/xui/en/floater_map.xml b/indra/newview/skins/default/xui/en/floater_map.xml index 18e7147136..9639e70544 100644 --- a/indra/newview/skins/default/xui/en/floater_map.xml +++ b/indra/newview/skins/default/xui/en/floater_map.xml @@ -16,11 +16,35 @@ width="200"> - [REGION](Double-click to open Map, shift-drag to pan) + [PARCEL_NAME_MSG][PARCEL_SALE_PRICE_MSG][PARCEL_SALE_AREA_MSG][PARCEL_OWNER_MSG][REGION_NAME_MSG][TOOL_TIP_HINT_MSG] + + [PARCEL_NAME] + + + Price: L$[PRICE] (L$[PRICE_PER_SQM]/m²) + + + Area: [AREA]m² + + + Owner: [PARCEL_OWNER] + + + Region: [REGION_NAME] + + + Double-click to open map + - [REGION](Double-click to teleport, shift-drag to pan) + name="AltToolTipHintMsg"> + Double-click to teleport Mini-map -- cgit v1.2.3 From 0e927e92f33f4a421a3cd56f7b9bc65c19003df2 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 28 Feb 2022 11:55:15 -0800 Subject: SL-16824: Fix minimap tooltip hint not updating until viewer restart (double click to show map vs double click to teleport) --- indra/newview/llfloatermap.cpp | 10 ++-------- indra/newview/llnetmap.cpp | 10 +++++++++- indra/newview/llnetmap.h | 2 ++ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index ab39d08830..95c43805d4 100755 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -84,14 +84,8 @@ BOOL LLFloaterMap::postBuild() mMap->setParcelSaleAreaMsg(getString("ParcelSaleAreaMsg")); mMap->setParcelOwnerMsg(getString("ParcelOwnerMsg")); mMap->setRegionNameMsg(getString("RegionNameMsg")); - if (gSavedSettings.getBOOL("DoubleClickTeleport")) - { - mMap->setToolTipHintMsg(getString("AltToolTipHintMsg")); - } - else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) - { - mMap->setToolTipHintMsg(getString("ToolTipHintMsg")); - } + mMap->setToolTipHintMsg(getString("ToolTipHintMsg")); + mMap->setAltToolTipHintMsg(getString("AltToolTipHintMsg")); sendChildToBack(mMap); mTextBoxNorth = getChild("floater_map_north"); diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index e87ec10e5d..29623ccd53 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -699,7 +699,15 @@ BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask) } } - std::string tool_tip_hint_msg = mToolTipHintMsg; + std::string tool_tip_hint_msg; + if (gSavedSettings.getBOOL("DoubleClickTeleport")) + { + tool_tip_hint_msg = mAltToolTipHintMsg; + } + else if (gSavedSettings.getBOOL("DoubleClickShowWorldMap")) + { + tool_tip_hint_msg = mToolTipHintMsg; + } LLStringUtil::format_map_t args; args["[PARCEL_NAME_MSG]"] = parcel_name_msg.empty() ? "" : parcel_name_msg + '\n'; diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index e7eeda7dcc..b82b3d4105 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -88,6 +88,7 @@ public: void setParcelOwnerMsg(const std::string& msg) { mParcelOwnerMsg = msg; } void setRegionNameMsg(const std::string& msg) { mRegionNameMsg = msg; } void setToolTipHintMsg(const std::string& msg) { mToolTipHintMsg = msg; } + void setAltToolTipHintMsg(const std::string& msg) { mAltToolTipHintMsg = msg; } void renderScaledPointGlobal( const LLVector3d& pos, const LLColor4U &color, F32 radius ); @@ -140,6 +141,7 @@ private: std::string mParcelOwnerMsg; std::string mRegionNameMsg; std::string mToolTipHintMsg; + std::string mAltToolTipHintMsg; public: void setSelected(uuid_vec_t uuids) { gmSelected=uuids; }; -- cgit v1.2.3 From fcbd928679619f2d1cb8550a30234dcdfc50ef81 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 25 Feb 2022 15:31:49 -0800 Subject: SL-16918: Minimap navigation improvements: Drag without holding shift, remove auto center, click button to re-center --- indra/newview/app_settings/settings.xml | 11 -- indra/newview/llnetmap.cpp | 163 +++++++++++---------- indra/newview/llnetmap.h | 13 +- .../newview/skins/default/xui/en/menu_mini_map.xml | 15 +- 4 files changed, 98 insertions(+), 104 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3ecfa4ef9a..d6836dd8ba 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6049,17 +6049,6 @@ Value 1 - MiniMapAutoCenter - - Comment - Center the focal point of the minimap. - Persist - 1 - Type - Boolean - Value - 1 - Marker Comment diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 29623ccd53..f7bcee2bbc 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -87,7 +87,6 @@ LLNetMap::LLNetMap (const Params & p) mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ), mObjectMapTPM(0.f), mObjectMapPixels(0.f), - mTargetPan(0.f, 0.f), mCurPan(0.f, 0.f), mStartPan(0.f, 0.f), mMouseDown(0, 0), @@ -112,13 +111,17 @@ LLNetMap::~LLNetMap() BOOL LLNetMap::postBuild() { - LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar; - - registrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2)); - registrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2)); + LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar; - mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - return TRUE; + commitRegistrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2)); + commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2)); + commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2)); + + mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_mini_map.xml", gMenuHolder, + LLViewerMenuHolderGL::child_registry_t::instance()); + mPopupMenu->setItemEnabled("Re-Center Map", false); + + return true; } void LLNetMap::setScale( F32 scale ) @@ -166,10 +169,16 @@ void LLNetMap::draw() createObjectImage(); } - static LLUICachedControl auto_center("MiniMapAutoCenter", true); - if (auto_center) + mCentering = mCentering && !mPanning; + if (mCentering) { - mCurPan = lerp(mCurPan, mTargetPan, LLSmoothInterpolation::getInterpolant(0.1f)); + mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f)); + if (abs(mCurPan.mV[0]) < 0.5f && abs(mCurPan.mV[1]) < 0.5f){ + mCurPan.mV[0] = 0.0f; + mCurPan.mV[1] = 0.0f; + mCentering = false; + mPopupMenu->setItemEnabled("Re-Center Map", false); + } } // Prepare a scissor region @@ -589,23 +598,25 @@ LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { - // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in - F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); + // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in + F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); + // *TODO: Decide if we want this feature +#if 0 F32 old_scale = mScale; +#endif - setScale(new_scale); + setScale(new_scale); - static LLUICachedControl auto_center("MiniMapAutoCenter", true); - if (!auto_center) - { - // Adjust pan to center the zoom on the mouse pointer - LLVector2 zoom_offset; - zoom_offset.mV[VX] = x - getRect().getWidth() / 2; - zoom_offset.mV[VY] = y - getRect().getHeight() / 2; - mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; - } + // *TODO: Decide if we want this feature +#if 0 + // Adjust pan to center the zoom on the mouse pointer + LLVector2 zoom_offset; + zoom_offset.mV[VX] = x - getRect().getWidth() / 2; + zoom_offset.mV[VY] = y - getRect().getHeight() / 2; + mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; +#endif - return TRUE; + return true; } BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask) @@ -898,50 +909,48 @@ void LLNetMap::createObjectImage() mUpdateNow = true; } -BOOL LLNetMap::handleMouseDown( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleMouseDown(S32 x, S32 y, MASK mask) { - if (!(mask & MASK_SHIFT)) return FALSE; - - // Start panning - gFocusMgr.setMouseCapture(this); + // Start panning + gFocusMgr.setMouseCapture(this); - mStartPan = mCurPan; - mMouseDown.mX = x; - mMouseDown.mY = y; - return TRUE; + mStartPan = mCurPan; + mMouseDown.mX = x; + mMouseDown.mY = y; + return true; } -BOOL LLNetMap::handleMouseUp( S32 x, S32 y, MASK mask ) +BOOL LLNetMap::handleMouseUp(S32 x, S32 y, MASK mask) { - if(abs(mMouseDown.mX-x)<3 && abs(mMouseDown.mY-y)<3) - handleClick(x,y,mask); + if (abs(mMouseDown.mX - x) < 3 && abs(mMouseDown.mY - y) < 3) + { + handleClick(x, y, mask); + } - if (hasMouseCapture()) - { - if (mPanning) - { - // restore mouse cursor - S32 local_x, local_y; - local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]); - local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]); - LLRect clip_rect = getRect(); - clip_rect.stretch(-8); - clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y); - LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y); - - // finish the pan - mPanning = false; - - mMouseDown.set(0, 0); - - // auto centre - mTargetPan.setZero(); - } - gViewerWindow->showCursor(); - gFocusMgr.setMouseCapture(NULL); - return TRUE; - } - return FALSE; + if (hasMouseCapture()) + { + if (mPanning) + { + // restore mouse cursor + S32 local_x, local_y; + local_x = mMouseDown.mX + llfloor(mCurPan.mV[VX] - mStartPan.mV[VX]); + local_y = mMouseDown.mY + llfloor(mCurPan.mV[VY] - mStartPan.mV[VY]); + LLRect clip_rect = getRect(); + clip_rect.stretch(-8); + clip_rect.clipPointToRect(mMouseDown.mX, mMouseDown.mY, local_x, local_y); + LLUI::getInstance()->setMousePositionLocal(this, local_x, local_y); + + // finish the pan + mPanning = false; + + mMouseDown.set(0, 0); + } + gViewerWindow->showCursor(); + gFocusMgr.setMouseCapture(NULL); + return true; + } + + return false; } BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) @@ -1015,9 +1024,10 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) { if (!mPanning) { - // just started panning, so hide cursor + // Just started panning. Hide cursor and enable the "Re-Center Map" button. mPanning = true; gViewerWindow->hideCursor(); + mPopupMenu->setItemEnabled("Re-Center Map", true); } LLVector2 delta(static_cast(gViewerWindow->getCurrentMouseDX()), @@ -1025,27 +1035,22 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) // Set pan to value at start of drag + offset mCurPan += delta; - mTargetPan = mCurPan; gViewerWindow->moveCursorToCenter(); } - - // Doesn't really matter, cursor should be hidden - gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); - } - else - { - if (mask & MASK_SHIFT) - { - // If shift is held, change the cursor to hint that the map can be dragged - gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); - } - else - { - gViewerWindow->setCursor( UI_CURSOR_CROSS ); - } } + if (mask & MASK_SHIFT) + { + // If shift is held, change the cursor to hint that the map can be + // dragged. However, holding shift is not required to drag the map. + gViewerWindow->setCursor( UI_CURSOR_TOOLPAN ); + } + else + { + gViewerWindow->setCursor( UI_CURSOR_CROSS ); + } + return TRUE; } @@ -1083,3 +1088,5 @@ void LLNetMap::handleStopTracking (const LLSD& userdata) LLTracker::stopTracking (LLTracker::isTracking(NULL)); } } + +void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; } diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index b82b3d4105..0f2eee171d 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -121,11 +121,11 @@ private: F32 mObjectMapPixels; // Width of object map in pixels F32 mDotRadius; // Size of avatar markers - bool mPanning; // map is being dragged - LLVector2 mTargetPan; - LLVector2 mCurPan; - LLVector2 mStartPan; // pan offset at start of drag - LLCoordGL mMouseDown; // pointer position at start of drag + bool mPanning; // map is being dragged + bool mCentering; // map is being re-centered around the agent + LLVector2 mCurPan; + LLVector2 mStartPan; // pan offset at start of drag + LLCoordGL mMouseDown; // pointer position at start of drag LLVector3d mObjectImageCenterGlobal; LLPointer mObjectRawImagep; @@ -148,7 +148,8 @@ public: private: void handleZoom(const LLSD& userdata); - void handleStopTracking (const LLSD& userdata); + void handleStopTracking(const LLSD& userdata); + void activateCenterMap(const LLSD& userdata); LLMenuGL* mPopupMenu; uuid_vec_t gmSelected; diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml index c3899b35cd..ddc952dfe7 100644 --- a/indra/newview/skins/default/xui/en/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml @@ -46,16 +46,13 @@ function="ToggleControl" parameter="MiniMapRotate" /> - - - - + + + -- cgit v1.2.3 From 39e553fc11ef1a96707abb0a26c3b1be06954436 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 3 Mar 2022 11:06:16 -0800 Subject: SL-16918: Re-add "Auto-center map" button to minimap context menu, enable minimap auto-center by default again --- indra/newview/app_settings/settings.xml | 11 ++++++ indra/newview/llnetmap.cpp | 45 ++++++++++++---------- .../newview/skins/default/xui/en/menu_mini_map.xml | 10 +++++ 3 files changed, 46 insertions(+), 20 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index d6836dd8ba..3ecfa4ef9a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6049,6 +6049,17 @@ Value 1 + MiniMapAutoCenter + + Comment + Center the focal point of the minimap. + Persist + 1 + Type + Boolean + Value + 1 + Marker Comment diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index f7bcee2bbc..387964f4e8 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -169,17 +169,25 @@ void LLNetMap::draw() createObjectImage(); } + static LLUICachedControl auto_center("MiniMapAutoCenter", true); + bool auto_centering = auto_center && !mPanning; mCentering = mCentering && !mPanning; - if (mCentering) + bool centered = mCurPan.mV[VX] == 0.0f && mCurPan.mV[VY] == 0.0f; + + if (auto_centering || mCentering) { mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f)); - if (abs(mCurPan.mV[0]) < 0.5f && abs(mCurPan.mV[1]) < 0.5f){ - mCurPan.mV[0] = 0.0f; - mCurPan.mV[1] = 0.0f; - mCentering = false; - mPopupMenu->setItemEnabled("Re-Center Map", false); - } } + centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f; + if (centered) + { + mCurPan.mV[0] = 0.0f; + mCurPan.mV[1] = 0.0f; + mCentering = false; + } + + bool can_recenter_map = !(centered || mCentering || auto_centering); + mPopupMenu->setItemEnabled("Re-Center Map", can_recenter_map); // Prepare a scissor region F32 rotation = 0; @@ -600,21 +608,19 @@ BOOL LLNetMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { // note that clicks are reversed from what you'd think: i.e. > 0 means zoom out, < 0 means zoom in F32 new_scale = mScale * pow(MAP_SCALE_ZOOM_FACTOR, -clicks); - // *TODO: Decide if we want this feature -#if 0 F32 old_scale = mScale; -#endif setScale(new_scale); - // *TODO: Decide if we want this feature -#if 0 - // Adjust pan to center the zoom on the mouse pointer - LLVector2 zoom_offset; - zoom_offset.mV[VX] = x - getRect().getWidth() / 2; - zoom_offset.mV[VY] = y - getRect().getHeight() / 2; - mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; -#endif + static LLUICachedControl auto_center("MiniMapAutoCenter", true); + if (!auto_center) + { + // Adjust pan to center the zoom on the mouse pointer + LLVector2 zoom_offset; + zoom_offset.mV[VX] = x - getRect().getWidth() / 2; + zoom_offset.mV[VY] = y - getRect().getHeight() / 2; + mCurPan -= zoom_offset * mScale / old_scale - zoom_offset; + } return true; } @@ -1024,10 +1030,9 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) { if (!mPanning) { - // Just started panning. Hide cursor and enable the "Re-Center Map" button. + // Just started panning. Hide cursor. mPanning = true; gViewerWindow->hideCursor(); - mPopupMenu->setItemEnabled("Re-Center Map", true); } LLVector2 delta(static_cast(gViewerWindow->getCurrentMouseDX()), diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml index ddc952dfe7..402e1b34d0 100644 --- a/indra/newview/skins/default/xui/en/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml @@ -47,6 +47,16 @@ parameter="MiniMapRotate" /> + + + + + -- cgit v1.2.3 From 340213b3023ec1dcc58587f35d270a3ad1a1e83d Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Thu, 3 Mar 2022 18:56:52 -0800 Subject: SL-9748 - Only supply a default physics shape if it is named default_physics_shape --- indra/newview/cube.dae | 2 +- indra/newview/llfloatermodelpreview.cpp | 2 +- indra/newview/llmodelpreview.cpp | 32 +++++++++++++++++--------------- indra/newview/llmodelpreview.h | 4 ++-- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/indra/newview/cube.dae b/indra/newview/cube.dae index f9df955ff2..085b2c7309 100644 --- a/indra/newview/cube.dae +++ b/indra/newview/cube.dae @@ -51,7 +51,7 @@ - + diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 4a51533a57..d99d95934c 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -483,7 +483,7 @@ void LLFloaterModelPreview::prepareToLoadModel(S32 lod) { // loading physics from file mModelPreview->mPhysicsSearchLOD = lod; - mModelPreview->mLastSpecifiedPhysicsP = NULL; + mModelPreview->mWarnOfUnmatchedPhyicsMeshes = false; } } void LLFloaterModelPreview::loadModel(S32 lod) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 4e3b4c5c41..7578d3b9bb 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -86,6 +86,7 @@ static const LLColor4 PREVIEW_DEG_FILL_COL(1.f, 0.f, 0.f, 0.5f); static const F32 PREVIEW_DEG_EDGE_WIDTH(3.f); static const F32 PREVIEW_DEG_POINT_SIZE(8.f); static const F32 PREVIEW_ZOOM_LIMIT(10.f); +static const std::string DEFAULT_PHYSICS_MESH_NAME = "default_physics_shape"; const F32 SKIN_WEIGHT_CAMERA_DISTANCE = 16.f; @@ -465,15 +466,19 @@ void LLModelPreview::rebuildUploadData() LLFloaterModelPreview::addStringToLog(out, false); } } - if (mLastSpecifiedPhysicsP && !lod_model && (i == LLModel::LOD_PHYSICS)) + if (mWarnOfUnmatchedPhyicsMeshes && !lod_model && (i == LLModel::LOD_PHYSICS)) { // Despite the various strategies above, if we don't now have a physics model, we're going to end up with decomposition. - // That's ok, but in the case where someone supplied a physics file, that's probably not what they wanted. + // That's ok, but might not what they wanted. Use default_physics_shape if found. std::ostringstream out; - out << "No physics model specified for " << instance.mLabel << ". Reusing physics model " << mLastSpecifiedPhysicsModelOriginalName << "."; + out << "No physics model specified for " << instance.mLabel; + if (mDefaultPhysicsShapeP) + { + out << " - using: " << DEFAULT_PHYSICS_MESH_NAME; + lod_model = mDefaultPhysicsShapeP; + } LL_WARNS() << out.str() << LL_ENDL; - LLFloaterModelPreview::addStringToLog(out, false); - lod_model = mLastSpecifiedPhysicsP; + LLFloaterModelPreview::addStringToLog(out, !mDefaultPhysicsShapeP); // Flash log tab if no default. } if (lod_model) @@ -1061,6 +1066,13 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) } else { + if (loaded_lod == LLModel::LOD_PHYSICS) + { // Explicitly loading physics. See if there is a default mesh. + LLMatrix4 ignored_transform; // Each mesh that uses this will supply their own. + mDefaultPhysicsShapeP = nullptr; + FindModel(mScene[loaded_lod], DEFAULT_PHYSICS_MESH_NAME + getLodSuffix(loaded_lod), mDefaultPhysicsShapeP, ignored_transform); + mWarnOfUnmatchedPhyicsMeshes = true; + } BOOL legacyMatching = gSavedSettings.getBOOL("ImporterLegacyMatching"); if (!legacyMatching) { @@ -1131,20 +1143,10 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) LL_WARNS() << out.str() << LL_ENDL; LLFloaterModelPreview::addStringToLog(out, false); } - if (loaded_lod == LLModel::LOD_PHYSICS) - { - mLastSpecifiedPhysicsModelOriginalName = loaded_name; - mLastSpecifiedPhysicsP = mModel[loaded_lod][idx]; - } mModel[loaded_lod][idx]->mLabel = name; } } } - else if ((loaded_lod == LLModel::LOD_PHYSICS) && !mLastSpecifiedPhysicsP) - { - mLastSpecifiedPhysicsModelOriginalName = stripSuffix(mModel[loaded_lod][0]->mLabel); - mLastSpecifiedPhysicsP = mModel[loaded_lod][0]; - } } } } diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index 9105ad2716..c46f9197e7 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -217,8 +217,8 @@ private: LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; } // Count amount of original models, excluding sub-models static U32 countRootModels(LLModelLoader::model_list models); - LLModel* mLastSpecifiedPhysicsP{}; // As opposed to being found by name or LOD; - std::string mLastSpecifiedPhysicsModelOriginalName{""}; // Since the above will have it's label bashed. + LLModel* mDefaultPhysicsShapeP{}; // If supplied by name in physics file. + bool mWarnOfUnmatchedPhyicsMeshes{false}; protected: friend class LLModelLoader; -- cgit v1.2.3 From 7f8236140266bb1f057333b3f0f8f2ea30e1aef0 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 4 Mar 2022 16:49:30 -0800 Subject: SL-9748 - add code doc! --- indra/newview/llmodelpreview.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/indra/newview/llmodelpreview.h b/indra/newview/llmodelpreview.h index c46f9197e7..f5f4227049 100644 --- a/indra/newview/llmodelpreview.h +++ b/indra/newview/llmodelpreview.h @@ -217,8 +217,21 @@ private: LLVOAvatar* getPreviewAvatar(void) { return mPreviewAvatar; } // Count amount of original models, excluding sub-models static U32 countRootModels(LLModelLoader::model_list models); - LLModel* mDefaultPhysicsShapeP{}; // If supplied by name in physics file. + /// Indicates whether we should warn of high-lod meshes that do not have a corresponding physics mesh. + /// Reset when resetting the modelpreview (i.e., when the uploader dialog is created or reset), and when + /// about to process a physics file. Set to true immediately after the file is loaded (before rebuildUploadData()). + /// + /// (The rules for mapping the correspondence of high-lod meshes to physics meshes are complex. When + /// lod rendering meshes are used, there is never an unmatched mesh. Nor is there a mismatch when + /// the high-lod file and physics file have ony one mesh each. In these cases, this value is moot. + /// When there are multiple meshes in each file, they are matched by name or order, and some meshes + /// are broken up by limitations into multiple objects, and thus there can be mismatches.) bool mWarnOfUnmatchedPhyicsMeshes{false}; + /// A mesh to use as the default physics shape in only those cases where the physics shape is not otherwise specified. + /// It is set only when the user chooses a physics shape file that contains a mesh with a name that matches DEFAULT_PHYSICS_MESH_NAME. + /// It is reset when such a name is not found, and when resetting the modelpreview. + /// Not read unless mWarnOfUnmatchedPhyicsMeshes is true. + LLModel* mDefaultPhysicsShapeP{}; protected: friend class LLModelLoader; -- cgit v1.2.3 From 6ab4aeb14878a091a04324c87f5f40d9270f7897 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine 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(-) 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 @@ + bevel_style="in" + height="0" + layout="topleft" + name="border0" + top_pad="8" + left="20" + width="540"/> + + Automatic settings + + + + - Shortcuts + Quality & Speed + width="380"> Reducing or turning off water effects can greatly improve frame rate. 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) - + + + Quality & speed: @@ -262,18 +283,6 @@ function="Pref.RenderOptionUpdate" /> - - - Date: Mon, 14 Mar 2022 20:40:39 +0200 Subject: merge fix --- indra/llcommon/tests/llprocess_test.cpp | 66 ++++++++++----------------------- 1 file changed, 20 insertions(+), 46 deletions(-) diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp index 54a1c55a2d..81449b4a42 100644 --- a/indra/llcommon/tests/llprocess_test.cpp +++ b/indra/llcommon/tests/llprocess_test.cpp @@ -356,24 +356,17 @@ namespace tut // Create a script file in a temporary place. NamedTempFile script("py", - "from __future__ import print_function" EOL + "from __future__ import print_function" EOL "import sys" EOL "import time" EOL EOL "time.sleep(2)" EOL -<<<<<<< HEAD "print('stdout after wait',file=sys.stdout)" EOL "sys.stdout.flush()" EOL "time.sleep(2)" EOL "print('stderr after wait',file=sys.stderr)" EOL -======= - "print('stdout after wait', file=sys.stdout)" EOL - "sys.stdout.flush()" EOL - "time.sleep(2)" EOL - "print('stderr after wait', file=sys.stderr)" EOL ->>>>>>> 6ca09a94554ec01f5c94ec60fffd01d7e33f3546 "sys.stderr.flush()" EOL - ); + ); // Arrange to track the history of our interaction with child: what we // fetched, which pipe it came from, how many tries it took before we @@ -869,11 +862,8 @@ namespace tut set_test_name("'bogus' test"); CaptureLog recorder; PythonProcessLauncher py(get_test_name(), -<<<<<<< HEAD - "from __future__ import print_function\n" -======= ->>>>>>> 6ca09a94554ec01f5c94ec60fffd01d7e33f3546 - "print('Hello world')\n"); + "from __future__ import print_function\n" + "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam("bogus")); py.mPy = LLProcess::create(py.mParams); ensure("should have rejected 'bogus'", ! py.mPy); @@ -888,11 +878,8 @@ namespace tut // Replace this test with one or more real 'file' tests when we // implement 'file' support PythonProcessLauncher py(get_test_name(), -<<<<<<< HEAD - "from __future__ import print_function\n" -======= ->>>>>>> 6ca09a94554ec01f5c94ec60fffd01d7e33f3546 - "print('Hello world')\n"); + "from __future__ import print_function\n" + "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam("file")); py.mPy = LLProcess::create(py.mParams); @@ -907,11 +894,8 @@ namespace tut // implement 'tpipe' support CaptureLog recorder; PythonProcessLauncher py(get_test_name(), -<<<<<<< HEAD - "from __future__ import print_function\n" -======= ->>>>>>> 6ca09a94554ec01f5c94ec60fffd01d7e33f3546 - "print('Hello world')\n"); + "from __future__ import print_function\n" + "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam("tpipe")); py.mPy = LLProcess::create(py.mParams); @@ -928,11 +912,8 @@ namespace tut // implement 'npipe' support CaptureLog recorder; PythonProcessLauncher py(get_test_name(), -<<<<<<< HEAD - "from __future__ import print_function\n" -======= ->>>>>>> 6ca09a94554ec01f5c94ec60fffd01d7e33f3546 - "print('Hello world')\n"); + "from __future__ import print_function\n" + "print('Hello world')\n"); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam()); py.mParams.files.add(LLProcess::FileParam("npipe")); @@ -1008,24 +989,20 @@ namespace tut { set_test_name("get*Pipe() validation"); PythonProcessLauncher py(get_test_name(), -<<<<<<< HEAD - "from __future__ import print_function\n" - "print('this output is expected')\n"); -======= - "print('this output is expected)'\n"); ->>>>>>> 6ca09a94554ec01f5c94ec60fffd01d7e33f3546 + "from __future__ import print_function\n" + "print('this output is expected')\n"); py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stdin py.mParams.files.add(LLProcess::FileParam()); // inherit stdout py.mParams.files.add(LLProcess::FileParam("pipe")); // pipe for stderr py.run(); TEST_getPipe(*py.mPy, getWritePipe, getOptWritePipe, - LLProcess::STDIN, // VALID - LLProcess::STDOUT, // NOPIPE - LLProcess::STDERR); // BADPIPE + LLProcess::STDIN, // VALID + LLProcess::STDOUT, // NOPIPE + LLProcess::STDERR); // BADPIPE TEST_getPipe(*py.mPy, getReadPipe, getOptReadPipe, - LLProcess::STDERR, // VALID - LLProcess::STDOUT, // NOPIPE - LLProcess::STDIN); // BADPIPE + LLProcess::STDERR, // VALID + LLProcess::STDOUT, // NOPIPE + LLProcess::STDIN); // BADPIPE } template<> template<> @@ -1152,11 +1129,8 @@ namespace tut { set_test_name("ReadPipe \"eof\" event"); PythonProcessLauncher py(get_test_name(), -<<<<<<< HEAD - "from __future__ import print_function\n" -======= ->>>>>>> 6ca09a94554ec01f5c94ec60fffd01d7e33f3546 - "print('Hello from Python!')\n"); + "from __future__ import print_function\n" + "print('Hello from Python!')\n"); py.mParams.files.add(LLProcess::FileParam()); // stdin py.mParams.files.add(LLProcess::FileParam("pipe")); // stdout py.launch(); -- cgit v1.2.3 From 00b71d8197ed2a64b2d2fa01a72f5cd316e198b7 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink 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(-) 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 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(-) 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 9e24280d81fd278caa914b8d54b26c3dc7f67242 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 16 Mar 2022 19:30:13 +0200 Subject: SL-16667 Show 'Voice volume' tooltip --- indra/newview/skins/default/xui/en/panel_avatar_list_item.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml index aa1b929412..54f038c24f 100644 --- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml +++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml @@ -155,6 +155,7 @@ right="-3" mouse_opaque="true" name="speaking_indicator" + tool_tip="Voice volume" visible="true" width="20" />
-- cgit v1.2.3 From e5e710a1e6e0f74cd60647e3dae7d037076351ff Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine 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(-) 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("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2)); mSettingsPanel->getChild("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this)); mSettingsPanel->getChild("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this)); + mSettingsPanel->getChild("Reflections")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning)); mNearbyPanel->getChild("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); mNearbyPanel->getChild("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("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning)); + getChild("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"> - - - 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? confirm 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(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index ae3ed56b3d..1809b707ef 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1313,9 +1313,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 c8eb9f54c4aa3b72184eb8a6bfc1ec6fd22320b7 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink 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(-) diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 1809b707ef..c9aa82f7d4 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -1344,7 +1344,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 0d280ae11299f54eb81f7e978bf40fcb8d1f58fe Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 24 Mar 2022 17:49:55 +0200 Subject: SL-17030 show particle age info --- indra/llmessage/llpartdata.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/indra/llmessage/llpartdata.cpp b/indra/llmessage/llpartdata.cpp index 53aa35c0f9..6664eb02dc 100644 --- a/indra/llmessage/llpartdata.cpp +++ b/indra/llmessage/llpartdata.cpp @@ -311,8 +311,9 @@ BOOL LLPartSysData::unpack(LLDataPacker &dp) std::ostream& operator<<(std::ostream& s, const LLPartSysData &data) { s << "Flags: " << std::hex << data.mFlags; - s << " Pattern: " << std::hex << (U32) data.mPattern << "\n"; - s << "Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; + s << "Pattern: " << std::hex << (U32) data.mPattern << "\n"; + s << "Source Age: [" << data.mStartAge << ", " << data.mMaxAge << "]\n"; + s << "Particle Age: " << data.mPartData.mMaxAge << "\n"; s << "Angle: [" << data.mInnerAngle << ", " << data.mOuterAngle << "]\n"; s << "Burst Rate: " << data.mBurstRate << "\n"; s << "Burst Radius: " << data.mBurstRadius << "\n"; -- cgit v1.2.3 From 322320a90fdfa61341090bd638cef0679bfc84b5 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 30 Mar 2022 18:29:33 +0300 Subject: SL-16668 Enable/disable appropriate menu items in context menu --- indra/newview/llfloaterland.cpp | 6 +++--- indra/newview/llfloaterland.h | 1 + indra/newview/llfloaterregioninfo.cpp | 6 +++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 04133f2710..ff2384e382 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -3054,7 +3054,8 @@ BOOL LLPanelLandCovenant::postBuild() { mLastRegionID = LLUUID::null; mNextUpdateTime = 0; - + mTextEstateOwner = getChild("estate_owner_text"); + mTextEstateOwner->setIsFriendCallback(LLAvatarActions::isFriend); return TRUE; } @@ -3162,8 +3163,7 @@ void LLPanelLandCovenant::updateEstateOwnerName(const std::string& name) LLPanelLandCovenant* self = LLFloaterLand::getCurrentPanelLandCovenant(); if (self) { - LLTextBox* editor = self->getChild("estate_owner_text"); - if (editor) editor->setText(name); + self->mTextEstateOwner->setText(name); } } diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h index 5d9b411f04..684950d88b 100644 --- a/indra/newview/llfloaterland.h +++ b/indra/newview/llfloaterland.h @@ -413,6 +413,7 @@ protected: private: LLUUID mLastRegionID; F64 mNextUpdateTime; //seconds since client start + LLTextBox* mTextEstateOwner; }; #endif diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 19080f05c0..1390f56ea7 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -47,6 +47,7 @@ #include "llagent.h" #include "llappviewer.h" +#include "llavataractions.h" #include "llavatarname.h" #include "llfloateravatarpicker.h" #include "llbutton.h" @@ -1826,7 +1827,7 @@ void LLPanelEstateInfo::updateControls(LLViewerRegion* region) setCtrlsEnabled(god || owner || manager); getChildView("apply_btn")->setEnabled(FALSE); - + getChildView("estate_owner")->setEnabled(TRUE); getChildView("message_estate_btn")->setEnabled(god || owner || manager); getChildView("kick_user_from_estate_btn")->setEnabled(god || owner || manager); @@ -1888,6 +1889,8 @@ BOOL LLPanelEstateInfo::postBuild() getChild("externally_visible_radio")->setFocus(TRUE); + getChild("estate_owner")->setIsFriendCallback(LLAvatarActions::isFriend); + return LLPanelRegionInfo::postBuild(); } @@ -2132,6 +2135,7 @@ BOOL LLPanelEstateCovenant::postBuild() { mEstateNameText = getChild("estate_name_text"); mEstateOwnerText = getChild("estate_owner_text"); + mEstateOwnerText->setIsFriendCallback(LLAvatarActions::isFriend); mLastModifiedText = getChild("covenant_timestamp_text"); mEditor = getChild("covenant_editor"); LLButton* reset_button = getChild("reset_covenant"); -- cgit v1.2.3 From f1b7ba6c284605f2104896d7316e74b1e436e821 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 18 Feb 2022 14:35:59 -0800 Subject: SL-16916: Update minimap context menu with new options and reworded existing options Map rotation: Split minimap "Rotate Map" context menu option into two options: "North at top" and "Camera at top" Zoom: - Adjust minimap context menu zoom presets: New presets are "far", "medium", "close", and "very close" - Change default minimap zoom level from 128 to 64 - Currently selected minimap zoom level is now checked About Land: Add "About Land" button to minimap context menu Reword: Rearrange and adjust capitalization of the various context menu options Code change: Remove unused zoom handling code in LLFloaterMap --- indra/newview/app_settings/settings.xml | 2 +- indra/newview/llfloatermap.cpp | 26 ----- indra/newview/llfloatermap.h | 1 - indra/newview/llnetmap.cpp | 125 +++++++++++++++----- indra/newview/llnetmap.h | 17 ++- .../newview/skins/default/xui/en/menu_mini_map.xml | 129 +++++++++++++-------- 6 files changed, 187 insertions(+), 113 deletions(-) mode change 100644 => 100755 indra/newview/llnetmap.cpp diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 3ecfa4ef9a..b098a2a18e 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6819,7 +6819,7 @@ Type F32 Value - 128.0 + 64.0 MiniMapShowPropertyLines diff --git a/indra/newview/llfloatermap.cpp b/indra/newview/llfloatermap.cpp index 95c43805d4..fd1af7ccc0 100755 --- a/indra/newview/llfloatermap.cpp +++ b/indra/newview/llfloatermap.cpp @@ -248,32 +248,6 @@ void LLFloaterMap::reshape(S32 width, S32 height, BOOL called_from_parent) updateMinorDirections(); } -void LLFloaterMap::handleZoom(const LLSD& userdata) -{ - std::string level = userdata.asString(); - - F32 scale = 0.0f; - if (level == std::string("default")) - { - LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); - if(pvar) - { - pvar->resetToDefault(); - scale = gSavedSettings.getF32("MiniMapScale"); - } - } - else if (level == std::string("close")) - scale = LLNetMap::MAP_SCALE_MAX; - else if (level == std::string("medium")) - scale = LLNetMap::MAP_SCALE_MID; - else if (level == std::string("far")) - scale = LLNetMap::MAP_SCALE_MIN; - if (scale != 0.0f) - { - mMap->setScale(scale); - } -} - LLFloaterMap* LLFloaterMap::getInstance() { return LLFloaterReg::getTypedInstance("mini_map"); diff --git a/indra/newview/llfloatermap.h b/indra/newview/llfloatermap.h index ff2fb20535..929b1795aa 100644 --- a/indra/newview/llfloatermap.h +++ b/indra/newview/llfloatermap.h @@ -48,7 +48,6 @@ public: /*virtual*/ void draw(); private: - void handleZoom(const LLSD& userdata); void setDirectionPos( LLTextBox* text_box, F32 rotation ); void updateMinorDirections(); diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp old mode 100644 new mode 100755 index 66cf6272fd..4d8bcd97fa --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -48,6 +48,7 @@ #include "llagentcamera.h" #include "llappviewer.h" // for gDisconnected #include "llcallingcard.h" // LLAvatarTracker +#include "llfloaterland.h" #include "llfloaterworldmap.h" #include "llparcel.h" #include "lltracker.h" @@ -69,7 +70,10 @@ static LLDefaultChildRegistry::Register r1("net_map"); const F32 LLNetMap::MAP_SCALE_MIN = 32; -const F32 LLNetMap::MAP_SCALE_MID = 1024; +const F32 LLNetMap::MAP_SCALE_FAR = 32; +const F32 LLNetMap::MAP_SCALE_MEDIUM = 128; +const F32 LLNetMap::MAP_SCALE_CLOSE = 256; +const F32 LLNetMap::MAP_SCALE_VERY_CLOSE = 1024; const F32 LLNetMap::MAP_SCALE_MAX = 4096; const F32 MAP_SCALE_ZOOM_FACTOR = 1.04f; // Zoom in factor per click of scroll wheel (4%) @@ -83,12 +87,13 @@ const F64 COARSEUPDATE_MAX_Z = 1020.0f; LLNetMap::LLNetMap (const Params & p) : LLUICtrl (p), mBackgroundColor (p.bg_color()), - mScale( MAP_SCALE_MID ), - mPixelsPerMeter( MAP_SCALE_MID / REGION_WIDTH_METERS ), + mScale( MAP_SCALE_MEDIUM ), + mPixelsPerMeter( MAP_SCALE_MEDIUM / REGION_WIDTH_METERS ), mObjectMapTPM(0.f), mObjectMapPixels(0.f), mCurPan(0.f, 0.f), mStartPan(0.f, 0.f), + mPopupWorldPos(0.f, 0.f, 0.f), mMouseDown(0, 0), mPanning(false), mUpdateNow(false), @@ -112,14 +117,19 @@ LLNetMap::~LLNetMap() BOOL LLNetMap::postBuild() { LLUICtrl::CommitCallbackRegistry::ScopedRegistrar commitRegistrar; + LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enableRegistrar; - commitRegistrar.add("Minimap.Zoom", boost::bind(&LLNetMap::handleZoom, this, _2)); + enableRegistrar.add("Minimap.Zoom.Check", boost::bind(&LLNetMap::isZoomChecked, this, _2)); + commitRegistrar.add("Minimap.Zoom.Set", boost::bind(&LLNetMap::setZoom, this, _2)); commitRegistrar.add("Minimap.Tracker", boost::bind(&LLNetMap::handleStopTracking, this, _2)); commitRegistrar.add("Minimap.Center.Activate", boost::bind(&LLNetMap::activateCenterMap, this, _2)); + enableRegistrar.add("Minimap.MapOrientation.Check", boost::bind(&LLNetMap::isMapOrientationChecked, this, _2)); + commitRegistrar.add("Minimap.MapOrientation.Set", boost::bind(&LLNetMap::setMapOrientation, this, _2)); + commitRegistrar.add("Minimap.AboutLand", boost::bind(&LLNetMap::popupShowAboutLand, this, _2)); mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile("menu_mini_map.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance()); - mPopupMenu->setItemEnabled("Re-Center Map", false); + mPopupMenu->setItemEnabled("Re-center map", false); return true; } @@ -186,7 +196,7 @@ void LLNetMap::draw() } bool can_recenter_map = !(centered || mCentering || auto_centering); - mPopupMenu->setItemEnabled("Re-Center Map", can_recenter_map); + mPopupMenu->setItemEnabled("Re-center map", can_recenter_map); // Prepare a scissor region F32 rotation = 0; @@ -962,9 +972,10 @@ BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask) { if (mPopupMenu) { + mPopupWorldPos = viewPosToGlobal(x, y); mPopupMenu->buildDrawLabels(); mPopupMenu->updateParent(LLMenuGL::sMenuContainer); - mPopupMenu->setItemEnabled("Stop Tracking", LLTracker::isTracking(0)); + mPopupMenu->setItemEnabled("Stop tracking", LLTracker::isTracking(0)); LLMenuGL::showPopup(this, mPopupMenu, x, y); } return TRUE; @@ -1012,6 +1023,27 @@ BOOL LLNetMap::handleDoubleClick(S32 x, S32 y, MASK mask) return TRUE; } +F32 LLNetMap::getScaleForName(std::string scale_name) +{ + if (scale_name == "very close") + { + return LLNetMap::MAP_SCALE_VERY_CLOSE; + } + else if (scale_name == "close") + { + return LLNetMap::MAP_SCALE_CLOSE; + } + else if (scale_name == "medium") + { + return LLNetMap::MAP_SCALE_MEDIUM; + } + else if (scale_name == "far") + { + return LLNetMap::MAP_SCALE_FAR; + } + return 0.0f; +} + // static bool LLNetMap::outsideSlop( S32 x, S32 y, S32 start_x, S32 start_y, S32 slop ) { @@ -1058,39 +1090,70 @@ BOOL LLNetMap::handleHover( S32 x, S32 y, MASK mask ) return TRUE; } -void LLNetMap::handleZoom(const LLSD& userdata) +bool LLNetMap::isZoomChecked(const LLSD &userdata) { - std::string level = userdata.asString(); - - F32 scale = 0.0f; - if (level == std::string("default")) - { - LLControlVariable *pvar = gSavedSettings.getControl("MiniMapScale"); - if(pvar) - { - pvar->resetToDefault(); - scale = gSavedSettings.getF32("MiniMapScale"); - } - } - else if (level == std::string("close")) - scale = LLNetMap::MAP_SCALE_MAX; - else if (level == std::string("medium")) - scale = LLNetMap::MAP_SCALE_MID; - else if (level == std::string("far")) - scale = LLNetMap::MAP_SCALE_MIN; - if (scale != 0.0f) - { - setScale(scale); - } + std::string level = userdata.asString(); + F32 scale = getScaleForName(level); + return scale == mScale; +} + +void LLNetMap::setZoom(const LLSD &userdata) +{ + std::string level = userdata.asString(); + F32 scale = getScaleForName(level); + if (scale != 0.0f) + { + setScale(scale); + } } void LLNetMap::handleStopTracking (const LLSD& userdata) { if (mPopupMenu) { - mPopupMenu->setItemEnabled ("Stop Tracking", false); + mPopupMenu->setItemEnabled ("Stop tracking", false); LLTracker::stopTracking (LLTracker::isTracking(NULL)); } } void LLNetMap::activateCenterMap(const LLSD &userdata) { mCentering = true; } + +bool LLNetMap::isMapOrientationChecked(const LLSD &userdata) +{ + const std::string command_name = userdata.asString(); + const bool rotate_map = gSavedSettings.getBOOL("MiniMapRotate"); + if (command_name == "north_at_top") + { + return !rotate_map; + } + + if (command_name == "camera_at_top") + { + return rotate_map; + } + + return false; +} + +void LLNetMap::setMapOrientation(const LLSD &userdata) +{ + const std::string command_name = userdata.asString(); + if (command_name == "north_at_top") + { + gSavedSettings.setBOOL("MiniMapRotate", false); + } + else if (command_name == "camera_at_top") + { + gSavedSettings.setBOOL("MiniMapRotate", true); + } +} + +void LLNetMap::popupShowAboutLand(const LLSD &userdata) +{ + // Update parcel selection. It's important to deselect land first so the "About Land" floater doesn't refresh with the old selection. + LLViewerParcelMgr::getInstance()->deselectLand(); + LLParcelSelectionHandle selection = LLViewerParcelMgr::getInstance()->selectParcelAt(mPopupWorldPos); + gMenuHolder->setParcelSelection(selection); + + LLFloaterReg::showInstance("about_land", LLSD(), false); +} diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 0f2eee171d..1864688a3c 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -62,9 +62,12 @@ protected: public: virtual ~LLNetMap(); - static const F32 MAP_SCALE_MIN; - static const F32 MAP_SCALE_MID; - static const F32 MAP_SCALE_MAX; + static const F32 MAP_SCALE_MIN; + static const F32 MAP_SCALE_FAR; + static const F32 MAP_SCALE_MEDIUM; + static const F32 MAP_SCALE_CLOSE; + static const F32 MAP_SCALE_VERY_CLOSE; + static const F32 MAP_SCALE_MAX; /*virtual*/ void draw(); /*virtual*/ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); @@ -108,6 +111,7 @@ private: void createObjectImage(); + F32 getScaleForName(std::string scale_name); static bool outsideSlop(S32 x, S32 y, S32 start_x, S32 start_y, S32 slop); private: @@ -125,6 +129,7 @@ private: bool mCentering; // map is being re-centered around the agent LLVector2 mCurPan; LLVector2 mStartPan; // pan offset at start of drag + LLVector3d mPopupWorldPos; // world position picked under mouse when context menu is opened LLCoordGL mMouseDown; // pointer position at start of drag LLVector3d mObjectImageCenterGlobal; @@ -147,9 +152,13 @@ public: void setSelected(uuid_vec_t uuids) { gmSelected=uuids; }; private: - void handleZoom(const LLSD& userdata); + bool isZoomChecked(const LLSD& userdata); + void setZoom(const LLSD& userdata); void handleStopTracking(const LLSD& userdata); void activateCenterMap(const LLSD& userdata); + bool isMapOrientationChecked(const LLSD& userdata); + void setMapOrientation(const LLSD& userdata); + void popupShowAboutLand(const LLSD& userdata); LLMenuGL* mPopupMenu; uuid_vec_t gmSelected; diff --git a/indra/newview/skins/default/xui/en/menu_mini_map.xml b/indra/newview/skins/default/xui/en/menu_mini_map.xml index 402e1b34d0..2715c916d4 100644 --- a/indra/newview/skins/default/xui/en/menu_mini_map.xml +++ b/indra/newview/skins/default/xui/en/menu_mini_map.xml @@ -8,79 +8,108 @@ top="724" visible="false" width="128"> - - + + + + + - - - + + + - - - + + + - - - - + + + label="North at top" + name="North at top"> + function="Minimap.MapOrientation.Check" + parameter="north_at_top" /> + function="Minimap.MapOrientation.Set" + parameter="north_at_top" /> - + label="Camera at top" + name="Camera at top"> + function="Minimap.MapOrientation.Check" + parameter="camera_at_top" /> + function="Minimap.MapOrientation.Set" + parameter="camera_at_top" /> + + + + + + + + + + + label="Re-center map" + name="Re-center map"> + label="Stop tracking" + name="Stop tracking"> - - - - - + + + -- cgit v1.2.3 From 6013e68ea2d2ca65bac912a295a8521c22a72325 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 5 Apr 2022 11:53:38 -0700 Subject: SL-16918: Fix unneeded assignment to centered in LLNetMap::draw() --- indra/newview/llnetmap.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 387964f4e8..66cf6272fd 100644 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -172,13 +172,12 @@ void LLNetMap::draw() static LLUICachedControl auto_center("MiniMapAutoCenter", true); bool auto_centering = auto_center && !mPanning; mCentering = mCentering && !mPanning; - bool centered = mCurPan.mV[VX] == 0.0f && mCurPan.mV[VY] == 0.0f; if (auto_centering || mCentering) { mCurPan = lerp(mCurPan, LLVector2(0.0f, 0.0f) , LLSmoothInterpolation::getInterpolant(0.1f)); } - centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f; + bool centered = abs(mCurPan.mV[VX]) < 0.5f && abs(mCurPan.mV[VY]) < 0.5f; if (centered) { mCurPan.mV[0] = 0.0f; -- cgit v1.2.3 From f2b57ac03b187e0a33b40bb5b8a1e7a73b5aee58 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 22 Mar 2022 16:45:33 -0700 Subject: SL-16916: Grey out "About Land" button in minimap context menu when land info is likely unavailable --- indra/newview/llnetmap.cpp | 69 ++++++++++++++++++++++++++++++++++++++++++++++ indra/newview/llnetmap.h | 2 ++ 2 files changed, 71 insertions(+) diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 4d8bcd97fa..d0fe771295 100755 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -197,6 +197,7 @@ void LLNetMap::draw() bool can_recenter_map = !(centered || mCentering || auto_centering); mPopupMenu->setItemEnabled("Re-center map", can_recenter_map); + updateAboutLandPopupButton(); // Prepare a scissor region F32 rotation = 0; @@ -588,6 +589,65 @@ void LLNetMap::drawTracking(const LLVector3d& pos_global, const LLColor4& color, } } +bool LLNetMap::isMouseOnPopupMenu() +{ + if (!mPopupMenu->isOpen()) + { + return false; + } + + S32 popup_x; + S32 popup_y; + LLUI::getInstance()->getMousePositionLocal(mPopupMenu, &popup_x, &popup_y); + // *NOTE: Tolerance is larger than it needs to be because the context menu is offset from the mouse when the menu is opened from certain + // directions. This may be a quirk of LLMenuGL::showPopup. -Cosmic,2022-03-22 + constexpr S32 tolerance = 10; + // Test tolerance from all four corners, as the popup menu can appear from a different direction if there's not enough space. + // Assume the size of the popup menu is much larger than the provided tolerance. + // In practice, this is a [tolerance]px margin around the popup menu. + for (S32 sign_x = -1; sign_x <= 1; sign_x += 2) + { + for (S32 sign_y = -1; sign_y <= 1; sign_y += 2) + { + if (mPopupMenu->pointInView(popup_x + (sign_x * tolerance), popup_y + (sign_y * tolerance))) + { + return true; + } + } + } + return false; +} + +void LLNetMap::updateAboutLandPopupButton() +{ + if (!mPopupMenu->isOpen()) + { + return; + } + + LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal(mPopupWorldPos); + if (!region) + { + mPopupMenu->setItemEnabled("About Land", false); + } + else + { + // Check if the mouse is in the bounds of the popup. If so, it's safe to assume no other hover function will be called, so the hover + // parcel can be used to check if location-sensitive tooltip options are available. + if (isMouseOnPopupMenu()) + { + LLViewerParcelMgr::getInstance()->setHoverParcel(mPopupWorldPos); + LLParcel *hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel(); + bool valid_parcel = false; + if (hover_parcel) + { + valid_parcel = hover_parcel->getOwnerID().notNull(); + } + mPopupMenu->setItemEnabled("About Land", valid_parcel); + } + } +} + LLVector3d LLNetMap::viewPosToGlobal( S32 x, S32 y ) { x -= ll_round(getRect().getWidth() / 2 + mCurPan.mV[VX]); @@ -648,6 +708,15 @@ BOOL LLNetMap::handleToolTip(S32 x, S32 y, MASK mask) return true; } + // The popup menu uses the hover parcel when it is open and the mouse is on + // top of it, with some additional tolerance. Returning early here prevents + // fighting over that hover parcel when getting tooltip info in the + // tolerance region. + if (isMouseOnPopupMenu()) + { + return false; + } + LLRect sticky_rect; S32 SLOP = 4; localPointToScreen(x - SLOP, y - SLOP, &(sticky_rect.mLeft), &(sticky_rect.mBottom)); diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h index 1864688a3c..fe1aca65a9 100644 --- a/indra/newview/llnetmap.h +++ b/indra/newview/llnetmap.h @@ -106,6 +106,8 @@ private: void drawTracking( const LLVector3d& pos_global, const LLColor4& color, BOOL draw_arrow = TRUE); + bool isMouseOnPopupMenu(); + void updateAboutLandPopupButton(); BOOL handleToolTipAgent(const LLUUID& avatar_id); static void showAvatarInspector(const LLUUID& avatar_id); -- cgit v1.2.3 From d3a616122f46dc1100bf9ef751b8530a94aa3799 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 3 Mar 2022 09:58:25 -0800 Subject: SL-15232: Test to scroll mouse wheel to map position on main map/minimap --- indra/newview/llappviewer.cpp | 4 +- indra/newview/llfloaterworldmap.cpp | 58 ++++++++------------ indra/newview/llfloaterworldmap.h | 4 -- indra/newview/llworldmapview.cpp | 105 ++++++++++++++++++++++++++++++++++-- indra/newview/llworldmapview.h | 25 +++++++-- 5 files changed, 147 insertions(+), 49 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 254bf05d05..0428feddc1 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -589,7 +589,7 @@ static void settings_to_globals() gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); - LLWorldMapView::sMapScale = gSavedSettings.getF32("MapScale"); + LLWorldMapView::setScale(gSavedSettings.getF32("MapScale")); #if LL_DARWIN gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); @@ -3404,7 +3404,7 @@ void LLAppViewer::cleanupSavedSettings() } } - gSavedSettings.setF32("MapScale", LLWorldMapView::sMapScale ); + gSavedSettings.setF32("MapScale", LLWorldMapView::getScale()); // Some things are cached in LLAgent. if (gAgent.isInitialized()) diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 27197f0b06..6e29a01dd1 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -79,7 +79,6 @@ //--------------------------------------------------------------------------- // Constants //--------------------------------------------------------------------------- -static const F32 MAP_ZOOM_TIME = 0.2f; // Merov: we switched from using the "world size" (which varies depending where the user went) to a fixed // width of 512 regions max visible at a time. This makes the zoom slider works in a consistent way across @@ -300,13 +299,11 @@ BOOL LLFloaterWorldMap::postBuild() landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); mListLandmarkCombo = dynamic_cast(landmark_combo); - mCurZoomVal = log(LLWorldMapView::sMapScale/256.f)/log(2.f); - getChild("zoom slider")->setValue(mCurZoomVal); + F32 slider_zoom = LLWorldMapView::getZoom(); + getChild("zoom slider")->setValue(slider_zoom); setDefaultBtn(NULL); - mZoomTimer.stop(); - onChangeMaturity(); return TRUE; @@ -406,18 +403,21 @@ BOOL LLFloaterWorldMap::handleHover(S32 x, S32 y, MASK mask) BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { - if (!isMinimized() && isFrontmost()) - { - if(mPanel->pointInView(x, y)) - { - F32 slider_value = (F32)getChild("zoom slider")->getValue().asReal(); - slider_value += ((F32)clicks * -0.3333f); - getChild("zoom slider")->setValue(LLSD(slider_value)); - return TRUE; - } - } - - return LLFloater::handleScrollWheel(x, y, clicks); + if (!isMinimized() && isFrontmost()) + { + if (mPanel->pointInView(x, y)) + { + F32 old_slider_zoom = (F32)getChild("zoom slider")->getValue().asReal(); + F32 slider_zoom = old_slider_zoom + ((F32)clicks * -0.3333f); + getChild("zoom slider")->setValue(LLSD(slider_zoom)); + S32 map_x = x - mPanel->getRect().mLeft; + S32 map_y = y - mPanel->getRect().mBottom; + LLWorldMapView::zoomWithPivot(slider_zoom, map_x, map_y); + return true; + } + } + + return LLFloater::handleScrollWheel(x, y, clicks); } @@ -496,21 +496,8 @@ void LLFloaterWorldMap::draw() setMouseOpaque(TRUE); getDragHandle()->setMouseOpaque(TRUE); - - //RN: snaps to zoom value because interpolation caused jitter in the text rendering - if (!mZoomTimer.getStarted() && mCurZoomVal != (F32)getChild("zoom slider")->getValue().asReal()) - { - mZoomTimer.start(); - } - F32 interp = mZoomTimer.getElapsedTimeF32() / MAP_ZOOM_TIME; - if (interp > 1.f) - { - interp = 1.f; - mZoomTimer.stop(); - } - mCurZoomVal = lerp(mCurZoomVal, (F32)getChild("zoom slider")->getValue().asReal(), interp); - F32 map_scale = 256.f*pow(2.f, mCurZoomVal); - LLWorldMapView::setScale( map_scale ); + + LLWorldMapView::zoom((F32)getChild("zoom slider")->getValue().asReal()); // Enable/disable checkboxes depending on the zoom level // If above threshold level (i.e. low res) -> Disable all checkboxes @@ -1338,9 +1325,10 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate) pos_global.clearVec(); } - LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)), - -llfloor((F32)(pos_global.mdV[VY] * (F64)LLWorldMapView::sMapScale / REGION_WIDTH_METERS)), - !animate); + F64 map_scale = (F64)LLWorldMapView::getScale(); + LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)), + -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)), + !animate); mWaitingForTracker = FALSE; } diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index 97e99297cf..b7e2890906 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -156,10 +156,6 @@ protected: private: LLPanel* mPanel; // Panel displaying the map - // Ties to LLWorldMapView::sMapScale, in pixels per region - F32 mCurZoomVal; - LLFrameTimer mZoomTimer; - // update display of teleport destination coordinates - pos is in global coordinates void updateTeleportCoordsDisplay( const LLVector3d& pos ); diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index a6df079223..e6092c6192 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -58,9 +58,14 @@ #include "llglheaders.h" +// # Constants +static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f; +static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f; +static const F32 MAP_ZOOM_MAX_INTERP = 0.5f; +static const F32 MAP_SCALE_SNAP_THRESHOLD = 0.005f; + // Basically a C++ implementation of the OCEAN_COLOR defined in mapstitcher.py // Please ensure consistency between those 2 files (TODO: would be better to get that color from an asset source...) -// # Constants // OCEAN_COLOR = "#1D475F" const F32 OCEAN_RED = (F32)(0x1D)/255.f; const F32 OCEAN_GREEN = (F32)(0x47)/255.f; @@ -100,6 +105,13 @@ S32 LLWorldMapView::sTrackingArrowX = 0; S32 LLWorldMapView::sTrackingArrowY = 0; bool LLWorldMapView::sVisibleTilesLoaded = false; F32 LLWorldMapView::sMapScale = 128.f; +F32 LLWorldMapView::sTargetMapScale = LLWorldMapView::sMapScale; +LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f); +LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer(); +// *HACK: Borrowing some non-static values from the parent LLPanel implementation. Ideally this entire class should not rely on statics for zoom functionality, but I'm treading lightly for smallest delta - Cosmic +// TODO: Actually make this class non-static as discussed above, then test to make sure there are no adverse consequences to performance/stability - Cosmic +F32 LLWorldMapView::sWidthForZoom = 0.0f; +F32 LLWorldMapView::sHeightForZoom = 0.0f; std::map LLWorldMapView::sStringsMap; @@ -210,6 +222,8 @@ BOOL LLWorldMapView::postBuild() mTextBoxNorthEast ->reshapeToFitText(); mTextBoxSouthWest->reshapeToFitText(); mTextBoxNorthWest ->reshapeToFitText(); + + sZoomTimer.stop(); return true; } @@ -227,9 +241,36 @@ void LLWorldMapView::cleanupTextures() { } +// static +void LLWorldMapView::zoom(F32 zoom) +{ + sTargetMapScale = scaleFromZoom(zoom); + if (!sZoomTimer.getStarted() && sMapScale != sTargetMapScale) + { + sZoomPivot = LLVector2(0, 0); + sZoomTimer.start(); + } +} + +// static +void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y) +{ + sTargetMapScale = scaleFromZoom(zoom); + sZoomPivot = LLVector2(x, y); + if (!sZoomTimer.getStarted() && sMapScale != sTargetMapScale) + { + sZoomTimer.start(); + } +} + +// static +F32 LLWorldMapView::getZoom() +{ + return LLWorldMapView::zoomFromScale(sMapScale); +} // static -void LLWorldMapView::setScale( F32 scale ) +void LLWorldMapView::setScale(F32 scale, bool snap) { if (scale != sMapScale) { @@ -247,9 +288,32 @@ void LLWorldMapView::setScale( F32 scale ) sTargetPanX = sPanX; sTargetPanY = sPanY; sVisibleTilesLoaded = false; + + // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here + if (!sZoomPivot.isExactlyZero()) + { + LLVector2 relative_pivot; + relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (sWidthForZoom / 2.0); + relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (sHeightForZoom / 2.0); + LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale); + sPanX += zoom_pan_offset.mV[VX]; + sPanY += zoom_pan_offset.mV[VY]; + sTargetPanX += zoom_pan_offset.mV[VX]; + sTargetPanY += zoom_pan_offset.mV[VY]; + } } + + if (snap) + { + sTargetMapScale = scale; + } } +// static +F32 LLWorldMapView::getScale() +{ + return sMapScale; +} // static void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y ) @@ -301,11 +365,34 @@ void LLWorldMapView::draw() mVisibleRegions.clear(); // animate pan if necessary - sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(0.1f)); - sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(0.1f)); + sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); + sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); + + //RN: snaps to zoom value because interpolation caused jitter in the text rendering + if (!sZoomTimer.getStarted() && sMapScale != sTargetMapScale) + { + sZoomTimer.start(); + } + bool snap_scale = false; + F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME); + F32 current_zoom_val = zoomFromScale(sMapScale); + F32 target_zoom_val = zoomFromScale(sTargetMapScale); + F32 new_zoom_val = lerp(current_zoom_val, target_zoom_val, interp); + if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD) + { + sZoomTimer.stop(); + snap_scale = true; + new_zoom_val = target_zoom_val; + } + F32 map_scale = scaleFromZoom(new_zoom_val); + setScale(map_scale, snap_scale); const S32 width = getRect().getWidth(); const S32 height = getRect().getHeight(); + // *HACK: Borrowing some non-static values from the parent LLPanel implementation. Ideally this entire class should not rely on statics for zoom functionality, but I'm treading lightly for smallest delta - Cosmic + // TODO: Actually make this class non-static as discussed above, then test to make sure there are no adverse consequences to performance/stability - Cosmic + sWidthForZoom = width; + sHeightForZoom = height; const F32 half_width = F32(width) / 2.0f; const F32 half_height = F32(height) / 2.0f; LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); @@ -1792,4 +1879,14 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) return FALSE; } +// static +F32 LLWorldMapView::scaleFromZoom(F32 zoom) +{ + return exp2(zoom) * 256.0f; +} +// static +F32 LLWorldMapView::zoomFromScale(F32 scale) +{ + return log2(scale / 256.f); +} diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index a2a6dc53fb..9a549a443a 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -67,8 +67,16 @@ public: bool checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track); void handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id); - // Scale and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered) - static void setScale( F32 scale ); + // Zoom, scale, and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered) + // Scale and zoom are the same thing but with different units. + // Scale is for things defined in in-world coordinates. + // Zoom is used for UI and will interpolate the map scale over multiple frames. + // Pan is in pixels relative to the center of the map. + static void zoom(F32 zoom); + static void zoomWithPivot(F32 zoom, S32 x, S32 y); + static F32 getZoom(); + static void setScale(F32 scale, bool snap = true); + static F32 getScale(); static void translatePan( S32 delta_x, S32 delta_y ); static void setPan( S32 x, S32 y, BOOL snap = TRUE ); // Return true if the current scale level is above the threshold for accessing region info @@ -153,8 +161,6 @@ public: static LLUIImagePtr sForSaleImage; static LLUIImagePtr sForSaleAdultImage; - static F32 sMapScale; // scale = size of a region in pixels - BOOL mItemPicked; static F32 sPanX; // in pixels @@ -194,6 +200,17 @@ public: private: void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right); + + static F32 scaleFromZoom(F32 zoom); + static F32 zoomFromScale(F32 scale); + + static F32 sMapScale; + static F32 sTargetMapScale; + static LLVector2 sZoomPivot; + static LLFrameTimer sZoomTimer; + + static F32 sWidthForZoom; + static F32 sHeightForZoom; }; #endif -- cgit v1.2.3 From 288fbe23175d504359169ae6d8dda86529f8d046 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 9 Mar 2022 14:58:31 -0800 Subject: SL-15232: Fix top/right edges of main map not being scrollable --- indra/newview/llfloaterworldmap.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 6e29a01dd1..2947804b69 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -405,13 +405,13 @@ BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { if (!isMinimized() && isFrontmost()) { - if (mPanel->pointInView(x, y)) + S32 map_x = x - mPanel->getRect().mLeft; + S32 map_y = y - mPanel->getRect().mBottom; + if (mPanel->pointInView(map_x, map_y)) { F32 old_slider_zoom = (F32)getChild("zoom slider")->getValue().asReal(); F32 slider_zoom = old_slider_zoom + ((F32)clicks * -0.3333f); getChild("zoom slider")->setValue(LLSD(slider_zoom)); - S32 map_x = x - mPanel->getRect().mLeft; - S32 map_y = y - mPanel->getRect().mBottom; LLWorldMapView::zoomWithPivot(slider_zoom, map_x, map_y); return true; } -- cgit v1.2.3 From c6cba3a67d4a346d1d5cf0cc6e6a8fe8c640e13f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 10 Mar 2022 16:38:07 -0800 Subject: SL-15232: Clean up LLWorldMapView a bit. Avoid a static variable hack and convert a few related variables/methods to non-static as well --- indra/newview/llappviewer.cpp | 4 +- indra/newview/llfloaterworldmap.cpp | 41 ++++---- indra/newview/llfloaterworldmap.h | 3 +- indra/newview/llworldmapview.cpp | 198 ++++++++++++++++++------------------ indra/newview/llworldmapview.h | 41 ++++---- 5 files changed, 144 insertions(+), 143 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0428feddc1..a06a9eb9fe 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -589,7 +589,7 @@ static void settings_to_globals() gDebugWindowProc = gSavedSettings.getBOOL("DebugWindowProc"); gShowObjectUpdates = gSavedSettings.getBOOL("ShowObjectUpdates"); - LLWorldMapView::setScale(gSavedSettings.getF32("MapScale")); + LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale")); #if LL_DARWIN gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); @@ -3404,7 +3404,7 @@ void LLAppViewer::cleanupSavedSettings() } } - gSavedSettings.setF32("MapScale", LLWorldMapView::getScale()); + gSavedSettings.setF32("MapScale", LLWorldMapView::getScaleSetting()); // Some things are cached in LLAgent. if (gAgent.isInitialized()) diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index 2947804b69..cf314c3e60 100644 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -278,7 +278,7 @@ void* LLFloaterWorldMap::createWorldMapView(void* data) BOOL LLFloaterWorldMap::postBuild() { - mPanel = getChild("objects_mapview"); + mMapView = dynamic_cast(getChild("objects_mapview")); LLComboBox *avatar_combo = getChild("friend combo"); avatar_combo->selectFirstItem(); @@ -299,7 +299,7 @@ BOOL LLFloaterWorldMap::postBuild() landmark_combo->setTextChangedCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) ); mListLandmarkCombo = dynamic_cast(landmark_combo); - F32 slider_zoom = LLWorldMapView::getZoom(); + F32 slider_zoom = mMapView->getZoom(); getChild("zoom slider")->setValue(slider_zoom); setDefaultBtn(NULL); @@ -313,7 +313,7 @@ BOOL LLFloaterWorldMap::postBuild() LLFloaterWorldMap::~LLFloaterWorldMap() { // All cleaned up by LLView destructor - mPanel = NULL; + mMapView = NULL; // Inventory deletes all observers on shutdown mInventory = NULL; @@ -345,17 +345,15 @@ void LLFloaterWorldMap::onOpen(const LLSD& key) mIsClosing = FALSE; - LLWorldMapView* map_panel; - map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; - map_panel->clearLastClick(); + mMapView->clearLastClick(); { // reset pan on show, so it centers on you again if (!center_on_target) { - LLWorldMapView::setPan(0, 0, TRUE); + mMapView->setPan(0, 0, true); } - map_panel->updateVisibleBlocks(); + mMapView->updateVisibleBlocks(); // Reload items as they may have changed LLWorldMap::getInstance()->reloadItems(); @@ -405,14 +403,14 @@ BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks) { if (!isMinimized() && isFrontmost()) { - S32 map_x = x - mPanel->getRect().mLeft; - S32 map_y = y - mPanel->getRect().mBottom; - if (mPanel->pointInView(map_x, map_y)) + S32 map_x = x - mMapView->getRect().mLeft; + S32 map_y = y - mMapView->getRect().mBottom; + if (mMapView->pointInView(map_x, map_y)) { F32 old_slider_zoom = (F32)getChild("zoom slider")->getValue().asReal(); F32 slider_zoom = old_slider_zoom + ((F32)clicks * -0.3333f); getChild("zoom slider")->setValue(LLSD(slider_zoom)); - LLWorldMapView::zoomWithPivot(slider_zoom, map_x, map_y); + mMapView->zoomWithPivot(slider_zoom, map_x, map_y); return true; } } @@ -497,12 +495,12 @@ void LLFloaterWorldMap::draw() setMouseOpaque(TRUE); getDragHandle()->setMouseOpaque(TRUE); - LLWorldMapView::zoom((F32)getChild("zoom slider")->getValue().asReal()); + mMapView->zoom((F32)getChild("zoom slider")->getValue().asReal()); // Enable/disable checkboxes depending on the zoom level // If above threshold level (i.e. low res) -> Disable all checkboxes // If under threshold level (i.e. high res) -> Enable all checkboxes - bool enable = LLWorldMapView::showRegionInfo(); + bool enable = mMapView->showRegionInfo(); getChildView("people_chk")->setEnabled(enable); getChildView("infohub_chk")->setEnabled(enable); getChildView("telehub_chk")->setEnabled(enable); @@ -1001,9 +999,7 @@ void LLFloaterWorldMap::adjustZoomSliderBounds() S32 world_height_regions = MAX_VISIBLE_REGIONS; // Find how much space we have to display the world - LLWorldMapView* map_panel; - map_panel = (LLWorldMapView*)mPanel; - LLRect view_rect = map_panel->getRect(); + LLRect view_rect = mMapView->getRect(); // View size in pixels S32 view_width = view_rect.getWidth(); @@ -1271,9 +1267,9 @@ void LLFloaterWorldMap::onShowTargetBtn() void LLFloaterWorldMap::onShowAgentBtn() { - LLWorldMapView::setPan( 0, 0, FALSE); // FALSE == animate + mMapView->setPan(0, 0, false); // false == animate // Set flag so user's location will be displayed if not tracking anything else - mSetToUserPosition = TRUE; + mSetToUserPosition = true; } void LLFloaterWorldMap::onClickTeleportBtn() @@ -1325,8 +1321,8 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate) pos_global.clearVec(); } - F64 map_scale = (F64)LLWorldMapView::getScale(); - LLWorldMapView::setPan( -llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)), + F64 map_scale = (F64)mMapView->getScale(); + mMapView->setPan(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)), -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)), !animate); mWaitingForTracker = FALSE; @@ -1627,6 +1623,5 @@ void LLFloaterWorldMap::onChangeMaturity() void LLFloaterWorldMap::onFocusLost() { gViewerWindow->showCursor(); - LLWorldMapView* map_panel = (LLWorldMapView*)gFloaterWorldMap->mPanel; - map_panel->mPanning = FALSE; + mMapView->mPanning = false; } diff --git a/indra/newview/llfloaterworldmap.h b/indra/newview/llfloaterworldmap.h index b7e2890906..c9724d37ac 100644 --- a/indra/newview/llfloaterworldmap.h +++ b/indra/newview/llfloaterworldmap.h @@ -44,6 +44,7 @@ class LLInventoryObserver; class LLItemInfo; class LLLineEditor; class LLTabContainer; +class LLWorldMapView; class LLFloaterWorldMap : public LLFloater { @@ -154,7 +155,7 @@ protected: void cacheLandmarkPosition(); private: - LLPanel* mPanel; // Panel displaying the map + LLWorldMapView* mMapView; // Panel displaying the map // update display of teleport destination coordinates - pos is in global coordinates void updateTeleportCoordsDisplay( const LLVector3d& pos ); diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index e6092c6192..cad655ea48 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -59,6 +59,7 @@ #include "llglheaders.h" // # Constants +static const F32 MAP_DEFAULT_SCALE = 128.f; static const F32 MAP_ITERP_TIME_CONSTANT = 0.75f; static const F32 MAP_ZOOM_ACCELERATION_TIME = 0.3f; static const F32 MAP_ZOOM_MAX_INTERP = 0.5f; @@ -97,21 +98,12 @@ LLUIImagePtr LLWorldMapView::sClassifiedsImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleImage = NULL; LLUIImagePtr LLWorldMapView::sForSaleAdultImage = NULL; -F32 LLWorldMapView::sPanX = 0.f; -F32 LLWorldMapView::sPanY = 0.f; -F32 LLWorldMapView::sTargetPanX = 0.f; -F32 LLWorldMapView::sTargetPanY = 0.f; S32 LLWorldMapView::sTrackingArrowX = 0; S32 LLWorldMapView::sTrackingArrowY = 0; bool LLWorldMapView::sVisibleTilesLoaded = false; -F32 LLWorldMapView::sMapScale = 128.f; -F32 LLWorldMapView::sTargetMapScale = LLWorldMapView::sMapScale; +F32 LLWorldMapView::sMapScaleSetting = MAP_DEFAULT_SCALE; LLVector2 LLWorldMapView::sZoomPivot = LLVector2(0.0f, 0.0f); LLFrameTimer LLWorldMapView::sZoomTimer = LLFrameTimer(); -// *HACK: Borrowing some non-static values from the parent LLPanel implementation. Ideally this entire class should not rely on statics for zoom functionality, but I'm treading lightly for smallest delta - Cosmic -// TODO: Actually make this class non-static as discussed above, then test to make sure there are no adverse consequences to performance/stability - Cosmic -F32 LLWorldMapView::sWidthForZoom = 0.0f; -F32 LLWorldMapView::sHeightForZoom = 0.0f; std::map LLWorldMapView::sStringsMap; @@ -182,12 +174,18 @@ LLWorldMapView::LLWorldMapView() : LLPanel(), mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ), mItemPicked(FALSE), + mPanX(0.f), + mPanY(0.f), + mTargetPanX(0.f), + mTargetPanY(0.f), mPanning( FALSE ), mMouseDownPanX( 0 ), mMouseDownPanY( 0 ), mMouseDownX( 0 ), mMouseDownY( 0 ), - mSelectIDStart(0) + mSelectIDStart(0), + mMapScale(0.f), + mTargetMapScale(0.f) { //LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; @@ -224,6 +222,7 @@ BOOL LLWorldMapView::postBuild() mTextBoxNorthWest ->reshapeToFitText(); sZoomTimer.stop(); + setScale(sMapScaleSetting, true); return true; } @@ -241,87 +240,96 @@ void LLWorldMapView::cleanupTextures() { } -// static void LLWorldMapView::zoom(F32 zoom) { - sTargetMapScale = scaleFromZoom(zoom); - if (!sZoomTimer.getStarted() && sMapScale != sTargetMapScale) + mTargetMapScale = scaleFromZoom(zoom); + if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) { sZoomPivot = LLVector2(0, 0); sZoomTimer.start(); } } -// static void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y) { - sTargetMapScale = scaleFromZoom(zoom); + mTargetMapScale = scaleFromZoom(zoom); sZoomPivot = LLVector2(x, y); - if (!sZoomTimer.getStarted() && sMapScale != sTargetMapScale) + if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) { sZoomTimer.start(); } } -// static F32 LLWorldMapView::getZoom() { - return LLWorldMapView::zoomFromScale(sMapScale); + return LLWorldMapView::zoomFromScale(mMapScale); +} + +F32 LLWorldMapView::getScale() +{ + return mMapScale; } // static +void LLWorldMapView::setScaleSetting(F32 scaleSetting) +{ + sMapScaleSetting = scaleSetting; +} + +// static +F32 LLWorldMapView::getScaleSetting() +{ + return sMapScaleSetting; +} + void LLWorldMapView::setScale(F32 scale, bool snap) { - if (scale != sMapScale) + if (scale != mMapScale) { - F32 old_scale = sMapScale; + F32 old_scale = mMapScale; - sMapScale = scale; - if (sMapScale <= 0.f) + mMapScale = scale; + // Set the scale used when saving the setting + sMapScaleSetting = scale; + if (mMapScale <= 0.f) { - sMapScale = 0.1f; + mMapScale = 0.1f; } F32 ratio = (scale / old_scale); - sPanX *= ratio; - sPanY *= ratio; - sTargetPanX = sPanX; - sTargetPanY = sPanY; + mPanX *= ratio; + mPanY *= ratio; + mTargetPanX = mPanX; + mTargetPanY = mPanY; sVisibleTilesLoaded = false; // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here if (!sZoomPivot.isExactlyZero()) { LLVector2 relative_pivot; - relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (sWidthForZoom / 2.0); - relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (sHeightForZoom / 2.0); + relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0); + relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0); LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale); - sPanX += zoom_pan_offset.mV[VX]; - sPanY += zoom_pan_offset.mV[VY]; - sTargetPanX += zoom_pan_offset.mV[VX]; - sTargetPanY += zoom_pan_offset.mV[VY]; + mPanX += zoom_pan_offset.mV[VX]; + mPanY += zoom_pan_offset.mV[VY]; + mTargetPanX += zoom_pan_offset.mV[VX]; + mTargetPanY += zoom_pan_offset.mV[VY]; } } if (snap) { - sTargetMapScale = scale; - } + mTargetMapScale = scale; } - -// static -F32 LLWorldMapView::getScale() -{ - return sMapScale; } // static void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y ) { - sPanX += delta_x; - sPanY += delta_y; - sTargetPanX = sPanX; - sTargetPanY = sPanY; + mPanX += delta_x; + mPanY += delta_y; + mTargetPanX = mPanX; + mTargetPanY = mPanY; sVisibleTilesLoaded = false; } @@ -329,19 +337,19 @@ void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y ) // static void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap ) { - sTargetPanX = (F32)x; - sTargetPanY = (F32)y; + mTargetPanX = (F32)x; + mTargetPanY = (F32)y; if (snap) { - sPanX = sTargetPanX; - sPanY = sTargetPanY; + mPanX = mTargetPanX; + mPanY = mTargetPanY; } sVisibleTilesLoaded = false; } bool LLWorldMapView::showRegionInfo() { - return (LLWorldMipmap::scaleToLevel(sMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); + return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); } /////////////////////////////////////////////////////////////////////////////////// @@ -365,18 +373,18 @@ void LLWorldMapView::draw() mVisibleRegions.clear(); // animate pan if necessary - sPanX = lerp(sPanX, sTargetPanX, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); - sPanY = lerp(sPanY, sTargetPanY, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); + mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); + mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); //RN: snaps to zoom value because interpolation caused jitter in the text rendering - if (!sZoomTimer.getStarted() && sMapScale != sTargetMapScale) + if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) { sZoomTimer.start(); } bool snap_scale = false; F32 interp = llmin(MAP_ZOOM_MAX_INTERP, sZoomTimer.getElapsedTimeF32() / MAP_ZOOM_ACCELERATION_TIME); - F32 current_zoom_val = zoomFromScale(sMapScale); - F32 target_zoom_val = zoomFromScale(sTargetMapScale); + F32 current_zoom_val = zoomFromScale(mMapScale); + F32 target_zoom_val = zoomFromScale(mTargetMapScale); F32 new_zoom_val = lerp(current_zoom_val, target_zoom_val, interp); if (abs(new_zoom_val - current_zoom_val) < MAP_SCALE_SNAP_THRESHOLD) { @@ -389,15 +397,11 @@ void LLWorldMapView::draw() const S32 width = getRect().getWidth(); const S32 height = getRect().getHeight(); - // *HACK: Borrowing some non-static values from the parent LLPanel implementation. Ideally this entire class should not rely on statics for zoom functionality, but I'm treading lightly for smallest delta - Cosmic - // TODO: Actually make this class non-static as discussed above, then test to make sure there are no adverse consequences to performance/stability - Cosmic - sWidthForZoom = width; - sHeightForZoom = height; const F32 half_width = F32(width) / 2.0f; const F32 half_height = F32(height) / 2.0f; LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal(); - S32 level = LLWorldMipmap::scaleToLevel(sMapScale); + S32 level = LLWorldMipmap::scaleToLevel(mMapScale); LLLocalClipRect clip(getLocalRect()); { @@ -437,15 +441,15 @@ void LLWorldMapView::draw() // Find x and y position relative to camera's center. LLVector3d rel_region_pos = origin_global - camera_global; - F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * sMapScale; - F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * sMapScale; + F32 relative_x = (rel_region_pos.mdV[0] / REGION_WIDTH_METERS) * mMapScale; + F32 relative_y = (rel_region_pos.mdV[1] / REGION_WIDTH_METERS) * mMapScale; // Coordinates of the sim in pixels in the UI panel // When the view isn't panned, 0,0 = center of rectangle - F32 bottom = sPanY + half_height + relative_y; - F32 left = sPanX + half_width + relative_x; - F32 top = bottom + sMapScale ; - F32 right = left + sMapScale ; + F32 bottom = mPanY + half_height + relative_y; + F32 left = mPanX + half_width + relative_x; + F32 top = bottom + mMapScale ; + F32 right = left + mMapScale ; // Discard if region is outside the screen rectangle (not visible on screen) if ((top < 0.f) || (bottom > height) || @@ -506,7 +510,7 @@ void LLWorldMapView::draw() if (overlayimage) { // Inform the fetch mechanism of the size we need - S32 draw_size = ll_round(sMapScale); + S32 draw_size = ll_round(mMapScale); overlayimage->setKnownDrawSize(ll_round(draw_size * LLUI::getScaleFactor().mV[VX]), ll_round(draw_size * LLUI::getScaleFactor().mV[VY])); // Draw something whenever we have enough info if (overlayimage->hasGLTexture()) @@ -534,7 +538,7 @@ void LLWorldMapView::draw() } // Draw the region name in the lower left corner - if (sMapScale >= DRAW_TEXT_THRESHOLD) + if (mMapScale >= DRAW_TEXT_THRESHOLD) { LLFontGL* font = LLFontGL::getFont(LLFontDescriptor("SansSerif", "Small", LLFontGL::BOLD)); std::string mesg; @@ -554,7 +558,7 @@ void LLWorldMapView::draw() LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, S32_MAX, //max_chars - sMapScale, //max_pixels + mMapScale, //max_pixels NULL, TRUE); //use ellipses } @@ -681,7 +685,7 @@ void LLWorldMapView::setVisible(BOOL visible) void LLWorldMapView::drawMipmap(S32 width, S32 height) { // Compute the level of the mipmap to use for the current scale level - S32 level = LLWorldMipmap::scaleToLevel(sMapScale); + S32 level = LLWorldMipmap::scaleToLevel(mMapScale); // Set the tile boost level so that unused tiles get to 0 LLWorldMap::getInstance()->equalizeBoostLevels(); @@ -964,7 +968,7 @@ void LLWorldMapView::drawAgents() void LLWorldMapView::drawFrustum() { // Draw frustum - F32 meters_to_pixels = sMapScale/ REGION_WIDTH_METERS; + F32 meters_to_pixels = mMapScale/ REGION_WIDTH_METERS; F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); @@ -974,8 +978,8 @@ void LLWorldMapView::drawFrustum() F32 half_width_pixels = half_width_meters * meters_to_pixels; // Compute the frustum coordinates. Take the UI scale into account. - F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + sPanX) * LLUI::getScaleFactor().mV[VX]); - F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + sPanY) * LLUI::getScaleFactor().mV[VY]); + F32 ctr_x = ((getLocalRect().getWidth() * 0.5f + mPanX) * LLUI::getScaleFactor().mV[VX]); + F32 ctr_y = ((getLocalRect().getHeight() * 0.5f + mPanY) * LLUI::getScaleFactor().mV[VY]); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -1032,13 +1036,13 @@ LLVector3 LLWorldMapView::globalPosToView( const LLVector3d& global_pos ) LLVector3 pos_local; pos_local.setVec(relative_pos_global); // convert to floats from doubles - pos_local.mV[VX] *= sMapScale / REGION_WIDTH_METERS; - pos_local.mV[VY] *= sMapScale / REGION_WIDTH_METERS; + pos_local.mV[VX] *= mMapScale / REGION_WIDTH_METERS; + pos_local.mV[VY] *= mMapScale / REGION_WIDTH_METERS; // leave Z component in meters - pos_local.mV[VX] += getRect().getWidth() / 2 + sPanX; - pos_local.mV[VY] += getRect().getHeight() / 2 + sPanY; + pos_local.mV[VX] += getRect().getWidth() / 2 + mPanX; + pos_local.mV[VY] += getRect().getHeight() / 2 + mPanY; return pos_local; } @@ -1109,12 +1113,12 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4& // If you change this, then you need to change LLTracker::getTrackedPositionGlobal() as well LLVector3d LLWorldMapView::viewPosToGlobal( S32 x, S32 y ) { - x -= llfloor((getRect().getWidth() / 2 + sPanX)); - y -= llfloor((getRect().getHeight() / 2 + sPanY)); + x -= llfloor((getRect().getWidth() / 2 + mPanX)); + y -= llfloor((getRect().getHeight() / 2 + mPanY)); LLVector3 pos_local( (F32)x, (F32)y, 0.f ); - pos_local *= ( REGION_WIDTH_METERS / sMapScale ); + pos_local *= ( REGION_WIDTH_METERS / mMapScale ); LLVector3d pos_global; pos_global.setVec( pos_local ); @@ -1571,7 +1575,7 @@ void LLWorldMapView::handleClick(S32 x, S32 y, MASK mask, LLWorldMap::getInstance()->cancelTracking(); - S32 level = LLWorldMipmap::scaleToLevel(sMapScale); + S32 level = LLWorldMipmap::scaleToLevel(mMapScale); // If the zoom level is not too far out already, test hits if (level <= DRAW_SIMINFO_THRESHOLD) { @@ -1688,8 +1692,8 @@ BOOL LLWorldMapView::handleMouseDown( S32 x, S32 y, MASK mask ) { gFocusMgr.setMouseCapture( this ); - mMouseDownPanX = ll_round(sPanX); - mMouseDownPanY = ll_round(sPanY); + mMouseDownPanX = ll_round(mPanX); + mMouseDownPanY = ll_round(mPanY); mMouseDownX = x; mMouseDownY = y; sHandledLastClick = TRUE; @@ -1704,8 +1708,8 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask ) { // restore mouse cursor S32 local_x, local_y; - local_x = mMouseDownX + llfloor(sPanX - mMouseDownPanX); - local_y = mMouseDownY + llfloor(sPanY - mMouseDownPanY); + local_x = mMouseDownX + llfloor(mPanX - mMouseDownPanX); + local_y = mMouseDownY + llfloor(mPanY - mMouseDownPanY); LLRect clip_rect = getRect(); clip_rect.stretch(-8); clip_rect.clipPointToRect(mMouseDownX, mMouseDownY, local_x, local_y); @@ -1733,7 +1737,7 @@ BOOL LLWorldMapView::handleMouseUp( S32 x, S32 y, MASK mask ) void LLWorldMapView::updateVisibleBlocks() { - if (LLWorldMipmap::scaleToLevel(sMapScale) > DRAW_SIMINFO_THRESHOLD) + if (LLWorldMipmap::scaleToLevel(mMapScale) > DRAW_SIMINFO_THRESHOLD) { // If we're zoomed out too much, we just don't load all those sim info: too much! return; @@ -1749,16 +1753,16 @@ void LLWorldMapView::updateVisibleBlocks() const F32 half_height = F32(height) / 2.0f; // Compute center into sim grid coordinates - S32 world_center_x = S32((-sPanX / sMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); - S32 world_center_y = S32((-sPanY / sMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); + S32 world_center_x = S32((-mPanX / mMapScale) + (camera_global.mdV[0] / REGION_WIDTH_METERS)); + S32 world_center_y = S32((-mPanY / mMapScale) + (camera_global.mdV[1] / REGION_WIDTH_METERS)); // Compute the boundaries into sim grid coordinates - S32 world_left = world_center_x - S32(half_width / sMapScale) - 1; - S32 world_right = world_center_x + S32(half_width / sMapScale) + 1; - S32 world_bottom = world_center_y - S32(half_height / sMapScale) - 1; - S32 world_top = world_center_y + S32(half_height / sMapScale) + 1; + S32 world_left = world_center_x - S32(half_width / mMapScale) - 1; + S32 world_right = world_center_x + S32(half_width / mMapScale) + 1; + S32 world_bottom = world_center_y - S32(half_height / mMapScale) - 1; + S32 world_top = world_center_y + S32(half_height / mMapScale) + 1; - //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : sMapScale = " << sMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL; + //LL_INFOS("WorldMap") << "LLWorldMapView::updateVisibleBlocks() : mMapScale = " << mMapScale << ", left = " << world_left << ", right = " << world_right << ", bottom = " << world_bottom << ", top = " << world_top << LL_ENDL; LLWorldMap::getInstance()->updateRegions(world_left, world_bottom, world_right, world_top); } @@ -1779,10 +1783,10 @@ BOOL LLWorldMapView::handleHover( S32 x, S32 y, MASK mask ) F32 delta_y = (F32)(gViewerWindow->getCurrentMouseDY()); // Set pan to value at start of drag + offset - sPanX += delta_x; - sPanY += delta_y; - sTargetPanX = sPanX; - sTargetPanY = sPanY; + mPanX += delta_x; + mPanY += delta_y; + mTargetPanX = mPanX; + mTargetPanY = mPanY; gViewerWindow->moveCursorToCenter(); } diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index 9a549a443a..edbdded120 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -67,20 +67,21 @@ public: bool checkItemHit(S32 x, S32 y, LLItemInfo& item, LLUUID* id, bool track); void handleClick(S32 x, S32 y, MASK mask, S32* hit_type, LLUUID* id); - // Zoom, scale, and pan are shared across all instances! (i.e. Terrain and Objects maps are always registered) - // Scale and zoom are the same thing but with different units. - // Scale is for things defined in in-world coordinates. + // Scale, aka zoom, is shared across all instances! (i.e. Terrain and Objects maps are always registered) // Zoom is used for UI and will interpolate the map scale over multiple frames. + void zoom(F32 zoom); + void zoomWithPivot(F32 zoom, S32 x, S32 y); + F32 getZoom(); + // Scale is a linear scaling factor of in-world coordinates + F32 getScale(); + // setScaleSetting/getScaleSetting are for the default map setting on login + static void setScaleSetting(F32 scaleSetting); + static F32 getScaleSetting(); // Pan is in pixels relative to the center of the map. - static void zoom(F32 zoom); - static void zoomWithPivot(F32 zoom, S32 x, S32 y); - static F32 getZoom(); - static void setScale(F32 scale, bool snap = true); - static F32 getScale(); - static void translatePan( S32 delta_x, S32 delta_y ); - static void setPan( S32 x, S32 y, BOOL snap = TRUE ); + void translatePan( S32 delta_x, S32 delta_y ); + void setPan( S32 x, S32 y, BOOL snap = TRUE ); // Return true if the current scale level is above the threshold for accessing region info - static bool showRegionInfo(); + bool showRegionInfo(); LLVector3 globalPosToView(const LLVector3d& global_pos); LLVector3d viewPosToGlobal(S32 x,S32 y); @@ -163,10 +164,10 @@ public: BOOL mItemPicked; - static F32 sPanX; // in pixels - static F32 sPanY; // in pixels - static F32 sTargetPanX; // in pixels - static F32 sTargetPanY; // in pixels + F32 mPanX; // in pixels + F32 mPanY; // in pixels + F32 mTargetPanX; // in pixels + F32 mTargetPanY; // in pixels static S32 sTrackingArrowX; static S32 sTrackingArrowY; static bool sVisibleTilesLoaded; @@ -201,16 +202,16 @@ public: private: void drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right); + void setScale(F32 scale, bool snap = true); + static F32 scaleFromZoom(F32 zoom); static F32 zoomFromScale(F32 scale); - static F32 sMapScale; - static F32 sTargetMapScale; + F32 mMapScale; + F32 mTargetMapScale; + static F32 sMapScaleSetting; static LLVector2 sZoomPivot; static LLFrameTimer sZoomTimer; - - static F32 sWidthForZoom; - static F32 sHeightForZoom; }; #endif -- cgit v1.2.3 From bd87a5b94254e6a827de2298989c0116a81efdc3 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 22 Mar 2022 17:43:01 -0700 Subject: SL-17058: Convert frustum on minimap to arc from triangle --- indra/newview/llnetmap.cpp | 55 ++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index d0fe771295..1559ed401d 100755 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -488,41 +488,34 @@ void LLNetMap::draw() F32 horiz_fov = LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect(); F32 far_clip_meters = LLViewerCamera::getInstance()->getFar(); F32 far_clip_pixels = far_clip_meters * meters_to_pixels; - - F32 half_width_meters = far_clip_meters * tan( horiz_fov / 2 ); - F32 half_width_pixels = half_width_meters * meters_to_pixels; - F32 ctr_x = (F32)center_sw_left; - F32 ctr_y = (F32)center_sw_bottom; - + F32 ctr_x = (F32)center_sw_left; + F32 ctr_y = (F32)center_sw_bottom; - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + const F32 steps_per_circle = 40.0f; + const F32 steps_per_radian = steps_per_circle / F_TWO_PI; + const F32 arc_start = -(horiz_fov / 2.0f) + F_PI_BY_TWO; + const F32 arc_end = (horiz_fov / 2.0f) + F_PI_BY_TWO; + const S32 steps = llmax(1, (S32)((horiz_fov * steps_per_radian) + 0.5f)); - if( rotate_map ) - { - gGL.color4fv((map_frustum_color()).mV); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.begin( LLRender::TRIANGLES ); - gGL.vertex2f( ctr_x, ctr_y ); - gGL.vertex2f( ctr_x - half_width_pixels, ctr_y + far_clip_pixels ); - gGL.vertex2f( ctr_x + half_width_pixels, ctr_y + far_clip_pixels ); - gGL.end(); - } - else - { - gGL.color4fv((map_frustum_rotating_color()).mV); - - // If we don't rotate the map, we have to rotate the frustum. - gGL.pushMatrix(); - gGL.translatef( ctr_x, ctr_y, 0 ); - gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); - gGL.begin( LLRender::TRIANGLES ); - gGL.vertex2f( 0, 0 ); - gGL.vertex2f( -half_width_pixels, far_clip_pixels ); - gGL.vertex2f( half_width_pixels, far_clip_pixels ); - gGL.end(); - gGL.popMatrix(); - } + if( rotate_map ) + { + gGL.pushMatrix(); + gGL.translatef( ctr_x, ctr_y, 0 ); + gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color()); + gGL.popMatrix(); + } + else + { + gGL.pushMatrix(); + gGL.translatef( ctr_x, ctr_y, 0 ); + // If we don't rotate the map, we have to rotate the frustum. + gGL.rotatef( atan2( LLViewerCamera::getInstance()->getAtAxis().mV[VX], LLViewerCamera::getInstance()->getAtAxis().mV[VY] ) * RAD_TO_DEG, 0.f, 0.f, -1.f); + gl_washer_segment_2d(far_clip_pixels, 0, arc_start, arc_end, steps, map_frustum_color(), map_frustum_color()); + gGL.popMatrix(); + } } gGL.popMatrix(); -- cgit v1.2.3 From 9bca1aa8fb69c2163866dd7e5ce3b60fb62676b3 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 10 Mar 2022 16:52:29 -0800 Subject: SL-15232: Clang format --- indra/newview/llfloaterworldmap.cpp | 12 ++-- indra/newview/llworldmapview.cpp | 127 +++++++++++++++--------------------- 2 files changed, 59 insertions(+), 80 deletions(-) mode change 100644 => 100755 indra/newview/llfloaterworldmap.cpp mode change 100644 => 100755 indra/newview/llworldmapview.cpp diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp old mode 100644 new mode 100755 index cf314c3e60..e54e042006 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -407,14 +407,14 @@ BOOL LLFloaterWorldMap::handleScrollWheel(S32 x, S32 y, S32 clicks) S32 map_y = y - mMapView->getRect().mBottom; if (mMapView->pointInView(map_x, map_y)) { - F32 old_slider_zoom = (F32)getChild("zoom slider")->getValue().asReal(); - F32 slider_zoom = old_slider_zoom + ((F32)clicks * -0.3333f); + F32 old_slider_zoom = (F32) getChild("zoom slider")->getValue().asReal(); + F32 slider_zoom = old_slider_zoom + ((F32) clicks * -0.3333f); getChild("zoom slider")->setValue(LLSD(slider_zoom)); mMapView->zoomWithPivot(slider_zoom, map_x, map_y); return true; } } - + return LLFloater::handleScrollWheel(x, y, clicks); } @@ -1267,8 +1267,8 @@ void LLFloaterWorldMap::onShowTargetBtn() void LLFloaterWorldMap::onShowAgentBtn() { - mMapView->setPan(0, 0, false); // false == animate - // Set flag so user's location will be displayed if not tracking anything else + mMapView->setPan(0, 0, false); // false == animate + // Set flag so user's location will be displayed if not tracking anything else mSetToUserPosition = true; } @@ -1622,6 +1622,6 @@ void LLFloaterWorldMap::onChangeMaturity() void LLFloaterWorldMap::onFocusLost() { - gViewerWindow->showCursor(); + gViewerWindow->showCursor(); mMapView->mPanning = false; } diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp old mode 100644 new mode 100755 index cad655ea48..57292f98a0 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -170,26 +170,26 @@ void LLWorldMapView::cleanupClass() sForSaleAdultImage = NULL; } -LLWorldMapView::LLWorldMapView() -: LLPanel(), - mBackgroundColor( LLColor4( OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f ) ), - mItemPicked(FALSE), +LLWorldMapView::LLWorldMapView() : + LLPanel(), + mBackgroundColor(LLColor4(OCEAN_RED, OCEAN_GREEN, OCEAN_BLUE, 1.f)), + mItemPicked(FALSE), mPanX(0.f), mPanY(0.f), mTargetPanX(0.f), mTargetPanY(0.f), - mPanning( FALSE ), - mMouseDownPanX( 0 ), - mMouseDownPanY( 0 ), - mMouseDownX( 0 ), - mMouseDownY( 0 ), + mPanning(FALSE), + mMouseDownPanX(0), + mMouseDownPanY(0), + mMouseDownX(0), + mMouseDownY(0), mSelectIDStart(0), mMapScale(0.f), mTargetMapScale(0.f) { - //LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; + // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; - clearLastClick(); + clearLastClick(); } BOOL LLWorldMapView::postBuild() @@ -253,104 +253,89 @@ void LLWorldMapView::zoom(F32 zoom) void LLWorldMapView::zoomWithPivot(F32 zoom, S32 x, S32 y) { mTargetMapScale = scaleFromZoom(zoom); - sZoomPivot = LLVector2(x, y); + sZoomPivot = LLVector2(x, y); if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) { sZoomTimer.start(); } } -F32 LLWorldMapView::getZoom() -{ - return LLWorldMapView::zoomFromScale(mMapScale); -} +F32 LLWorldMapView::getZoom() { return LLWorldMapView::zoomFromScale(mMapScale); } -F32 LLWorldMapView::getScale() -{ - return mMapScale; -} +F32 LLWorldMapView::getScale() { return mMapScale; } // static -void LLWorldMapView::setScaleSetting(F32 scaleSetting) -{ - sMapScaleSetting = scaleSetting; -} +void LLWorldMapView::setScaleSetting(F32 scaleSetting) { sMapScaleSetting = scaleSetting; } // static -F32 LLWorldMapView::getScaleSetting() -{ - return sMapScaleSetting; -} +F32 LLWorldMapView::getScaleSetting() { return sMapScaleSetting; } void LLWorldMapView::setScale(F32 scale, bool snap) { - if (scale != mMapScale) - { - F32 old_scale = mMapScale; + if (scale != mMapScale) + { + F32 old_scale = mMapScale; - mMapScale = scale; + mMapScale = scale; // Set the scale used when saving the setting sMapScaleSetting = scale; - if (mMapScale <= 0.f) - { - mMapScale = 0.1f; - } + if (mMapScale <= 0.f) + { + mMapScale = 0.1f; + } + + F32 ratio = (scale / old_scale); + mPanX *= ratio; + mPanY *= ratio; + mTargetPanX = mPanX; + mTargetPanY = mPanY; + sVisibleTilesLoaded = false; - F32 ratio = (scale / old_scale); - mPanX *= ratio; - mPanY *= ratio; - mTargetPanX = mPanX; - mTargetPanY = mPanY; - sVisibleTilesLoaded = false; - // If we are zooming relative to somewhere else rather than the center of the map, compensate for the difference in panning here if (!sZoomPivot.isExactlyZero()) { LLVector2 relative_pivot; - relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0); - relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0); + relative_pivot.mV[VX] = sZoomPivot.mV[VX] - (getRect().getWidth() / 2.0); + relative_pivot.mV[VY] = sZoomPivot.mV[VY] - (getRect().getHeight() / 2.0); LLVector2 zoom_pan_offset = relative_pivot - (relative_pivot * scale / old_scale); mPanX += zoom_pan_offset.mV[VX]; mPanY += zoom_pan_offset.mV[VY]; mTargetPanX += zoom_pan_offset.mV[VX]; mTargetPanY += zoom_pan_offset.mV[VY]; } - } + } if (snap) { mTargetMapScale = scale; -} + } } // static -void LLWorldMapView::translatePan( S32 delta_x, S32 delta_y ) +void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y) { - mPanX += delta_x; - mPanY += delta_y; - mTargetPanX = mPanX; - mTargetPanY = mPanY; - sVisibleTilesLoaded = false; + mPanX += delta_x; + mPanY += delta_y; + mTargetPanX = mPanX; + mTargetPanY = mPanY; + sVisibleTilesLoaded = false; } // static -void LLWorldMapView::setPan( S32 x, S32 y, BOOL snap ) +void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap) { - mTargetPanX = (F32)x; - mTargetPanY = (F32)y; - if (snap) - { - mPanX = mTargetPanX; - mPanY = mTargetPanY; - } - sVisibleTilesLoaded = false; + mTargetPanX = (F32) x; + mTargetPanY = (F32) y; + if (snap) + { + mPanX = mTargetPanX; + mPanY = mTargetPanY; + } + sVisibleTilesLoaded = false; } -bool LLWorldMapView::showRegionInfo() -{ - return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); -} +bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); } /////////////////////////////////////////////////////////////////////////////////// // HELPERS @@ -1884,13 +1869,7 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) } // static -F32 LLWorldMapView::scaleFromZoom(F32 zoom) -{ - return exp2(zoom) * 256.0f; -} +F32 LLWorldMapView::scaleFromZoom(F32 zoom) { return exp2(zoom) * 256.0f; } // static -F32 LLWorldMapView::zoomFromScale(F32 scale) -{ - return log2(scale / 256.f); -} +F32 LLWorldMapView::zoomFromScale(F32 scale) { return log2(scale / 256.f); } -- cgit v1.2.3 From d4cadd53d49b47c56ab3ff5bbfab6f2baf5a4631 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 23 Mar 2022 09:38:54 -0700 Subject: SL-17058: Remove redundant minimap frustum color, hopefully fixing mac build. So THAT's why the frustum transparency was different when rotating... --- indra/newview/llnetmap.cpp | 1 - indra/newview/skins/default/colors.xml | 3 --- 2 files changed, 4 deletions(-) diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 1559ed401d..5cae3ce8d6 100755 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -171,7 +171,6 @@ void LLNetMap::draw() static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white); //static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white); static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white); - static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white); static LLUIColor map_parcel_outline_color = LLUIColorTable::instance().getColor("MapParcelOutlineColor", LLColor4(LLColor3(LLColor4::yellow), 0.5f)); if (mObjectImagep.isNull()) diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 82e1942aa5..ad2bc075c6 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -516,9 +516,6 @@ - -- cgit v1.2.3 From 651610d7541ec92d7e076860f07f6a585660fb71 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 6 Apr 2022 21:04:38 +0300 Subject: SL-17167 FIXED Crash in LLFloaterHoverHeight::onSliderMoved --- indra/newview/llfloaterhoverheight.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/indra/newview/llfloaterhoverheight.cpp b/indra/newview/llfloaterhoverheight.cpp index 42c5e40761..a00fc4aa84 100644 --- a/indra/newview/llfloaterhoverheight.cpp +++ b/indra/newview/llfloaterhoverheight.cpp @@ -100,11 +100,14 @@ void LLFloaterHoverHeight::onClose(bool app_quitting) // static void LLFloaterHoverHeight::onSliderMoved(LLUICtrl* ctrl, void* userData) { - LLSliderCtrl* sldrCtrl = static_cast(ctrl); - F32 value = sldrCtrl->getValueF32(); - LLVector3 offset(0.0, 0.0, llclamp(value,MIN_HOVER_Z,MAX_HOVER_Z)); - LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL; - gAgentAvatarp->setHoverOffset(offset, false); + if (isAgentAvatarValid()) + { + LLSliderCtrl* sldrCtrl = static_cast(ctrl); + F32 value = sldrCtrl->getValueF32(); + LLVector3 offset(0.0, 0.0, llclamp(value, MIN_HOVER_Z, MAX_HOVER_Z)); + LL_INFOS("Avatar") << "setting hover from slider moved" << offset[2] << LL_ENDL; + gAgentAvatarp->setHoverOffset(offset, false); + } } // Do send-to-the-server work when slider drag completes, or new -- cgit v1.2.3 From b5406352e9632b6466fdc9bde349ec55b368596b Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 19 Apr 2022 00:01:52 +0300 Subject: DRTVWR-548 post-merge build fix --- indra/newview/llfloaterworldmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index fb44449c55..e7b1efb41d 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -1565,7 +1565,7 @@ void LLFloaterWorldMap::onTeleportFinished() { if(isInVisibleChain()) { - LLWorldMapView::setPan(0, 0, TRUE); + mMapView->setPan(0, 0, TRUE); } } -- cgit v1.2.3 From 9e352924207447ab294f9581cfc349e17fdd6f6b Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 26 Apr 2022 16:10:52 +0300 Subject: merge fix --- indra/newview/llvoavatar.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) 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 FADE_DURATION(gSavedSettings, "RenderNameFadeDuration"); // seconds static LLCachedControl 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 ddaa0d84ccbd68eeacb81361360bfcdd5d3dfe4a Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 29 Apr 2022 19:06:22 +0300 Subject: SL-17206 FIXED Unable to move an avatar after fall on the ground --- indra/llcharacter/llkeyframemotion.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index fe9de30f0a..f2584ee6f3 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1343,6 +1343,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) return FALSE; } + //SL-17206 hack to alter Female_land loop setting, while current behavior won't be changed serverside + LLUUID const female_land_anim("ca1baf4d-0a18-5a1f-0330-e4bd1e71f09e"); + if (female_land_anim == asset_id) + { + LL_WARNS() << "Animation(" << female_land_anim << ") won't be looped." << LL_ENDL; + mJointMotionList->mLoop = FALSE; + } + //------------------------------------------------------------------------- // get easeIn and easeOut //------------------------------------------------------------------------- -- cgit v1.2.3 From 0569eb776c7ec758ca8125b500fdd4c589c5ae50 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 3 May 2022 22:25:05 +0300 Subject: SL-16053 Landmark shouldn't be saved into location history --- indra/newview/llnavigationbar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp index 19dbbeb60e..e7d4ff7cdb 100644 --- a/indra/newview/llnavigationbar.cpp +++ b/indra/newview/llnavigationbar.cpp @@ -451,9 +451,9 @@ void LLNavigationBar::onLocationSelection() if(value.has("AssetUUID")) { - gAgent.teleportViaLandmark( LLUUID(value["AssetUUID"].asString())); - mSaveToLocationHistory = true; + // user teleported by manually inputting inventory landmark's name + mSaveToLocationHistory = false; return; } else -- cgit v1.2.3 From ad8634856dcc06db79b285b6109a2da6a363b002 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 4 May 2022 22:23:03 +0300 Subject: SL-17314 Don't focus inventory when handling landmark creation --- indra/newview/llfloatercreatelandmark.cpp | 1 + indra/newview/llviewermessage.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index 6b1d9306fb..495bf5d20e 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -316,6 +316,7 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items) { removeObserver(); mItem = item; + setVisibleAndFrontmost(true); break; } } diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 10ffbc7fa7..6d19f868b4 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -33,6 +33,7 @@ #include "llavataractions.h" #include "llavatarnamecache.h" // IDEVO HACK #include "lleventtimer.h" +#include "llfloatercreatelandmark.h" #include "llfloaterreg.h" #include "llfolderview.h" #include "llfollowcamparams.h" @@ -1560,6 +1561,17 @@ bool highlight_offered_object(const LLUUID& obj_id) } } + if (obj->getType() == LLAssetType::AT_LANDMARK) + { + LLFloaterCreateLandmark *floater = LLFloaterReg::findTypedInstance("add_landmark"); + if (floater && floater->getItem() && floater->getItem()->getUUID() == obj_id) + { + // LLFloaterCreateLandmark is supposed to handle this, + // keep landmark creation floater at the front + return false; + } + } + return true; } -- cgit v1.2.3 From d647b75310dd73d9c3b1859de1a414f51422ae26 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 5 May 2022 01:05:01 +0300 Subject: SL-17314 Location and label desync Example: User can rename item in inventory, then attempt to save new landmark and changes will be lost --- indra/newview/llfloatercreatelandmark.cpp | 124 ++++++++++++++++++++- indra/newview/llfloatercreatelandmark.h | 3 + .../default/xui/en/floater_create_landmark.xml | 1 + 3 files changed, 125 insertions(+), 3 deletions(-) diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index 495bf5d20e..5b50fd7677 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -46,19 +46,60 @@ typedef std::pair folder_pair_t; -class LLLandmarksInventoryObserver : public LLInventoryAddedObserver +class LLLandmarksInventoryObserver : public LLInventoryObserver { public: LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) : mFloater(create_landmark_floater) {} + void changed(U32 mask) override + { + if (mFloater->getItem()) + { + checkChanged(mask); + } + else + { + checkCreated(mask); + } + } + protected: - /*virtual*/ void done() + void checkCreated(U32 mask) { + if (gInventory.getAddedIDs().empty()) + { + return; + } + + if (!(mask & LLInventoryObserver::ADD) || + !(mask & LLInventoryObserver::CREATE) || + !(mask & LLInventoryObserver::UPDATE_CREATE)) + { + return; + } + mFloater->setItem(gInventory.getAddedIDs()); } + void checkChanged(U32 mask) + { + if (gInventory.getChangedIDs().empty()) + { + return; + } + + if ((mask & LLInventoryObserver::LABEL) || + (mask & LLInventoryObserver::INTERNAL) || + (mask & LLInventoryObserver::REMOVE) || + (mask & LLInventoryObserver::STRUCTURE) || + (mask & LLInventoryObserver::REBUILD)) + { + mFloater->updateItem(gInventory.getChangedIDs(), mask); + } + } + private: LLFloaterCreateLandmark* mFloater; }; @@ -85,6 +126,9 @@ BOOL LLFloaterCreateLandmark::postBuild() getChild("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this)); getChild("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this)); + mLandmarkTitleEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); }); + mNotesEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) { onCommitTextChanges(); }); + mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK); return TRUE; @@ -204,6 +248,29 @@ void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id) } } +void LLFloaterCreateLandmark::onCommitTextChanges() +{ + std::string current_title_value = mLandmarkTitleEditor->getText(); + std::string item_title_value = mItem->getName(); + std::string current_notes_value = mNotesEditor->getText(); + std::string item_notes_value = mItem->getDescription(); + + LLStringUtil::trim(current_title_value); + LLStringUtil::trim(current_notes_value); + + if (!current_title_value.empty() && + (item_title_value != current_title_value || item_notes_value != current_notes_value)) + { + LLPointer new_item = new LLViewerInventoryItem(mItem); + new_item->rename(current_title_value); + new_item->setDescription(current_notes_value); + LLPointer cb; + LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0); + gInventory.accountForUpdate(up); + update_inventory_item(new_item, cb); + } +} + void LLFloaterCreateLandmark::onCreateFolderClicked() { LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(), @@ -278,6 +345,8 @@ void LLFloaterCreateLandmark::onSaveClicked() new_item->updateParentOnServer(FALSE); } + removeObserver(); + gInventory.updateItem(new_item); gInventory.notifyObservers(); @@ -286,6 +355,7 @@ void LLFloaterCreateLandmark::onSaveClicked() void LLFloaterCreateLandmark::onCancelClicked() { + removeObserver(); if (!mItem.isNull()) { LLUUID item_id = mItem->getUUID(); @@ -314,11 +384,59 @@ void LLFloaterCreateLandmark::setItem(const uuid_set_t& items) { if(!getItem()) { - removeObserver(); mItem = item; + mAssetID = mItem->getAssetUUID(); setVisibleAndFrontmost(true); break; } } } } + +void LLFloaterCreateLandmark::updateItem(const uuid_set_t& items, U32 mask) +{ + if (!getItem()) + { + return; + } + + LLUUID landmark_id = getItem()->getUUID(); + + for (uuid_set_t::const_iterator item_iter = items.begin(); + item_iter != items.end(); + ++item_iter) + { + const LLUUID& item_id = (*item_iter); + if (landmark_id == item_id) + { + if (getItem() != gInventory.getItem(item_id)) + { + // item is obsolete or removed + closeFloater(); + } + + LLUUID folder_id = mFolderCombo->getValue().asUUID(); + if (folder_id != mItem->getParentUUID()) + { + // user moved landmark in inventory, + // assume that we are done all other changes should already be commited + closeFloater(); + } + + if ((mask & LLInventoryObserver::INTERNAL) && mAssetID != mItem->getAssetUUID()) + { + closeFloater(); + } + + if (mask & LLInventoryObserver::LABEL) + { + mLandmarkTitleEditor->setText(mItem->getName()); + } + + if (mask & LLInventoryObserver::INTERNAL) + { + mNotesEditor->setText(mItem->getDescription()); + } + } + } +} diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h index 74ac5e651c..d84f5ae1fc 100644 --- a/indra/newview/llfloatercreatelandmark.h +++ b/indra/newview/llfloatercreatelandmark.h @@ -49,6 +49,7 @@ public: void onOpen(const LLSD& key); void setItem(const uuid_set_t& items); + void updateItem(const uuid_set_t& items, U32 mask); LLInventoryItem* getItem() { return mItem; } @@ -56,6 +57,7 @@ private: void setLandmarkInfo(const LLUUID &folder_id); void removeObserver(); void populateFoldersList(const LLUUID &folder_id = LLUUID::null); + void onCommitTextChanges(); void onCreateFolderClicked(); void onSaveClicked(); void onCancelClicked(); @@ -66,6 +68,7 @@ private: LLLineEditor* mLandmarkTitleEditor; LLTextEditor* mNotesEditor; LLUUID mLandmarksID; + LLUUID mAssetID; LLLandmarksInventoryObserver* mInventoryObserver; LLPointer mItem; diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml index bba30626b2..632daaec7e 100644 --- a/indra/newview/skins/default/xui/en/floater_create_landmark.xml +++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml @@ -88,6 +88,7 @@ spellcheck="true" text_readonly_color="white" text_type="ascii_with_newline" + commit_on_focus_lost="true" top_pad="5" width="290" wrap="true" /> -- cgit v1.2.3 From 77d10601c77b35d5480f4e73a9b0f74c21729437 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 5 May 2022 10:36:26 -0700 Subject: SL-16916: Fix incorrect defaults for minimap rotation and minimap scale --- indra/newview/app_settings/settings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 05d04e38db..74241823f4 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6797,7 +6797,7 @@ Type Boolean Value - 1 + 0 MiniMapScale @@ -6808,7 +6808,7 @@ Type F32 Value - 64.0 + 128.0 MiniMapShowPropertyLines -- cgit v1.2.3 From 7565e734d29112e14e885a6097805c1315b81917 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 10 May 2022 14:57:24 -0700 Subject: SL-2243 - match server physics shape calculation re mesh dimensions --- indra/newview/llphysicsshapebuilderutil.cpp | 13 ++++++++++++- indra/newview/llphysicsshapebuilderutil.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp index 5bfe5c9941..9603ee6329 100644 --- a/indra/newview/llphysicsshapebuilderutil.cpp +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -29,7 +29,7 @@ #include "llphysicsshapebuilderutil.h" /* static */ -void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut ) +void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut) { const LLProfileParams& profile_params = volume_params.getProfileParams(); const LLPathParams& path_params = volume_params.getPathParams(); @@ -191,6 +191,7 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara if ( volume_params.shouldForceConvex() ) { + // Server distinguishes between convex of a prim vs isSculpt, but we don't care. specOut.mType = PhysicsShapeSpecification::USER_CONVEX; } // Make a simpler convex shape if we can. @@ -199,6 +200,16 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara { specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; } + else if (volume_params.isMeshSculpt() && + // Check overall dimensions, not individual triangles. + (scale.mV[0] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[1] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE || + scale.mV[2] < SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE + ) ) + { + // Server distinguishes between user-specified or default convex mesh, vs server's thin-triangle override, but we don't. + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; + } else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy) { specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT; diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h index bd5b7d799c..b3b100296f 100644 --- a/indra/newview/llphysicsshapebuilderutil.h +++ b/indra/newview/llphysicsshapebuilderutil.h @@ -47,6 +47,7 @@ const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f; const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f; const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE; const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE; +const F32 SHAPE_BUILDER_USER_MESH_CONVEXIFICATION_SIZE = 0.5f; class LLPhysicsVolumeParams : public LLVolumeParams { -- cgit v1.2.3 From f7edcab9c3187a2dc797db614ba0302ed7eed578 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Fri, 7 Dec 2018 21:27:12 +0000 Subject: SL-288, SL-10163 - allow joint aliases, but otherwise reject upload of animations containing invalid joint names # Conflicts: # indra/newview/llviewerassetupload.cpp # indra/newview/llvoavatar.cpp --- indra/llappearance/llavatarappearance.cpp | 4 ++- indra/llcharacter/llkeyframemotion.cpp | 10 +++++-- indra/llcharacter/llkeyframemotion.h | 2 +- indra/newview/llfloaterbvhpreview.cpp | 2 +- indra/newview/llviewerassetupload.cpp | 49 +++++++++++++++++++++++++++++-- indra/newview/llvoavatar.cpp | 13 ++++++-- 6 files changed, 71 insertions(+), 9 deletions(-) diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp index 90dfa04f28..6c77a9242e 100644 --- a/indra/llappearance/llavatarappearance.cpp +++ b/indra/llappearance/llavatarappearance.cpp @@ -927,6 +927,9 @@ BOOL LLAvatarAppearance::loadAvatar() return FALSE; } + // initialize mJointAliasMap + getJointAliases(); + // avatar_lad.xml : if( !loadSkeletonNode() ) { @@ -1047,7 +1050,6 @@ BOOL LLAvatarAppearance::loadAvatar() return FALSE; } } - return TRUE; } diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index f2584ee6f3..daff69c73a 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1221,8 +1221,11 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 //----------------------------------------------------------------------------- // deserialize() +// +// allow_invalid_joints should be true when handling existing content, to avoid breakage. +// During upload, we should be more restrictive and reject such animations. //----------------------------------------------------------------------------- -BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) +BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) { BOOL old_version = FALSE; mJointMotionList = new LLKeyframeMotion::JointMotionList; @@ -1464,7 +1467,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id) { LL_WARNS() << "invalid joint name: " << joint_name << " for animation " << asset_id << LL_ENDL; - //return FALSE; + if (!allow_invalid_joints) + { + return FALSE; + } } joint_motion->mJointName = joint_name; diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index 9a927ede9a..ff29a90010 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -156,7 +156,7 @@ public: public: U32 getFileSize(); BOOL serialize(LLDataPacker& dp) const; - BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id); + BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true); BOOL isLoaded() { return mJointMotionList != NULL; } void dumpToFile(const std::string& name); diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp index 687d820a18..09cf44bdf2 100644 --- a/indra/newview/llfloaterbvhpreview.cpp +++ b/indra/newview/llfloaterbvhpreview.cpp @@ -294,7 +294,7 @@ BOOL LLFloaterBvhPreview::postBuild() loaderp->serialize(dp); dp.reset(); LL_INFOS("BVH") << "Deserializing motionp" << LL_ENDL; - BOOL success = motionp && motionp->deserialize(dp, mMotionID); + BOOL success = motionp && motionp->deserialize(dp, mMotionID, false); LL_INFOS("BVH") << "Done" << LL_ENDL; delete []buffer; diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 3f7e8531fb..a320f07a9f 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -450,9 +450,54 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() errorLabel = "DoNotSupportBulkAnimationUpload"; error = true; } - else if (assetType == LLAssetType::AT_ANIMATION) + else if (exten == "anim") + { + // Default unless everything succeeds + errorLabel = "ProblemWithFile"; + error = true; + + // read from getFileName() + LLAPRFile infile; + infile.open(getFileName(),LL_APR_RB); + if (!infile.getFileHandle()) + { + LL_WARNS() << "Couldn't open file for reading: " << getFileName() << LL_ENDL; + errorMessage = llformat("Failed to open animation file %s\n", getFileName().c_str()); + } + else + { + S32 size = LLAPRFile::size(getFileName()); + U8* buffer = new U8[size]; + S32 size_read = infile.read(buffer,size); + if (size_read != size) + { + errorMessage = llformat("Failed to read animation file %s: wanted %d bytes, got %d\n", getFileName().c_str(), size, size_read); + } + else + { + LLDataPackerBinaryBuffer dp(buffer, size); + LLKeyframeMotion *motionp = new LLKeyframeMotion(getAssetId()); + motionp->setCharacter(gAgentAvatarp); + if (motionp->deserialize(dp, getAssetId(), false)) + { + // write to temp file + bool succ = motionp->dumpToFile(filename); + if (succ) + { + assetType = LLAssetType::AT_ANIMATION; + errorLabel = ""; + error = false; + } + } + } + } + } + else { - filename = getFileName(); + // Unknown extension + errorMessage = llformat(LLTrans::getString("UnknownFileExtension").c_str(), exten.c_str()); + errorLabel = "ErrorMessage"; + error = TRUE;; } if (error) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index d421b3b1f6..487730e209 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6145,8 +6145,17 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* jointp = NULL; if (iter == mJointMap.end() || iter->second == NULL) - { //search for joint and cache found joint in lookup table - jointp = mRoot->findJoint(name); + joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); + std::string canonical_name; + if (alias_iter != mJointAliasMap.end()) + { + canonical_name = alias_iter->second; + } + else + { + canonical_name = name; + } + jointp = mRoot->findJoint(canonical_name); mJointMap[name] = jointp; } else -- cgit v1.2.3 From 4413f9be879c14328988ce4d285c1dfa263db027 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Mon, 10 Dec 2018 15:02:41 +0000 Subject: SL-288, SL-10163 - error reporting for animation upload failures. --- indra/newview/llviewerassetupload.cpp | 9 +++++++++ indra/newview/llvoavatar.cpp | 1 + 2 files changed, 10 insertions(+) diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index a320f07a9f..7c6721cad9 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -488,6 +488,14 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile() errorLabel = ""; error = false; } + else + { + errorMessage = "Failed saving temporary animation file"; + } + } + else + { + errorMessage = "Failed reading animation file"; } } } @@ -908,6 +916,7 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res { args["FILE"] = uploadInfo->getDisplayName(); args["REASON"] = reason; + args["ERROR"] = reason; } LLNotificationsUtil::add(label, args); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 487730e209..b1f04601fd 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6145,6 +6145,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* jointp = NULL; if (iter == mJointMap.end() || iter->second == NULL) + { joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); std::string canonical_name; if (alias_iter != mJointAliasMap.end()) -- cgit v1.2.3 From 307db06310d6d3dc5a38da5543d0f074266fb12a Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 6 Dec 2018 21:58:14 +0000 Subject: SL-10163 - allow joint aliases in animation uploads. Names are canonicalized before sending to simulator. # Conflicts: # indra/newview/llviewerassetupload.cpp # indra/newview/llvoavatar.cpp # scripts/content_tools/anim_tool.py --- indra/llcharacter/llkeyframemotion.cpp | 26 ++++++++++++++++++++++---- indra/llcharacter/llkeyframemotion.h | 5 ++++- indra/newview/llviewerassetupload.cpp | 4 ++++ indra/newview/llvoavatar.cpp | 6 +++++- scripts/content_tools/anim_tool.py | 8 +++++++- 5 files changed, 42 insertions(+), 7 deletions(-) diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index daff69c73a..1eee736b48 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1453,6 +1453,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (joint) { S32 joint_num = joint->getJointNum(); + joint_name = joint->getName(); // canonical name in case this is an alias. // LL_INFOS() << " joint: " << joint_name << LL_ENDL; if ((joint_num >= (S32)LL_CHARACTER_MAX_ANIMATED_JOINTS) || (joint_num < 0)) { @@ -2109,8 +2110,9 @@ U32 LLKeyframeMotion::getFileSize() //----------------------------------------------------------------------------- // dumpToFile() //----------------------------------------------------------------------------- -void LLKeyframeMotion::dumpToFile(const std::string& name) +bool LLKeyframeMotion::dumpToFile(const std::string& name) { + bool succ = false; if (isLoaded()) { std::string outfile_base; @@ -2127,10 +2129,24 @@ void LLKeyframeMotion::dumpToFile(const std::string& name) const LLUUID& id = getID(); outfile_base = id.asString(); } - std::string outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base + ".anim"); + + if (gDirUtilp->getExtension(outfile_base).empty()) + { + outfile_base += ".anim"; + } + std::string outfilename; + if (gDirUtilp->getDirName(outfile_base).empty()) + { + outfilename = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfile_base); + } + else + { + outfilename = outfile_base; + } if (LLFile::isfile(outfilename)) { - return; + LL_WARNS() << outfilename << " already exists, write failed" << LL_ENDL; + return false; } S32 file_size = getFileSize(); @@ -2144,11 +2160,13 @@ void LLKeyframeMotion::dumpToFile(const std::string& name) outfile.open(outfilename, LL_APR_WPB); if (outfile.getFileHandle()) { - outfile.write(buffer, file_size); + S32 wrote_bytes = outfile.write(buffer, file_size); + succ = (wrote_bytes == file_size); } } delete [] buffer; } + return succ; } //----------------------------------------------------------------------------- diff --git a/indra/llcharacter/llkeyframemotion.h b/indra/llcharacter/llkeyframemotion.h index ff29a90010..96746f57c9 100644 --- a/indra/llcharacter/llkeyframemotion.h +++ b/indra/llcharacter/llkeyframemotion.h @@ -158,7 +158,7 @@ public: BOOL serialize(LLDataPacker& dp) const; BOOL deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints = true); BOOL isLoaded() { return mJointMotionList != NULL; } - void dumpToFile(const std::string& name); + bool dumpToFile(const std::string& name); // setters for modifying a keyframe animation @@ -432,6 +432,9 @@ protected: F32 mLastUpdateTime; F32 mLastLoopedTime; AssetStatus mAssetStatus; + +public: + void setCharacter(LLCharacter* character) { mCharacter = character; } }; class LLKeyframeDataCache diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 7c6721cad9..14fae8d035 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -50,6 +50,10 @@ #include "llpreviewnotecard.h" #include "llpreviewgesture.h" #include "llcoproceduremanager.h" +#include "llthread.h" +#include "llkeyframemotion.h" +#include "lldatapacker.h" +#include "llvoavatarself.h" void dialog_refresh_all(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index b1f04601fd..8c8025e352 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -6145,7 +6145,11 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name ) LLJoint* jointp = NULL; if (iter == mJointMap.end() || iter->second == NULL) - { + { //search for joint and cache found joint in lookup table + if (mJointAliasMap.empty()) + { + getJointAliases(); + } joint_alias_map_t::const_iterator alias_iter = mJointAliasMap.find(name); std::string canonical_name; if (alias_iter != mJointAliasMap.end()) diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py index e7b86a88fa..205fc2b6e1 100644 --- a/scripts/content_tools/anim_tool.py +++ b/scripts/content_tools/anim_tool.py @@ -637,6 +637,7 @@ def main(*argv): parser.add_argument("--no_hud", help="omit hud joints from list of attachments", action="store_true") parser.add_argument("--base_priority", help="set base priority", type=int) parser.add_argument("--joint_priority", help="set joint priority for all joints", type=int) + parser.add_argument("--force_joints", help="don't check validity of joint names", action="store_true") parser.add_argument("infilename", help="name of a .anim file to input") parser.add_argument("outfilename", nargs="?", help="name of a .anim file to output") args = parser.parse_args(argv) @@ -661,7 +662,12 @@ def main(*argv): if lad_tree is None: raise Error("failed to parse " + args.lad) if args.joints: - joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud) + if args.force_joints: + joints = args.joints + else: + joints = resolve_joints(args.joints, skel_tree, lad_tree, args.no_hud) + if args.use_aliases: + joints = map(lambda name: "avatar_" + name, joints) if args.verbose: print("joints resolved to",joints) for name in joints: -- cgit v1.2.3 From b3bfe05494aa12d87728f7df93ce72bc25019b33 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Tue, 4 Dec 2018 20:02:25 +0000 Subject: SL-10025 - via Cathy Foil, all bones now have standard alias 'avatar_' + name. # Conflicts: # scripts/content_tools/anim_tool.py --- indra/newview/character/avatar_skeleton.xml | 214 ++++++++++++++-------------- scripts/content_tools/anim_tool.py | 1 + scripts/content_tools/skel_tool.py | 17 +++ 3 files changed, 125 insertions(+), 107 deletions(-) diff --git a/indra/newview/character/avatar_skeleton.xml b/indra/newview/character/avatar_skeleton.xml index 2241a12545..6cfc0b0be2 100644 --- a/indra/newview/character/avatar_skeleton.xml +++ b/indra/newview/character/avatar_skeleton.xml @@ -2,15 +2,15 @@ - - + + - - + + @@ -23,58 +23,58 @@ - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - + + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - + + + @@ -86,29 +86,29 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + @@ -123,49 +123,49 @@ - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - + + + + + + - - - - - + + + + + @@ -200,30 +200,30 @@ - - - - - - + + + + + + - - - - - - + + + + + + - - - - + + + + diff --git a/scripts/content_tools/anim_tool.py b/scripts/content_tools/anim_tool.py index 205fc2b6e1..4a0773951e 100644 --- a/scripts/content_tools/anim_tool.py +++ b/scripts/content_tools/anim_tool.py @@ -611,6 +611,7 @@ def main(*argv): parser = argparse.ArgumentParser(description="process SL animations") parser.add_argument("--verbose", help="verbose flag", action="store_true") parser.add_argument("--dump", help="dump to stdout", action="store_true") + parser.add_argument("--use_aliases", help="use alias names for bones", action="store_true") parser.add_argument("--rot", help="specify sequence of rotations", type=float_triple, nargs="+") parser.add_argument("--rand_pos", help="request NUM random positions (default %(default)s)", metavar="NUM", type=int, default=2) diff --git a/scripts/content_tools/skel_tool.py b/scripts/content_tools/skel_tool.py index 449ecd6a6c..696e4e2923 100644 --- a/scripts/content_tools/skel_tool.py +++ b/scripts/content_tools/skel_tool.py @@ -72,6 +72,22 @@ def check_symmetry(name, field, vec1, vec2): if vec1[2] != vec2[2]: print(name,field,"z match fail") +def enforce_alias_rules(tree, element, fix=False): + if element.tag != "bone": + return + alias_lis = [] + aliases = element.get("aliases") + if aliases: + alias_lis = aliases.split(" ") + name = element.get("name") + if name: + std_alias = "avatar_" + name + if not std_alias in alias_lis: + print "missing expected alias",name,std_alias + for alias in alias_lis: + if alias.startswith("avatar_") and alias != std_alias: + print "invalid avatar_ alias",name,alias + def enforce_symmetry(tree, element, field, fix=False): name = element.get("name") if not name: @@ -209,6 +225,7 @@ def validate_skel_tree(tree, ogtree, reftree, fix=False): unfixable += 1 fix_name(element) + enforce_alias_rules(tree, element, fix) enforce_precision_rules(element) for field in ["pos","pivot"]: enforce_symmetry(tree, element, field, fix) -- cgit v1.2.3 From eaf9171aca0f1073674a009548fc86eb2d623c4b Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 19 May 2022 11:18:05 +0300 Subject: SL-17404 Adjust 'More' button width --- indra/newview/skins/default/xui/ru/panel_navigation_bar.xml | 2 +- indra/newview/skins/default/xui/tr/panel_navigation_bar.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml index 5e3de180f9..331ba889d8 100644 --- a/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/ru/panel_navigation_bar.xml @@ -14,7 +14,7 @@ - + Больше ▼ diff --git a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml index 8d43e3fb5a..ae9bc33bfa 100644 --- a/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml +++ b/indra/newview/skins/default/xui/tr/panel_navigation_bar.xml @@ -14,7 +14,7 @@ - + Daha Fazla ▼ -- cgit v1.2.3 From 6fb787cd10ea840a9d099715e7462bb5f29c5e6b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 20 May 2022 11:56:31 -0700 Subject: SL-17463: Set the default for MiniMapRotate back to true (enable minimap rotation by default), but set MiniMapRotate to false for new installs --- indra/newview/app_settings/settings.xml | 5 ++++- indra/newview/llnetmap.cpp | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 74241823f4..f2943c5c03 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6797,7 +6797,10 @@ Type Boolean Value - 0 + + 1 MiniMapScale diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp index 5cae3ce8d6..fa901fbdfd 100755 --- a/indra/newview/llnetmap.cpp +++ b/indra/newview/llnetmap.cpp @@ -106,6 +106,13 @@ LLNetMap::LLNetMap (const Params & p) mPopupMenu(NULL) { mScale = gSavedSettings.getF32("MiniMapScale"); + if (gAgent.isFirstLogin()) + { + // *HACK: On first run, set this to false for new users, otherwise the + // default is true to maintain consistent experience for existing + // users. + gSavedSettings.setBOOL("MiniMapRotate", false); + } mPixelsPerMeter = mScale / REGION_WIDTH_METERS; mDotRadius = llmax(DOT_SCALE * mPixelsPerMeter, MIN_DOT_RADIUS); } -- cgit v1.2.3 From 7345cd16625b9fc5db03877aaf4efc1d7db22389 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 23 May 2022 20:26:25 +0300 Subject: SL-17339 Controls > Restore Defaults should clear the "Walk to" action. --- indra/newview/app_settings/key_bindings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/newview/app_settings/key_bindings.xml b/indra/newview/app_settings/key_bindings.xml index 55babc88bc..8d5349550f 100644 --- a/indra/newview/app_settings/key_bindings.xml +++ b/indra/newview/app_settings/key_bindings.xml @@ -85,7 +85,6 @@ - -- cgit v1.2.3 From 8ef25a63bd1e84e02fe2c08ce439aa26c0f3d5f1 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 23 May 2022 19:49:18 -0700 Subject: SL-15937 - adjust memory limit / cache code --- indra/llcommon/llmemory.cpp | 8 ++--- indra/newview/app_settings/settings.xml | 6 ++-- indra/newview/llvocache.cpp | 52 ++++++++++++++++----------------- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp index ea84e4c1ea..afd476096e 100644 --- a/indra/llcommon/llmemory.cpp +++ b/indra/llcommon/llmemory.cpp @@ -210,11 +210,9 @@ U64 LLMemory::getCurrentRSS() mach_msg_type_number_t basicInfoCount = MACH_TASK_BASIC_INFO_COUNT; if (task_info(mach_task_self(), MACH_TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS) { -// residentSize = basicInfo.resident_size; - // Although this method is defined to return the "resident set size," - // in fact what callers want from it is the total virtual memory - // consumed by the application. - residentSize = basicInfo.virtual_size; + residentSize = basicInfo.resident_size; + // 64-bit macos apps allocate 32 GB or more at startup, and this is reflected in virtual_size. + // basicInfo.virtual_size is not what we want. } else { diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c13329dc4a..463daeaa76 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -7077,13 +7077,13 @@ NonvisibleObjectsInMemoryTime Comment - Number of frames non-visible objects stay in memory before being removed. 0 means never to remove. + Number of frames non-visible objects stay in memory before being removed. 0 means max. Persist 1 Type U32 Value - 300 + 64 NoPreload @@ -11011,7 +11011,7 @@ Type U32 Value - 1024 + 2048 SceneLoadLowMemoryBound diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 5ebc65405f..1579eb304e 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -369,15 +369,6 @@ void LLVOCacheEntry::updateDebugSettings() } timer.reset(); - //the number of frames invisible objects stay in memory - static LLCachedControl inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime"); - sMinFrameRange = inv_obj_time - 1; //make 0 to be the maximum - - //min radius: all objects within this radius remain loaded in memory - static LLCachedControl min_radius(gSavedSettings,"SceneLoadMinRadius"); - sNearRadius = llmin((F32)min_radius, gAgentCamera.mDrawDistance); //can not exceed the draw distance - sNearRadius = llmax(sNearRadius, 1.f); //minimum value is 1.0m - //objects within the view frustum whose visible area is greater than this threshold will be loaded static LLCachedControl front_pixel_threshold(gSavedSettings,"SceneLoadFrontPixelThreshold"); sFrontPixelThreshold = front_pixel_threshold; @@ -387,29 +378,37 @@ void LLVOCacheEntry::updateDebugSettings() sRearPixelThreshold = rear_pixel_threshold; sRearPixelThreshold = llmax(sRearPixelThreshold, sFrontPixelThreshold); //can not be smaller than sFrontPixelThreshold. - // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold - static LLCachedControl rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); - sRearFarRadius = llmax(rear_max_radius_frac * gAgentCamera.mDrawDistance / 100.f, 1.0f); //minimum value is 1.0m - sRearFarRadius = llmax(sRearFarRadius, (F32)min_radius); //can not be less than "SceneLoadMinRadius". - sRearFarRadius = llmin(sRearFarRadius, gAgentCamera.mDrawDistance); //can not be more than the draw distance. - - //make the above parameters adaptive to memory usage + //make parameters adaptive to memory usage //starts to put restrictions from low_mem_bound_MB, apply tightest restrictions when hits high_mem_bound_MB static LLCachedControl low_mem_bound_MB(gSavedSettings,"SceneLoadLowMemoryBound"); static LLCachedControl high_mem_bound_MB(gSavedSettings,"SceneLoadHighMemoryBound"); LLMemory::updateMemoryInfo() ; U32 allocated_mem = LLMemory::getAllocatedMemKB().value(); - allocated_mem /= 1024; //convert to MB. - if(allocated_mem < low_mem_bound_MB) - { - return; - } - F32 adjust_factor = llmax(0.f, (F32)(high_mem_bound_MB - allocated_mem) / (high_mem_bound_MB - low_mem_bound_MB)); - - sRearFarRadius = llmin(adjust_factor * sRearFarRadius, 96.f); //[0.f, 96.f] - sMinFrameRange = (U32)llclamp(adjust_factor * sMinFrameRange, 10.f, 64.f); //[10, 64] - sNearRadius = llmax(adjust_factor * sNearRadius, 1.0f); + static const F32 KB_to_MB = 1.f / 1024.f; + U32 clamped_memory = llclamp(allocated_mem * KB_to_MB, (F32) low_mem_bound_MB, (F32) high_mem_bound_MB); + const F32 adjust_range = high_mem_bound_MB - low_mem_bound_MB; + const F32 adjust_factor = (high_mem_bound_MB - clamped_memory) / adjust_range; // [0, 1] + + //min radius: all objects within this radius remain loaded in memory + static LLCachedControl min_radius(gSavedSettings,"SceneLoadMinRadius"); + static const F32 MIN_RADIUS = 1.0f; + const F32 draw_radius = gAgentCamera.mDrawDistance; + const F32 clamped_min_radius = llclamp((F32) min_radius, MIN_RADIUS, draw_radius); // [1, mDrawDistance] + sNearRadius = MIN_RADIUS + ((clamped_min_radius - MIN_RADIUS) * adjust_factor); + + // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold + static LLCachedControl rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); + const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance; + const F32 clamped_max_radius = llclamp(max_radius, sNearRadius, draw_radius); // [sNearRadius, mDrawDistance] + sRearFarRadius = sNearRadius + ((clamped_max_radius - sNearRadius) * adjust_factor); + + //the number of frames invisible objects stay in memory + static LLCachedControl inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime"); + static const U32 MIN_FRAMES = 10; + static const U32 MAX_FRAMES = 64; + const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64 + sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor); } //static @@ -504,6 +503,7 @@ void LLVOCacheEntry::calcSceneContribution(const LLVector4a& camera_origin, bool { mSceneContrib = 0.f; //out of draw distance, not to load } + } setVisible(); -- cgit v1.2.3 From 10f56db475316433586fee273cd442b143a31c08 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 24 May 2022 07:04:54 -0700 Subject: SL-15937 - far must be greater than near near, not equal --- indra/newview/llvocache.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 1579eb304e..89dab23399 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -399,9 +399,10 @@ void LLVOCacheEntry::updateDebugSettings() // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold static LLCachedControl rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); + const F32 min_radius_plus_one = sNearRadius; const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance; - const F32 clamped_max_radius = llclamp(max_radius, sNearRadius, draw_radius); // [sNearRadius, mDrawDistance] - sRearFarRadius = sNearRadius + ((clamped_max_radius - sNearRadius) * adjust_factor); + const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance] + sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor); //the number of frames invisible objects stay in memory static LLCachedControl inv_obj_time(gSavedSettings,"NonvisibleObjectsInMemoryTime"); @@ -503,7 +504,6 @@ void LLVOCacheEntry::calcSceneContribution(const LLVector4a& camera_origin, bool { mSceneContrib = 0.f; //out of draw distance, not to load } - } setVisible(); -- cgit v1.2.3 From f55c1ff40562a6f46a5508c7308d335a9aadb68f Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 24 May 2022 09:33:06 -0700 Subject: SL-15937 - forget the +1 --- indra/newview/llvocache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 89dab23399..3e5f1bdc7f 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -399,7 +399,7 @@ void LLVOCacheEntry::updateDebugSettings() // a percentage of draw distance beyond which all objects outside of view frustum will be unloaded, regardless of pixel threshold static LLCachedControl rear_max_radius_frac(gSavedSettings,"SceneLoadRearMaxRadiusFraction"); - const F32 min_radius_plus_one = sNearRadius; + const F32 min_radius_plus_one = sNearRadius + 1.f; const F32 max_radius = rear_max_radius_frac * gAgentCamera.mDrawDistance; const F32 clamped_max_radius = llclamp(max_radius, min_radius_plus_one, draw_radius); // [sNearRadius, mDrawDistance] sRearFarRadius = min_radius_plus_one + ((clamped_max_radius - min_radius_plus_one) * adjust_factor); -- cgit v1.2.3 From bc495fe39aa682c4142840bee323792f836a9d6c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 25 May 2022 00:31:01 +0300 Subject: SL-17458 Cut works the same way as Copy when pasting into Favorites --- indra/newview/llinventorybridge.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 342920630b..1294bb4d92 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -3798,7 +3798,20 @@ void LLFolderBridge::perform_pasteFromClipboard() { if (item && can_move_to_landmarks(item)) { - dropToFavorites(item); + if (LLClipboard::instance().isCutMode()) + { + LLViewerInventoryItem* viitem = dynamic_cast(item); + llassert(viitem); + if (viitem) + { + //changeItemParent() implicity calls dirtyFilter + changeItemParent(model, viitem, parent_id, FALSE); + } + } + else + { + dropToFavorites(item); + } } } else if (LLClipboard::instance().isCutMode()) -- cgit v1.2.3 From ef7254a68ab09abc15cc3f51406a1cebf652f205 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 25 May 2022 16:15:14 +0300 Subject: SL-17206 Unable to move an avatar after a strong fall on the ground --- indra/llcharacter/llkeyframemotion.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index 1eee736b48..13030df483 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1348,9 +1348,10 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //SL-17206 hack to alter Female_land loop setting, while current behavior won't be changed serverside LLUUID const female_land_anim("ca1baf4d-0a18-5a1f-0330-e4bd1e71f09e"); - if (female_land_anim == asset_id) + LLUUID const formal_female_land_anim("6a9a173b-61fa-3ad5-01fa-a851cfc5f66a"); + if (female_land_anim == asset_id || formal_female_land_anim == asset_id) { - LL_WARNS() << "Animation(" << female_land_anim << ") won't be looped." << LL_ENDL; + LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; mJointMotionList->mLoop = FALSE; } -- cgit v1.2.3 From e6245adce883d62f18a2d8b8af5061d3183d9be9 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 25 May 2022 19:18:51 +0300 Subject: SL-17462 soften colors of the prims on mini-map --- indra/newview/skins/default/colors.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index ad2bc075c6..eb25fd14a6 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -607,10 +607,10 @@ value="0 0 0 1" /> + value="0.85 0 0.85 1" /> + value="0.63 0 0.63 1" /> @@ -619,10 +619,10 @@ value="0.12 0.12 0.12 1" /> + value="0 0.85 0.85 1" /> + value="0 0.63 0.63 1" /> -- cgit v1.2.3 From 4cfa59d3f1b856f62ab18543b1dbefbc574fb218 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 26 May 2022 21:25:23 +0300 Subject: SL-17473 Viewer not clearing all Vertex Buffers in some cases Image thread doesn't need mBuffer and buffer isn't thread safe so no point allocating it in an image thread. --- indra/llrender/llimagegl.cpp | 2 +- indra/llrender/llrender.cpp | 77 +++++++++++++++++++++++++-------------- indra/llrender/llrender.h | 4 +- indra/llrender/llvertexbuffer.cpp | 2 +- indra/llrender/llvertexbuffer.h | 1 - indra/newview/llviewerwindow.cpp | 2 +- indra/newview/llvoavatar.cpp | 3 +- indra/newview/pipeline.cpp | 8 +++- 8 files changed, 64 insertions(+), 35 deletions(-) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 9bd3a0a6b0..46f0095c92 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -2432,7 +2432,7 @@ void LLImageGLThread::run() // We must perform setup on this thread before actually servicing our // WorkQueue, likewise cleanup afterwards. mWindow->makeContextCurrent(mContext); - gGL.init(); + gGL.init(false); ThreadPool::run(); gGL.shutdown(); mWindow->destroySharedContext(mContext); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index a03a27cf94..72cca1f2a2 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -869,7 +869,7 @@ LLRender::~LLRender() shutdown(); } -void LLRender::init() +void LLRender::init(bool needs_vertex_buffer) { #if LL_WINDOWS if (gGLManager.mHasDebugOutput && gDebugGL) @@ -897,15 +897,27 @@ void LLRender::init() #endif } + if (needs_vertex_buffer) + { + initVertexBuffer(); + } +} - llassert_always(mBuffer.isNull()) ; - stop_glerror(); - mBuffer = new LLVertexBuffer(immediate_mask, 0); - mBuffer->allocateBuffer(4096, 0, TRUE); - mBuffer->getVertexStrider(mVerticesp); - mBuffer->getTexCoord0Strider(mTexcoordsp); - mBuffer->getColorStrider(mColorsp); - stop_glerror(); +void LLRender::initVertexBuffer() +{ + llassert_always(mBuffer.isNull()); + stop_glerror(); + mBuffer = new LLVertexBuffer(immediate_mask, 0); + mBuffer->allocateBuffer(4096, 0, TRUE); + mBuffer->getVertexStrider(mVerticesp); + mBuffer->getTexCoord0Strider(mTexcoordsp); + mBuffer->getColorStrider(mColorsp); + stop_glerror(); +} + +void LLRender::resetVertexBuffer() +{ + mBuffer = NULL; } void LLRender::shutdown() @@ -923,7 +935,7 @@ void LLRender::shutdown() delete mLightState[i]; } mLightState.clear(); - mBuffer = NULL ; + resetVertexBuffer(); } void LLRender::refreshState(void) @@ -1625,25 +1637,34 @@ void LLRender::flush() mCount = 0; - if (mBuffer->useVBOs() && !mBuffer->isLocked()) - { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata) - mBuffer->getVertexStrider(mVerticesp, 0, count); - mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count); - mBuffer->getColorStrider(mColorsp, 0, count); - } - - mBuffer->flush(); - mBuffer->setBuffer(immediate_mask); + if (mBuffer) + { + if (mBuffer->useVBOs() && !mBuffer->isLocked()) + { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata) + mBuffer->getVertexStrider(mVerticesp, 0, count); + mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count); + mBuffer->getColorStrider(mColorsp, 0, count); + } + + mBuffer->flush(); + mBuffer->setBuffer(immediate_mask); + + if (mMode == LLRender::QUADS && sGLCoreProfile) + { + mBuffer->drawArrays(LLRender::TRIANGLES, 0, count); + mQuadCycle = 1; + } + else + { + mBuffer->drawArrays(mMode, 0, count); + } + } + else + { + // mBuffer is present in main thread and not present in an image thread + LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL; + } - if (mMode == LLRender::QUADS && sGLCoreProfile) - { - mBuffer->drawArrays(LLRender::TRIANGLES, 0, count); - mQuadCycle = 1; - } - else - { - mBuffer->drawArrays(mMode, 0, count); - } mVerticesp[0] = mVerticesp[count]; mTexcoordsp[0] = mTexcoordsp[count]; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index e2489876e4..9c36c230fb 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -354,7 +354,9 @@ public: LLRender(); ~LLRender(); - void init() ; + void init(bool needs_vertex_buffer); + void initVertexBuffer(); + void resetVertexBuffer(); void shutdown(); // Refreshes renderer state to the cached values diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 6338cab96a..be3e6ddff0 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1055,7 +1055,7 @@ void LLVertexBuffer::releaseIndices() bool LLVertexBuffer::createGLBuffer(U32 size) { - if (mGLBuffer) + if (mGLBuffer || mMappedData) { destroyGLBuffer(); } diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index baf8407fc6..3b3fe44984 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -265,7 +265,6 @@ public: bool getTangentStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTangentStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getColorStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getTextureIndexStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getEmissiveStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getWeightStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getWeight4Strider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8e565bbdca..33e8178593 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1998,7 +1998,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) } LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; - gGL.init() ; + gGL.init(true); if (LLFeatureManager::getInstance()->isSafe() || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 37851ce99b..5dfcb68562 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2810,6 +2810,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (detailed_update) { U32 draw_order = 0; + S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment(); for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter) @@ -2849,7 +2850,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) } // if selecting any attachments, update all of them as non-damped - if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment()) + if (attachment_selected) { gPipeline.updateMoveNormalAsync(attached_object->mDrawable); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index da16c8209f..db5c446e7a 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7238,6 +7238,7 @@ void LLPipeline::doResetVertexBuffers(bool forced) mResetVertexBuffers = false; mCubeVB = NULL; + mDeferredVB = NULL; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -7271,10 +7272,11 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLPathingLib::getInstance()->cleanupVBOManager(); } LLVOPartGroup::destroyGL(); + gGL.resetVertexBuffer(); SUBSYSTEM_CLEANUP(LLVertexBuffer); - if (LLVertexBuffer::sGLCount > 0) + if (LLVertexBuffer::sGLCount != 0) { LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL; } @@ -7295,6 +7297,10 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping); + gGL.initVertexBuffer(); + + mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); + mDeferredVB->allocateBuffer(8, 0, true); LLVOPartGroup::restoreGL(); } -- cgit v1.2.3 From ce0286c33b6d0f6f37d90702c4800362e5c0e7d7 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 27 May 2022 20:51:34 +0300 Subject: SL-17474 Device context not properly released at shutdown --- indra/llwindow/llwindowwin32.cpp | 49 ++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 1f3823509c..8635261103 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -874,21 +874,20 @@ void LLWindowWin32::close() // Restore gamma to the system values. restoreGamma(); - if (mhDC) - { - if (!ReleaseDC(mWindowHandle, mhDC)) - { - LL_WARNS("Window") << "Release of ghDC failed" << LL_ENDL; - } - mhDC = NULL; - } - LL_DEBUGS("Window") << "Destroying Window" << LL_ENDL; mWindowThread->post([=]() { if (IsWindow(mWindowHandle)) { + if (mhDC) + { + if (!ReleaseDC(mWindowHandle, mhDC)) + { + LL_WARNS("Window") << "Release of ghDC failed!" << LL_ENDL; + } + } + // Make sure we don't leave a blank toolbar button. ShowWindow(mWindowHandle, SW_HIDE); @@ -914,6 +913,7 @@ void LLWindowWin32::close() // Even though the above lambda might not yet have run, we've already // bound mWindowHandle into it by value, which should suffice for the // operations we're asking. That's the last time WE should touch it. + mhDC = NULL; mWindowHandle = NULL; mWindowThread->close(); } @@ -1506,12 +1506,10 @@ const S32 max_format = (S32)num_formats - 1; { wglDeleteContext (mhRC); // Release The Rendering Context mhRC = 0; // Zero The Rendering Context - } - ReleaseDC (mWindowHandle, mhDC); // Release The Device Context - mhDC = 0; // Zero The Device Context } + // will release and recreate mhDC, mWindowHandle recreateWindow(window_rect, dw_ex_style, dw_style); RECT rect; @@ -1661,7 +1659,8 @@ const S32 max_format = (S32)num_formats - 1; void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw_style) { - auto oldHandle = mWindowHandle; + auto oldWindowHandle = mWindowHandle; + auto oldDCHandle = mhDC; // zero out mWindowHandle and mhDC before destroying window so window // thread falls back to peekmessage @@ -1673,7 +1672,8 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw auto window_work = [this, self=mWindowThread, - oldHandle, + oldWindowHandle, + oldDCHandle, // bind CreateWindowEx() parameters by value instead of // back-referencing LLWindowWin32 members windowClassName=mWindowClassName, @@ -1689,11 +1689,20 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw self->mWindowHandle = 0; self->mhDC = 0; - // important to call DestroyWindow() from the window thread - if (oldHandle && !destroy_window_handler(oldHandle)) + if (oldWindowHandle) { - LL_WARNS("Window") << "Failed to properly close window before recreating it!" - << LL_ENDL; + if (oldDCHandle && !ReleaseDC(oldWindowHandle, oldDCHandle)) + { + LL_WARNS("Window") << "Failed to ReleaseDC" << LL_ENDL; + } + + // important to call DestroyWindow() from the window thread + if (!destroy_window_handler(oldWindowHandle)) + { + + LL_WARNS("Window") << "Failed to properly close window before recreating it!" + << LL_ENDL; + } } auto handle = CreateWindowEx(dw_ex_style, @@ -1731,7 +1740,7 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw }; // But how we pass window_work to the window thread depends on whether we // already have a window handle. - if (! oldHandle) + if (!oldWindowHandle) { // Pass window_work using the WorkQueue: without an existing window // handle, the window thread can't call GetMessage(). @@ -1744,7 +1753,7 @@ void LLWindowWin32::recreateWindow(RECT window_rect, DWORD dw_ex_style, DWORD dw // PostMessage(oldHandle) because oldHandle won't be destroyed until // the window thread has retrieved and executed window_work. LL_DEBUGS("Window") << "posting window_work to message queue" << LL_ENDL; - mWindowThread->Post(oldHandle, window_work); + mWindowThread->Post(oldWindowHandle, window_work); } auto future = promise.get_future(); -- cgit v1.2.3 From 0fe8493b5a531bb0fbc431f54ee25f8e2923b5bf Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 1 Jun 2022 17:42:25 +0300 Subject: SL-17509 The viewer spams warnings if the user is in a parcel or region with voice disabled --- indra/newview/llvoicevivox.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 19036a3f77..54f79a3a2e 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1606,8 +1606,21 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo() } else { - LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL; - + LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel(); + if (channel != NULL) + { + if (channel->getSessionName().empty() && channel->getSessionID().isNull()) + { + if (LLViewerParcelMgr::getInstance()->allowAgentVoice()) + { + LL_WARNS("Voice") << "No channel credentials for default channel" << LL_ENDL; + } + } + else + { + LL_WARNS("Voice") << "No voice channel credentials" << LL_ENDL; + } + } } } else -- cgit v1.2.3 From 616f2b639bc6907e810664522304305337646292 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 6 Jun 2022 19:57:03 -0500 Subject: SL-17532 Potential fix for some rigged mesh draw order issues. --- .../shaders/class1/deferred/materialF.glsl | 13 ++--- indra/newview/lldrawable.h | 1 + indra/newview/lldrawpoolalpha.cpp | 43 +++++++++++++--- indra/newview/llspatialpartition.cpp | 59 ++++++++++++++++++++++ indra/newview/llspatialpartition.h | 2 +- indra/newview/llviewershadermgr.cpp | 12 +++++ indra/newview/llvovolume.cpp | 51 ++++++++++++++++--- 7 files changed, 161 insertions(+), 20 deletions(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index 02d83925ea..b26194f278 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -202,7 +202,7 @@ VARYING vec2 vary_texcoord2; uniform float env_intensity; uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) +#ifdef HAS_ALPHA_MASK uniform float minimum_alpha; #endif @@ -227,11 +227,12 @@ void main() vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); diffcol.rgb *= vertex_color.rgb; -#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) - - // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points - float bias = 0.001953125; // 1/512, or half an 8-bit quantization - if (diffcol.a < minimum_alpha-bias) +#ifdef HAS_ALPHA_MASK +#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND + if (diffcol.a*vertex_color.a < minimum_alpha) +#else + if (diffcol.a < minimum_alpha) +#endif { discard; } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index 2372ea01a6..2a0f4c93ac 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -133,6 +133,7 @@ public: inline LLFace* getFace(const S32 i) const; inline S32 getNumFaces() const; face_list_t& getFaces() { return mFaces; } + const face_list_t& getFaces() const { return mFaces; } //void removeFace(const S32 i); // SJB: Avoid using this, it's slow LLFace* addFace(LLFacePool *poolp, LLViewerTexture *texturep); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index e674707c01..70ffd85608 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -50,6 +50,8 @@ #include "llglcommonfunc.h" #include "llvoavatar.h" +#pragma optimize("", off) + BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; #define current_shader (LLGLSLShader::sCurBoundShaderPtr) @@ -58,8 +60,11 @@ static BOOL deferred_render = FALSE; // minimum alpha before discarding a fragment static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255 +static const F32 MINIMUM_RIGGED_ALPHA = MINIMUM_ALPHA; + // minimum alpha before discarding a fragment when rendering impostors static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f; +static const F32 MINIMUM_IMPOSTOR_RIGGED_ALPHA = 0.1f; LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : LLRenderPass(type), target_shader(NULL), @@ -111,11 +116,25 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d if (LLPipeline::sImpostorRender) { - shader->setMinimumAlpha(MINIMUM_IMPOSTOR_ALPHA); + if (shader->mRiggedVariant == shader) + { + shader->setMinimumAlpha(MINIMUM_IMPOSTOR_RIGGED_ALPHA); + } + else + { + shader->setMinimumAlpha(MINIMUM_IMPOSTOR_ALPHA); + } } else { - shader->setMinimumAlpha(MINIMUM_ALPHA); + if (shader->mRiggedVariant == shader) + { + shader->setMinimumAlpha(MINIMUM_RIGGED_ALPHA); + } + else + { + shader->setMinimumAlpha(MINIMUM_ALPHA); + } } if (textureGamma) { @@ -147,6 +166,10 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram; prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms) + for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i) + { + prepare_alpha_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], false, false); // note: bindDeferredShader will get called during render loop for materials + } // first pass, render rigged objects only and render to depth buffer forwardRender(true); @@ -184,7 +207,7 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) } //set some generic parameters for forward (non-deferred) rendering -static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha) +static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha, F32 minimum_rigged_alpha) { shader->bind(); shader->setMinimumAlpha(minimum_alpha); @@ -193,7 +216,7 @@ static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha) //also prepare rigged variant if (shader->mRiggedVariant && shader->mRiggedVariant != shader) { - prepare_forward_shader(shader->mRiggedVariant, minimum_alpha); + prepare_forward_shader(shader->mRiggedVariant, minimum_rigged_alpha, minimum_rigged_alpha); } } @@ -211,12 +234,20 @@ void LLDrawPoolAlpha::render(S32 pass) (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; F32 minimum_alpha = MINIMUM_ALPHA; + F32 minimum_rigged_alpha = MINIMUM_RIGGED_ALPHA; if (LLPipeline::sImpostorRender) { minimum_alpha = MINIMUM_IMPOSTOR_ALPHA; + minimum_rigged_alpha = MINIMUM_IMPOSTOR_RIGGED_ALPHA; + } + + prepare_forward_shader(fullbright_shader, minimum_alpha, minimum_rigged_alpha); + prepare_forward_shader(simple_shader, minimum_alpha, minimum_rigged_alpha); + + for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i) + { + prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha, minimum_rigged_alpha); } - prepare_forward_shader(fullbright_shader, minimum_alpha); - prepare_forward_shader(simple_shader, minimum_alpha); //first pass -- rigged only and drawn to depth buffer forwardRender(true); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 0d53950889..c16a1854be 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1567,6 +1567,62 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) } } +// return false if drawable is rigged and: +// - a linked rigged drawable has a different spatial group +// - a linked rigged drawable face has the wrong draw order index +bool check_rigged_group(LLDrawable* drawable) +{ + if (drawable->isState(LLDrawable::RIGGED)) + { + LLSpatialGroup* group = drawable->getSpatialGroup(); + LLDrawable* root = drawable->getRoot(); + + if (root->isState(LLDrawable::RIGGED) && root->getSpatialGroup() != group) + { + llassert(false); + return false; + } + + S32 last_draw_index = -1; + if (root->isState(LLDrawable::RIGGED)) + { + for (auto& face : root->getFaces()) + { + if ((S32) face->getDrawOrderIndex() <= last_draw_index) + { + llassert(false); + return false; + } + last_draw_index = face->getDrawOrderIndex(); + } + } + + for (auto& child : root->getVObj()->getChildren()) + { + if (child->mDrawable->isState(LLDrawable::RIGGED)) + { + for (auto& face : child->mDrawable->getFaces()) + { + if ((S32) face->getDrawOrderIndex() <= last_draw_index) + { + llassert(false); + return false; + } + last_draw_index = face->getDrawOrderIndex(); + } + } + + if (child->mDrawable->getSpatialGroup() != group) + { + llassert(false); + return false; + } + } + } + + return true; +} + void renderOctree(LLSpatialGroup* group) { //render solid object bounding box, color @@ -1611,6 +1667,9 @@ void renderOctree(LLSpatialGroup* group) { continue; } + + llassert(check_rigged_group(drawable)); + if (!group->getSpatialPartition()->isBridge()) { gGL.pushMatrix(); diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 6d3ef33801..f7bc9fb644 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -264,7 +264,7 @@ public: return lhs->mAvatarp < rhs->mAvatarp; } - return lhs->mRenderOrder > rhs->mRenderOrder; + return lhs->mRenderOrder < rhs->mRenderOrder; } }; diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 086b433c72..e926c5c3ba 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1484,6 +1484,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + if (alpha_mode != 0) + { + gDeferredMaterialProgram[i].mFeatures.hasAlphaMask = true; + gDeferredMaterialProgram[i].addPermutation("HAS_ALPHA_MASK", "1"); + } + if (use_sun_shadow) { gDeferredMaterialProgram[i].addPermutation("HAS_SUN_SHADOW", "1"); @@ -1542,6 +1548,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() } gDeferredMaterialWaterProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode)); + if (alpha_mode != 0) + { + gDeferredMaterialWaterProgram[i].mFeatures.hasAlphaMask = true; + gDeferredMaterialWaterProgram[i].addPermutation("HAS_ALPHA_MASK", "1"); + } + if (use_sun_shadow) { gDeferredMaterialWaterProgram[i].addPermutation("HAS_SUN_SHADOW", "1"); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 126a25115d..eb1e2cbd80 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5480,7 +5480,7 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[1] < MAX_FACE_COUNT) { - face->setDrawOrderIndex(count[1]); + //face->setDrawOrderIndex(count[1]); list[1][count[1]++] = face; } } @@ -5488,15 +5488,40 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[0] < MAX_FACE_COUNT) { - face->setDrawOrderIndex(count[0]); + //face->setDrawOrderIndex(count[0]); list[0][count[0]++] = face; } } } +// return index into linkset for given object (0 for root prim) +U32 get_linkset_index(LLVOVolume* vobj) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; + if (vobj->isRootEdit()) + { + return 0; + } + + LLViewerObject* root = vobj->getRootEdit(); + U32 idx = 1; + for (auto& child : root->getChildren()) + { + if (child == vobj) + { + return idx; + } + ++idx; + } + + llassert(false); + return idx; //should never get here +} + void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; + if (group->changeLOD()) { group->mLastUpdateDistance = group->mDistance; @@ -5655,6 +5680,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) avatar->addAttachmentOverridesForObject(vobj, NULL, false); } + U32 linkset_index = get_linkset_index(vobj); + // Standard rigged mesh attachments: bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); // Animated objects. Have to check for isRiggedMesh() to @@ -5674,6 +5701,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } + // order by linkset index first and face index second + facep->setDrawOrderIndex(linkset_index * 100 + i); + //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group facep->setVertexBuffer(NULL); @@ -5698,11 +5728,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (facep->isState(LLFace::RIGGED)) { //face is not rigged but used to be, remove from rigged face pool - LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*) facep->getPool(); - if (pool) - { - pool->removeFace(facep); - } facep->clearState(LLFace::RIGGED); facep->mAvatar = NULL; facep->mSkinInfo = NULL; @@ -6158,6 +6183,13 @@ struct CompareBatchBreakerRigged } }; +struct CompareDrawOrder +{ + bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) + { + return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex(); + } +}; U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged) { @@ -6202,6 +6234,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //sort faces by things that break batches, including avatar and mesh id std::sort(faces, faces + face_count, CompareBatchBreakerRigged()); } + else + { + // preserve legacy draw order for rigged faces + std::sort(faces, faces + face_count, CompareDrawOrder()); + } } else if (!distance_sort) { -- cgit v1.2.3 From 3e1db1f18405d50a63d772722175c859c1952f92 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 7 Jun 2022 10:36:59 -0500 Subject: SL-17532 Cleanup from hasty commit (thanks to Henri for the prodding). --- indra/newview/lldrawpoolalpha.cpp | 34 +++++++--------------------------- indra/newview/llvovolume.cpp | 2 +- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 70ffd85608..6c1abb24c9 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -50,8 +50,6 @@ #include "llglcommonfunc.h" #include "llvoavatar.h" -#pragma optimize("", off) - BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE; #define current_shader (LLGLSLShader::sCurBoundShaderPtr) @@ -60,11 +58,9 @@ static BOOL deferred_render = FALSE; // minimum alpha before discarding a fragment static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255 -static const F32 MINIMUM_RIGGED_ALPHA = MINIMUM_ALPHA; // minimum alpha before discarding a fragment when rendering impostors static const F32 MINIMUM_IMPOSTOR_ALPHA = 0.1f; -static const F32 MINIMUM_IMPOSTOR_RIGGED_ALPHA = 0.1f; LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) : LLRenderPass(type), target_shader(NULL), @@ -116,25 +112,11 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d if (LLPipeline::sImpostorRender) { - if (shader->mRiggedVariant == shader) - { - shader->setMinimumAlpha(MINIMUM_IMPOSTOR_RIGGED_ALPHA); - } - else - { - shader->setMinimumAlpha(MINIMUM_IMPOSTOR_ALPHA); - } + shader->setMinimumAlpha(MINIMUM_IMPOSTOR_ALPHA); } else { - if (shader->mRiggedVariant == shader) - { - shader->setMinimumAlpha(MINIMUM_RIGGED_ALPHA); - } - else - { - shader->setMinimumAlpha(MINIMUM_ALPHA); - } + shader->setMinimumAlpha(MINIMUM_ALPHA); } if (textureGamma) { @@ -207,7 +189,7 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass) } //set some generic parameters for forward (non-deferred) rendering -static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha, F32 minimum_rigged_alpha) +static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha) { shader->bind(); shader->setMinimumAlpha(minimum_alpha); @@ -216,7 +198,7 @@ static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha, F32 //also prepare rigged variant if (shader->mRiggedVariant && shader->mRiggedVariant != shader) { - prepare_forward_shader(shader->mRiggedVariant, minimum_rigged_alpha, minimum_rigged_alpha); + prepare_forward_shader(shader->mRiggedVariant, minimum_alpha); } } @@ -234,19 +216,17 @@ void LLDrawPoolAlpha::render(S32 pass) (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram; F32 minimum_alpha = MINIMUM_ALPHA; - F32 minimum_rigged_alpha = MINIMUM_RIGGED_ALPHA; if (LLPipeline::sImpostorRender) { minimum_alpha = MINIMUM_IMPOSTOR_ALPHA; - minimum_rigged_alpha = MINIMUM_IMPOSTOR_RIGGED_ALPHA; } - prepare_forward_shader(fullbright_shader, minimum_alpha, minimum_rigged_alpha); - prepare_forward_shader(simple_shader, minimum_alpha, minimum_rigged_alpha); + prepare_forward_shader(fullbright_shader, minimum_alpha); + prepare_forward_shader(simple_shader, minimum_alpha); for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i) { - prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha, minimum_rigged_alpha); + prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha); } //first pass -- rigged only and drawn to depth buffer diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index eb1e2cbd80..f47fb6287c 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5505,7 +5505,7 @@ U32 get_linkset_index(LLVOVolume* vobj) LLViewerObject* root = vobj->getRootEdit(); U32 idx = 1; - for (auto& child : root->getChildren()) + for (const auto& child : root->getChildren()) { if (child == vobj) { -- cgit v1.2.3 From ba9bff5b9bdd7904916c3ae844840c87376498c3 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 8 Jun 2022 01:21:42 +0300 Subject: SL-17541 Show the message that user is currently at maximum FPS --- indra/llwindow/llwindow.cpp | 3 ++- indra/llwindow/llwindow.h | 3 +++ indra/llwindow/llwindowwin32.cpp | 3 ++- indra/newview/llfloaterperformance.cpp | 20 +++++++++++++++++--- indra/newview/llfloaterperformance.h | 1 + .../skins/default/xui/en/floater_performance.xml | 8 +++++++- 6 files changed, 32 insertions(+), 6 deletions(-) diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp index f4678a70c5..c5725677b4 100644 --- a/indra/llwindow/llwindow.cpp +++ b/indra/llwindow/llwindow.cpp @@ -117,7 +117,8 @@ LLWindow::LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags) mSwapMethod(SWAP_METHOD_UNDEFINED), mHideCursorPermanent(FALSE), mFlags(flags), - mHighSurrogate(0) + mHighSurrogate(0), + mRefreshRate(0) { } diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h index 0edf39f6ef..4380bbdb73 100644 --- a/indra/llwindow/llwindow.h +++ b/indra/llwindow/llwindow.h @@ -196,6 +196,8 @@ public: // windows only DirectInput8 for joysticks virtual void* getDirectInput8() { return NULL; }; virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; }; + + virtual S32 getRefreshRate() { return mRefreshRate; } protected: LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags); virtual ~LLWindow(); @@ -229,6 +231,7 @@ protected: U16 mHighSurrogate; S32 mMinWindowWidth; S32 mMinWindowHeight; + S32 mRefreshRate; // Handle a UTF-16 encoding unit received from keyboard. // Converting the series of UTF-16 encoding units to UTF-32 data, diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 1f3823509c..932f8c32cf 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -583,7 +583,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks, { current_refresh = 60; } - + mRefreshRate = current_refresh; //----------------------------------------------------------------------- // Drop resolution and go fullscreen // use a display mode with our desired size and depth, with a refresh @@ -1061,6 +1061,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO { current_refresh = 60; } + mRefreshRate = current_refresh; gGLManager.shutdownGL(); //destroy gl context 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("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("fps_value")->setValue(current_fps); + + std::string fps_text = getString("fps_text"); + static LLCachedControl vsync_enabled(gSavedSettings, "RenderVSyncEnable", true); + if (vsync_enabled && (current_fps >= gViewerWindow->getWindow()->getRefreshRate())) + { + fps_text += getString("max_text"); + } + getChild("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"> + + -- cgit v1.2.3 From 76c8a7ff0b57e7856613960391be7c400384183b Mon Sep 17 00:00:00 2001 From: Mnikolenko ProductEngine Date: Wed, 8 Jun 2022 03:15:59 +0300 Subject: SL-17541 show the message on mac --- indra/llwindow/llwindowmacosx.cpp | 2 ++ indra/newview/llfloaterperformance.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index bc4f07941b..b3616e4ea8 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -660,6 +660,8 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits } } + mRefreshRate = CGDisplayModeGetRefreshRate(CGDisplayCopyDisplayMode(mDisplay)); + // Disable vertical sync for swap toggleVSync(enable_vsync); 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 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 f96659d7b0661455c8a29f9186f9c96484b6c193 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 8 Jun 2022 18:24:48 +0300 Subject: SL-17552 Clear dirty flag when clicking Save button --- indra/newview/llfloatereditextdaycycle.cpp | 1 + indra/newview/llfloaterfixedenvironment.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp index 24673d5a7c..297ad24359 100644 --- a/indra/newview/llfloatereditextdaycycle.cpp +++ b/indra/newview/llfloatereditextdaycycle.cpp @@ -665,6 +665,7 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data) if (ctrl_action == ACTION_SAVE) { doApplyUpdateInventory(dayclone); + clearDirtyFlag(); } else if (ctrl_action == ACTION_SAVEAS) { diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp index fec218ca3b..aa9a2c164a 100644 --- a/indra/newview/llfloaterfixedenvironment.cpp +++ b/indra/newview/llfloaterfixedenvironment.cpp @@ -296,6 +296,7 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data) if (ctrl_action == ACTION_SAVE) { doApplyUpdateInventory(setting_clone); + clearDirtyFlag(); } else if (ctrl_action == ACTION_SAVEAS) { -- cgit v1.2.3 From 14ea73033ab64321d4034714ece6ad999093a9a8 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 31 May 2022 12:49:53 -0700 Subject: SL-17483: Make ThreadPool inherit LLInstanceTracker (cherry picked from commit 41d6a0e222241606c317281e2f0b211e16813dd5) --- indra/llcommon/threadpool.cpp | 1 + indra/llcommon/threadpool.h | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/indra/llcommon/threadpool.cpp b/indra/llcommon/threadpool.cpp index ba914035e2..d5adf11264 100644 --- a/indra/llcommon/threadpool.cpp +++ b/indra/llcommon/threadpool.cpp @@ -22,6 +22,7 @@ #include "stringize.h" LL::ThreadPool::ThreadPool(const std::string& name, size_t threads, size_t capacity): + super(name), mQueue(name, capacity), mName("ThreadPool:" + name), mThreadCount(threads) diff --git a/indra/llcommon/threadpool.h b/indra/llcommon/threadpool.h index b79c9b9090..f8eec3b457 100644 --- a/indra/llcommon/threadpool.h +++ b/indra/llcommon/threadpool.h @@ -22,8 +22,10 @@ namespace LL { - class ThreadPool + class ThreadPool: public LLInstanceTracker { + private: + using super = LLInstanceTracker; public: /** * Pass ThreadPool a string name. This can be used to look up the -- cgit v1.2.3 From 3e60b53d52d09e3f1412a9476743a77e555104d9 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 6 May 2022 14:46:49 -0700 Subject: SL-16182: Offload audio decoding from the main thread to the general work queue. The work queue callback binds "this". This is deemed safe due to current dependencies, but see the associated comment in the return callback. There was some trial and error to get a this-binded lambda to compile. Due to LLVorbisDecodeState writing to disk off-thread, limit audio decodes proportional to general worker thread count. Guess the thread count for now. --- indra/llaudio/llaudiodecodemgr.cpp | 333 ++++++++++++++++++----------- indra/llaudio/llaudiodecodemgr.h | 15 +- indra/llaudio/llaudioengine.cpp | 105 ++++----- indra/llaudio/llaudioengine.h | 69 +++--- indra/llaudio/llaudioengine_fmodstudio.cpp | 14 +- indra/llaudio/llaudioengine_fmodstudio.h | 2 +- indra/llaudio/llaudioengine_openal.cpp | 4 +- indra/llcommon/workqueue.h | 8 +- indra/newview/llappviewer.cpp | 3 +- indra/newview/llstartup.cpp | 2 +- indra/newview/llvieweraudio.h | 2 - 11 files changed, 320 insertions(+), 237 deletions(-) mode change 100644 => 100755 indra/llaudio/llaudiodecodemgr.cpp mode change 100644 => 100755 indra/llaudio/llaudioengine.h diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp old mode 100644 new mode 100755 index ff0aa6e76e..cc5abee08a --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -35,6 +35,7 @@ #include "llendianswizzle.h" #include "llassetstorage.h" #include "llrefcount.h" +#include "workqueue.h" #include "llvorbisencode.h" @@ -45,15 +46,13 @@ extern LLAudioEngine *gAudiop; -LLAudioDecodeMgr *gAudioDecodeMgrp = NULL; - static const S32 WAV_HEADER_SIZE = 44; ////////////////////////////////////////////////////////////////////////////// -class LLVorbisDecodeState : public LLRefCount +class LLVorbisDecodeState : public LLThreadSafeRefCount { public: class WriteResponder : public LLLFSThread::Responder @@ -532,146 +531,242 @@ void LLVorbisDecodeState::flushBadFile() class LLAudioDecodeMgr::Impl { - friend class LLAudioDecodeMgr; -public: - Impl() {}; - ~Impl() {}; + friend class LLAudioDecodeMgr; + LLAudioDecodeMgr::Impl(); + public: - void processQueue(const F32 num_secs = 0.005); + void processQueue(); -protected: - std::deque mDecodeQueue; - LLPointer mCurrentDecodep; + void startMoreDecodes(); + void enqueueFinishAudio(const LLUUID &decode_id, LLPointer& decode_state); + void checkDecodesFinished(); + + protected: + std::deque mDecodeQueue; + std::map> mDecodes; }; +LLAudioDecodeMgr::Impl::Impl() +{ +} + +// Returns the in-progress decode_state, which may be an empty LLPointer if +// there was an error and there is no more work to be done. +LLPointer beginDecodingAndWritingAudio(const LLUUID &decode_id); -void LLAudioDecodeMgr::Impl::processQueue(const F32 num_secs) +// Return true if finished +bool tryFinishAudio(const LLUUID &decode_id, LLPointer decode_state); + +void LLAudioDecodeMgr::Impl::processQueue() { - LLUUID uuid; + // First, check if any audio from in-progress decodes are ready to play. If + // so, mark them ready for playback (or errored, in case of error). + checkDecodesFinished(); - LLTimer decode_timer; + // Second, start as many decodes from the queue as permitted + startMoreDecodes(); +} - BOOL done = FALSE; - while (!done) - { - if (mCurrentDecodep) - { - BOOL res; +void LLAudioDecodeMgr::Impl::startMoreDecodes() +{ + llassert_always(gAudiop); + + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + // *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak + // pointer + LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); + llassert_always(main_queue); + llassert_always(general_queue); + // Set max decodes to double the thread count of the general work queue. + // This ensures the general work queue is full, but prevents theoretical + // buildup of buffers in memory due to disk writes once the + // LLVorbisDecodeState leaves the worker thread (see + // LLLFSThread::sLocal->write). This is probably as fast as we can get it + // without modifying/removing LLVorbisDecodeState, at which point we should + // consider decoding the audio during the asset download process. + // -Cosmic,2022-05-11 + const size_t MAX_DECODES = 4 * 2; + + while (!mDecodeQueue.empty() && mDecodes.size() < MAX_DECODES) + { + const LLUUID decode_id = mDecodeQueue.front(); + mDecodeQueue.pop_front(); + + // Don't decode the same file twice + if (mDecodes.find(decode_id) != mDecodes.end()) + { + continue; + } + if (gAudiop->hasDecodedFile(decode_id)) + { + continue; + } + + // Kick off a decode + mDecodes[decode_id] = LLPointer(NULL); + main_queue->postTo( + general_queue, + [decode_id, this]() // Work done on general queue + { + LLPointer decode_state = beginDecodingAndWritingAudio(decode_id); + + if (!decode_state) + { + // Audio decode has errored + return decode_state; + } + + // Disk write of decoded audio is now in progress off-thread + return decode_state; + }, + [decode_id, this](LLPointer decode_state) // Callback to main thread + mutable { + if (!gAudiop) + { + // There is no LLAudioEngine anymore. This might happen if + // an audio decode is enqueued just before shutdown. + return; + } + + // At this point, we can be certain that the pointer to "this" + // is valid because the lifetime of "this" is dependent upon + // the lifetime of gAudiop. + + enqueueFinishAudio(decode_id, decode_state); + }); + } +} - // Decode in a loop until we're done or have run out of time. - while(!(res = mCurrentDecodep->decodeSection()) && (decode_timer.getElapsedTimeF32() < num_secs)) - { - // decodeSection does all of the work above - } +LLPointer beginDecodingAndWritingAudio(const LLUUID &decode_id) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; + + LL_DEBUGS() << "Decoding " << decode_id << " from audio queue!" << LL_ENDL; + + std::string d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, decode_id.asString()) + ".dsf"; + LLPointer decode_state = new LLVorbisDecodeState(decode_id, d_path); + + if (!decode_state->initDecode()) + { + return NULL; + } + + // Decode in a loop until we're done + while (!decode_state->decodeSection()) + { + // decodeSection does all of the work above + } + + if (!decode_state->isDone()) + { + // Decode stopped early, or something bad happened to the file + // during decoding. + LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data or decode has been canceled, aborting decode" << LL_ENDL; + decode_state->flushBadFile(); + return NULL; + } + + if (!decode_state->isValid()) + { + // We had an error when decoding, abort. + LL_WARNS("AudioEngine") << decode_id << " has invalid vorbis data, aborting decode" << LL_ENDL; + decode_state->flushBadFile(); + return NULL; + } + + // Kick off the writing of the decoded audio to the disk cache. + // The receiving thread can then cheaply call finishDecode() again to check + // if writing has finished. Someone has to hold on to the refcounted + // decode_state to prevent it from getting destroyed during write. + decode_state->finishDecode(); + + return decode_state; +} - if (mCurrentDecodep->isDone() && !mCurrentDecodep->isValid()) - { - // We had an error when decoding, abort. - LL_WARNS("AudioEngine") << mCurrentDecodep->getUUID() << " has invalid vorbis data, aborting decode" << LL_ENDL; - mCurrentDecodep->flushBadFile(); - - if (gAudiop) - { - LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); - adp->setHasValidData(false); - adp->setHasCompletedDecode(true); - } - - mCurrentDecodep = NULL; - done = TRUE; - } +void LLAudioDecodeMgr::Impl::enqueueFinishAudio(const LLUUID &decode_id, LLPointer& decode_state) +{ + // Assumed fast + if (tryFinishAudio(decode_id, decode_state)) + { + // Done early! + auto decode_iter = mDecodes.find(decode_id); + llassert(decode_iter != mDecodes.end()); + mDecodes.erase(decode_iter); + return; + } + + // Not done yet... enqueue it + mDecodes[decode_id] = decode_state; +} - if (!res) - { - // We've used up out time slice, bail... - done = TRUE; - } - else if (mCurrentDecodep) - { - if (gAudiop && mCurrentDecodep->finishDecode()) - { - // We finished! - LLAudioData *adp = gAudiop->getAudioData(mCurrentDecodep->getUUID()); - if (!adp) - { - LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << mCurrentDecodep->getUUID() << LL_ENDL; - } - else if (mCurrentDecodep->isValid() && mCurrentDecodep->isDone()) - { - adp->setHasCompletedDecode(true); - adp->setHasDecodedData(true); - adp->setHasValidData(true); - - // At this point, we could see if anyone needs this sound immediately, but - // I'm not sure that there's a reason to - we need to poll all of the playing - // sounds anyway. - //LL_INFOS("AudioEngine") << "Finished the vorbis decode, now what?" << LL_ENDL; - } - else - { - adp->setHasCompletedDecode(true); - LL_INFOS("AudioEngine") << "Vorbis decode failed for " << mCurrentDecodep->getUUID() << LL_ENDL; - } - mCurrentDecodep = NULL; - } - done = TRUE; // done for now - } - } +void LLAudioDecodeMgr::Impl::checkDecodesFinished() +{ + auto decode_iter = mDecodes.begin(); + while (decode_iter != mDecodes.end()) + { + const LLUUID& decode_id = decode_iter->first; + const LLPointer& decode_state = decode_iter->second; + if (tryFinishAudio(decode_id, decode_state)) + { + decode_iter = mDecodes.erase(decode_iter); + } + else + { + ++decode_iter; + } + } +} - if (!done) - { - if (mDecodeQueue.empty()) - { - // Nothing else on the queue. - done = TRUE; - } - else - { - LLUUID uuid; - uuid = mDecodeQueue.front(); - mDecodeQueue.pop_front(); - if (!gAudiop || gAudiop->hasDecodedFile(uuid)) - { - // This file has already been decoded, don't decode it again. - continue; - } - - LL_DEBUGS() << "Decoding " << uuid << " from audio queue!" << LL_ENDL; - - std::string uuid_str; - std::string d_path; - - LLTimer timer; - timer.reset(); - - uuid.toString(uuid_str); - d_path = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf"; - - mCurrentDecodep = new LLVorbisDecodeState(uuid, d_path); - if (!mCurrentDecodep->initDecode()) - { - mCurrentDecodep = NULL; - } - } - } - } +bool tryFinishAudio(const LLUUID &decode_id, LLPointer decode_state) +{ + // decode_state is a file write in progress unless finished is true + bool finished = decode_state && decode_state->finishDecode(); + if (!finished) + { + return false; + } + + llassert_always(gAudiop); + + LLAudioData *adp = gAudiop->getAudioData(decode_id); + if (!adp) + { + LL_WARNS("AudioEngine") << "Missing LLAudioData for decode of " << decode_id << LL_ENDL; + return true; + } + + bool valid = decode_state && decode_state->isValid(); + // Mark current decode finished regardless of success or failure + adp->setHasCompletedDecode(true); + // Flip flags for decoded data + adp->setHasDecodeFailed(!valid); + adp->setHasDecodedData(valid); + // When finished decoding, there will also be a decoded wav file cached on + // disk with the .dsf extension + if (valid) + { + adp->setHasWAVLoadFailed(false); + } + + return true; } ////////////////////////////////////////////////////////////////////////////// LLAudioDecodeMgr::LLAudioDecodeMgr() { - mImpl = new Impl; + mImpl = new Impl(); } LLAudioDecodeMgr::~LLAudioDecodeMgr() { - delete mImpl; + delete mImpl; + mImpl = nullptr; } -void LLAudioDecodeMgr::processQueue(const F32 num_secs) +void LLAudioDecodeMgr::processQueue() { - mImpl->processQueue(num_secs); + mImpl->processQueue(); } BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid) @@ -687,7 +782,7 @@ BOOL LLAudioDecodeMgr::addDecodeRequest(const LLUUID &uuid) { // Just put it on the decode queue. LL_DEBUGS("AudioEngine") << "addDecodeRequest for " << uuid << " has local asset file already" << LL_ENDL; - mImpl->mDecodeQueue.push_back(uuid); + mImpl->mDecodeQueue.push_back(uuid); return TRUE; } diff --git a/indra/llaudio/llaudiodecodemgr.h b/indra/llaudio/llaudiodecodemgr.h index ceaff3f2d8..4c17b46156 100644 --- a/indra/llaudio/llaudiodecodemgr.h +++ b/indra/llaudio/llaudiodecodemgr.h @@ -32,24 +32,23 @@ #include "llassettype.h" #include "llframetimer.h" +#include "llsingleton.h" +template class LLPointer; class LLVorbisDecodeState; -class LLAudioDecodeMgr +class LLAudioDecodeMgr : public LLSingleton { + LLSINGLETON(LLAudioDecodeMgr); + ~LLAudioDecodeMgr(); public: - LLAudioDecodeMgr(); - ~LLAudioDecodeMgr(); - - void processQueue(const F32 num_secs = 0.005); + void processQueue(); BOOL addDecodeRequest(const LLUUID &uuid); void addAudioRequest(const LLUUID &uuid); protected: class Impl; - Impl* mImpl; + Impl* mImpl; }; -extern LLAudioDecodeMgr *gAudioDecodeMgrp; - #endif diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp index e0ebbb76bd..cae6bb62d9 100644 --- a/indra/llaudio/llaudioengine.cpp +++ b/indra/llaudio/llaudioengine.cpp @@ -83,18 +83,10 @@ void LLAudioEngine::setDefaults() mLastStatus = 0; - mNumChannels = 0; mEnableWind = false; - S32 i; - for (i = 0; i < MAX_CHANNELS; i++) - { - mChannels[i] = NULL; - } - for (i = 0; i < MAX_BUFFERS; i++) - { - mBuffers[i] = NULL; - } + mChannels.fill(nullptr); + mBuffers.fill(nullptr); mMasterGain = 1.f; // Setting mInternalGain to an out of range value fixes the issue reported in STORM-830. @@ -111,18 +103,14 @@ void LLAudioEngine::setDefaults() } -bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::string &app_title) +bool LLAudioEngine::init(void* userdata, const std::string &app_title) { setDefaults(); - mNumChannels = num_channels; mUserData = userdata; allocateListener(); - // Initialize the decode manager - gAudioDecodeMgrp = new LLAudioDecodeMgr; - LL_INFOS("AudioEngine") << "LLAudioEngine::init() AudioEngine successfully initialized" << LL_ENDL; return true; @@ -131,10 +119,6 @@ bool LLAudioEngine::init(const S32 num_channels, void* userdata, const std::stri void LLAudioEngine::shutdown() { - // Clean up decode manager - delete gAudioDecodeMgrp; - gAudioDecodeMgrp = NULL; - // Clean up wind source cleanupWind(); @@ -156,14 +140,14 @@ void LLAudioEngine::shutdown() // Clean up channels S32 i; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { delete mChannels[i]; mChannels[i] = NULL; } // Clean up buffers - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { delete mBuffers[i]; mBuffers[i] = NULL; @@ -229,7 +213,7 @@ std::string LLAudioEngine::getInternetStreamURL() void LLAudioEngine::updateChannels() { S32 i; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (mChannels[i]) { @@ -240,20 +224,14 @@ void LLAudioEngine::updateChannels() } } -static const F32 default_max_decode_time = .002f; // 2 ms -void LLAudioEngine::idle(F32 max_decode_time) +void LLAudioEngine::idle() { - if (max_decode_time <= 0.f) - { - max_decode_time = default_max_decode_time; - } - // "Update" all of our audio sources, clean up dead ones. // Primarily does position updating, cleanup of unused audio sources. // Also does regeneration of the current priority of each audio source. S32 i; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i]) { @@ -473,7 +451,7 @@ void LLAudioEngine::idle(F32 max_decode_time) commitDeferredChanges(); // Flush unused buffers that are stale enough - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i]) { @@ -489,7 +467,7 @@ void LLAudioEngine::idle(F32 max_decode_time) // Clear all of the looped flags for the channels - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (mChannels[i]) { @@ -498,7 +476,7 @@ void LLAudioEngine::idle(F32 max_decode_time) } // Decode audio files - gAudioDecodeMgrp->processQueue(max_decode_time); + LLAudioDecodeMgr::getInstance()->processQueue(); // Call this every frame, just in case we somehow // missed picking it up in all the places that can add @@ -532,7 +510,7 @@ bool LLAudioEngine::updateBufferForData(LLAudioData *adp, const LLUUID &audio_uu { if (audio_uuid.notNull()) { - gAudioDecodeMgrp->addDecodeRequest(audio_uuid); + LLAudioDecodeMgr::getInstance()->addDecodeRequest(audio_uuid); } } else @@ -561,7 +539,7 @@ void LLAudioEngine::enableWind(bool enable) LLAudioBuffer * LLAudioEngine::getFreeBuffer() { S32 i; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (!mBuffers[i]) { @@ -574,7 +552,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer() // Grab the oldest unused buffer F32 max_age = -1.f; S32 buffer_id = -1; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i]) { @@ -605,7 +583,7 @@ LLAudioBuffer * LLAudioEngine::getFreeBuffer() LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) { S32 i; - for (i = 0; i < mNumChannels; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -633,7 +611,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) F32 min_priority = 10000.f; LLAudioChannel *min_channelp = NULL; - for (i = 0; i < mNumChannels; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { LLAudioChannel *channelp = mChannels[i]; LLAudioSource *sourcep = channelp->getSource(); @@ -660,7 +638,7 @@ LLAudioChannel * LLAudioEngine::getFreeChannel(const F32 priority) void LLAudioEngine::cleanupBuffer(LLAudioBuffer *bufferp) { S32 i; - for (i = 0; i < MAX_BUFFERS; i++) + for (i = 0; i < LL_MAX_AUDIO_BUFFERS; i++) { if (mBuffers[i] == bufferp) { @@ -678,7 +656,7 @@ bool LLAudioEngine::preloadSound(const LLUUID &uuid) getAudioData(uuid); // We don't care about the return value, this is just to make sure // that we have an entry, which will mean that the audio engine knows about this - if (gAudioDecodeMgrp->addDecodeRequest(uuid)) + if (LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid)) { // This means that we do have a local copy, and we're working on decoding it. return true; @@ -953,6 +931,7 @@ LLAudioSource * LLAudioEngine::findAudioSource(const LLUUID &source_id) LLAudioData * LLAudioEngine::getAudioData(const LLUUID &audio_uuid) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; data_map::iterator iter; iter = mAllData.find(audio_uuid); if (iter == mAllData.end()) @@ -1039,7 +1018,7 @@ void LLAudioEngine::startNextTransfer() // Check all channels for currently playing sounds. F32 max_pri = -1.f; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -1067,7 +1046,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1078,7 +1057,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.isNull()) { max_pri = -1.f; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -1103,7 +1082,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1115,7 +1094,7 @@ void LLAudioEngine::startNextTransfer() if (asset_id.isNull()) { max_pri = -1.f; - for (i = 0; i < MAX_CHANNELS; i++) + for (i = 0; i < LL_MAX_AUDIO_CHANNELS; i++) { if (!mChannels[i]) { @@ -1143,7 +1122,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1171,7 +1150,7 @@ void LLAudioEngine::startNextTransfer() } adp = asp->getCurrentData(); - if (adp && !adp->hasLocalData() && adp->hasValidData()) + if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1179,7 +1158,7 @@ void LLAudioEngine::startNextTransfer() } adp = asp->getQueuedData(); - if (adp && !adp->hasLocalData() && adp->hasValidData()) + if (adp && !adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1194,7 +1173,7 @@ void LLAudioEngine::startNextTransfer() continue; } - if (!adp->hasLocalData() && adp->hasValidData()) + if (!adp->hasLocalData() && !adp->hasDecodeFailed()) { asset_id = adp->getID(); max_pri = asp->getPriority(); @@ -1235,7 +1214,7 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v LLAudioData *adp = gAudiop->getAudioData(uuid); if (adp) { // Make sure everything is cleared - adp->setHasValidData(false); + adp->setHasDecodeFailed(true); adp->setHasLocalData(false); adp->setHasDecodedData(false); adp->setHasCompletedDecode(true); @@ -1252,9 +1231,9 @@ void LLAudioEngine::assetCallback(const LLUUID &uuid, LLAssetType::EType type, v else { // LL_INFOS() << "Got asset callback with good audio data for " << uuid << ", making decode request" << LL_ENDL; - adp->setHasValidData(true); + adp->setHasDecodeFailed(false); adp->setHasLocalData(true); - gAudioDecodeMgrp->addDecodeRequest(uuid); + LLAudioDecodeMgr::getInstance()->addDecodeRequest(uuid); } } gAudiop->mCurrentTransfer = LLUUID::null; @@ -1324,11 +1303,15 @@ void LLAudioSource::update() { // Hack - try and load the sound. Will do this as a callback // on decode later. - if (adp->load() && adp->getBuffer()) + if (adp->getBuffer()) { play(adp->getID()); } - else if (adp->hasCompletedDecode()) // Only mark corrupted after decode is done + else if (adp->hasDecodedData() && !adp->hasWAVLoadFailed()) + { + adp->load(); + } + else if (adp->hasCompletedDecode() && adp->hasDecodeFailed()) // Only mark corrupted after decode is done { LL_WARNS() << "Marking LLAudioSource corrupted for " << adp->getID() << LL_ENDL; mCorrupted = true ; @@ -1624,12 +1607,12 @@ bool LLAudioSource::hasPendingPreloads() const { LLAudioData *adp = iter->second; // note: a bad UUID will forever be !hasDecodedData() - // but also !hasValidData(), hence the check for hasValidData() + // but also hasDecodeFailed(), hence the check for hasDecodeFailed() if (!adp) { continue; } - if (!adp->hasDecodedData() && adp->hasValidData()) + if (!adp->hasDecodedData() && !adp->hasDecodeFailed()) { // This source is still waiting for a preload return true; @@ -1786,7 +1769,8 @@ LLAudioData::LLAudioData(const LLUUID &uuid) : mHasLocalData(false), mHasDecodedData(false), mHasCompletedDecode(false), - mHasValidData(true) + mHasDecodeFailed(false), + mHasWAVLoadFailed(false) { if (uuid.isNull()) { @@ -1821,12 +1805,14 @@ bool LLAudioData::load() { // We already have this sound in a buffer, don't do anything. LL_INFOS() << "Already have a buffer for this sound, don't bother loading!" << LL_ENDL; + mHasWAVLoadFailed = false; return true; } if (!gAudiop) { LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL; + mHasWAVLoadFailed = true; return false; } @@ -1835,6 +1821,8 @@ bool LLAudioData::load() { // No free buffers, abort. LL_INFOS() << "Not able to allocate a new audio buffer, aborting." << LL_ENDL; + // *TODO: Mark this failure differently so the audio engine could retry loading this buffer in the future + mHasWAVLoadFailed = true; return true; } @@ -1843,7 +1831,8 @@ bool LLAudioData::load() mID.toString(uuid_str); wav_path= gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str) + ".dsf"; - if (!mBufferp->loadWAV(wav_path)) + mHasWAVLoadFailed = !mBufferp->loadWAV(wav_path); + if (mHasWAVLoadFailed) { // Hrm. Right now, let's unset the buffer, since it's empty. gAudiop->cleanupBuffer(mBufferp); diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h old mode 100644 new mode 100755 index b5fd4c27a1..65356ba00e --- a/indra/llaudio/llaudioengine.h +++ b/indra/llaudio/llaudioengine.h @@ -47,8 +47,8 @@ const F32 LL_WIND_UNDERWATER_CENTER_FREQ = 20.f; const F32 ATTACHED_OBJECT_TIMEOUT = 5.0f; const F32 DEFAULT_MIN_DISTANCE = 2.0f; -#define MAX_CHANNELS 30 -#define MAX_BUFFERS 40 // Some extra for preloading, maybe? +#define LL_MAX_AUDIO_CHANNELS 30 +#define LL_MAX_AUDIO_BUFFERS 40 // Some extra for preloading, maybe? class LLAudioSource; class LLAudioData; @@ -88,7 +88,7 @@ public: virtual ~LLAudioEngine(); // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *userdata, const std::string &app_title); + virtual bool init(void *userdata, const std::string &app_title); virtual std::string getDriverName(bool verbose) = 0; virtual void shutdown(); @@ -96,7 +96,7 @@ public: //virtual void processQueue(const LLUUID &sound_guid); virtual void setListener(LLVector3 pos,LLVector3 vel,LLVector3 up,LLVector3 at); virtual void updateWind(LLVector3 direction, F32 camera_height_above_water) = 0; - virtual void idle(F32 max_decode_time = 0.f); + virtual void idle(); virtual void updateChannels(); // @@ -209,7 +209,6 @@ protected: S32 mLastStatus; - S32 mNumChannels; bool mEnableWind; LLUUID mCurrentTransfer; // Audio file currently being transferred by the system @@ -224,11 +223,11 @@ protected: source_map mAllSources; data_map mAllData; - LLAudioChannel *mChannels[MAX_CHANNELS]; + std::array mChannels; // Buffers needs to change into a different data structure, as the number of buffers // that we have active should be limited by RAM usage, not count. - LLAudioBuffer *mBuffers[MAX_BUFFERS]; + std::array mBuffers; F32 mMasterGain; F32 mInternalGain; // Actual gain set; either mMasterGain or 0 when mMuted is true. @@ -360,32 +359,36 @@ protected: class LLAudioData { -public: - LLAudioData(const LLUUID &uuid); - bool load(); - - LLUUID getID() const { return mID; } - LLAudioBuffer *getBuffer() const { return mBufferp; } - - bool hasLocalData() const { return mHasLocalData; } - bool hasDecodedData() const { return mHasDecodedData; } - bool hasCompletedDecode() const { return mHasCompletedDecode; } - bool hasValidData() const { return mHasValidData; } - - void setHasLocalData(const bool hld) { mHasLocalData = hld; } - void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; } - void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; } - void setHasValidData(const bool hvd) { mHasValidData = hvd; } - - friend class LLAudioEngine; // Severe laziness, bad. - -protected: - LLUUID mID; - LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. - bool mHasLocalData; // Set true if the sound asset file is available locally - bool mHasDecodedData; // Set true if the sound file has been decoded - bool mHasCompletedDecode; // Set true when the sound is decoded - bool mHasValidData; // Set false if decoding failed, meaning the sound asset is bad + public: + LLAudioData(const LLUUID &uuid); + bool load(); + + LLUUID getID() const { return mID; } + LLAudioBuffer *getBuffer() const { return mBufferp; } + + bool hasLocalData() const { return mHasLocalData; } + bool hasDecodedData() const { return mHasDecodedData; } + bool hasCompletedDecode() const { return mHasCompletedDecode; } + bool hasDecodeFailed() const { return mHasDecodeFailed; } + bool hasWAVLoadFailed() const { return mHasWAVLoadFailed; } + + void setHasLocalData(const bool hld) { mHasLocalData = hld; } + void setHasDecodedData(const bool hdd) { mHasDecodedData = hdd; } + void setHasCompletedDecode(const bool hcd) { mHasCompletedDecode = hcd; } + void setHasDecodeFailed(const bool hdf) { mHasDecodeFailed = hdf; } + void setHasWAVLoadFailed(const bool hwlf) { mHasWAVLoadFailed = hwlf; } + + friend class LLAudioEngine; // Severe laziness, bad. + + protected: + LLUUID mID; + LLAudioBuffer *mBufferp; // If this data is being used by the audio system, a pointer to the buffer will be set here. + bool mHasLocalData; // Set true if the encoded sound asset file is available locally + bool mHasDecodedData; // Set true if the decoded sound file is available on disk + bool mHasCompletedDecode; // Set true when the sound is decoded + bool mHasDecodeFailed; // Set true if decoding failed, meaning the sound asset is bad + bool mHasWAVLoadFailed; // Set true if loading the decoded WAV file failed, meaning the sound asset should be decoded instead if + // possible }; diff --git a/indra/llaudio/llaudioengine_fmodstudio.cpp b/indra/llaudio/llaudioengine_fmodstudio.cpp index b0c87b0208..ce2c7d5551 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.cpp +++ b/indra/llaudio/llaudioengine_fmodstudio.cpp @@ -74,7 +74,7 @@ static inline bool Check_FMOD_Error(FMOD_RESULT result, const char *string) return true; } -bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, const std::string &app_title) +bool LLAudioEngine_FMODSTUDIO::init(void* userdata, const std::string &app_title) { U32 version; FMOD_RESULT result; @@ -86,7 +86,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons return false; //will call LLAudioEngine_FMODSTUDIO::allocateListener, which needs a valid mSystem pointer. - LLAudioEngine::init(num_channels, userdata, app_title); + LLAudioEngine::init(userdata, app_title); result = mSystem->getVersion(&version); Check_FMOD_Error(result, "FMOD::System::getVersion"); @@ -98,7 +98,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons } // In this case, all sounds, PLUS wind and stream will be software. - result = mSystem->setSoftwareChannels(num_channels + 2); + result = mSystem->setSoftwareChannels(LL_MAX_AUDIO_CHANNELS + 2); Check_FMOD_Error(result, "FMOD::System::setSoftwareChannels"); FMOD_ADVANCEDSETTINGS settings; @@ -127,7 +127,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons { LL_DEBUGS("AppInit") << "Trying PulseAudio audio output..." << LL_ENDL; if (mSystem->setOutput(FMOD_OUTPUTTYPE_PULSEAUDIO) == FMOD_OK && - (result = mSystem->init(num_channels + 2, fmod_flags, const_cast(app_title.c_str()))) == FMOD_OK) + (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, const_cast(app_title.c_str()))) == FMOD_OK) { LL_DEBUGS("AppInit") << "PulseAudio output initialized OKAY" << LL_ENDL; audio_ok = true; @@ -149,7 +149,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons { LL_DEBUGS("AppInit") << "Trying ALSA audio output..." << LL_ENDL; if (mSystem->setOutput(FMOD_OUTPUTTYPE_ALSA) == FMOD_OK && - (result = mSystem->init(num_channels + 2, fmod_flags, 0)) == FMOD_OK) + (result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0)) == FMOD_OK) { LL_DEBUGS("AppInit") << "ALSA audio output initialized OKAY" << LL_ENDL; audio_ok = true; @@ -190,7 +190,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons // initialize the FMOD engine // number of channel in this case looks to be identiacal to number of max simultaneously // playing objects and we can set practically any number - result = mSystem->init(num_channels + 2, fmod_flags, 0); + result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0); if (Check_FMOD_Error(result, "Error initializing FMOD Studio with default settins, retrying with other format")) { result = mSystem->setSoftwareFormat(44100, FMOD_SPEAKERMODE_STEREO, 0/*- ignore*/); @@ -198,7 +198,7 @@ bool LLAudioEngine_FMODSTUDIO::init(const S32 num_channels, void* userdata, cons { return false; } - result = mSystem->init(num_channels + 2, fmod_flags, 0); + result = mSystem->init(LL_MAX_AUDIO_CHANNELS + 2, fmod_flags, 0); } if (Check_FMOD_Error(result, "Error initializing FMOD Studio")) { diff --git a/indra/llaudio/llaudioengine_fmodstudio.h b/indra/llaudio/llaudioengine_fmodstudio.h index f2361df1b6..d3d6d69685 100644 --- a/indra/llaudio/llaudioengine_fmodstudio.h +++ b/indra/llaudio/llaudioengine_fmodstudio.h @@ -51,7 +51,7 @@ public: virtual ~LLAudioEngine_FMODSTUDIO(); // initialization/startup/shutdown - virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title); + virtual bool init(void *user_data, const std::string &app_title); virtual std::string getDriverName(bool verbose); virtual void allocateListener(); diff --git a/indra/llaudio/llaudioengine_openal.cpp b/indra/llaudio/llaudioengine_openal.cpp index 3bdd0302ee..a87b4c07e2 100644 --- a/indra/llaudio/llaudioengine_openal.cpp +++ b/indra/llaudio/llaudioengine_openal.cpp @@ -52,10 +52,10 @@ LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL() } // virtual -bool LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata, const std::string &app_title) +bool LLAudioEngine_OpenAL::init(void* userdata, const std::string &app_title) { mWindGen = NULL; - LLAudioEngine::init(num_channels, userdata, app_title); + LLAudioEngine::init(userdata, app_title); if(!alutInit(NULL, NULL)) { diff --git a/indra/llcommon/workqueue.h b/indra/llcommon/workqueue.h index 96574a18b9..70fd65bd0c 100644 --- a/indra/llcommon/workqueue.h +++ b/indra/llcommon/workqueue.h @@ -403,7 +403,7 @@ namespace LL [result = std::forward(callable)(), callback = std::move(callback)] () - { callback(std::move(result)); }; + mutable { callback(std::move(result)); }; } }; @@ -449,7 +449,7 @@ namespace LL callable = std::move(callable), callback = std::move(callback)] () - { + mutable { // Use postMaybe() below in case this originating WorkQueue // has been closed or destroyed. Remember, the outer lambda is // now running on a thread servicing the target WorkQueue, and @@ -513,7 +513,7 @@ namespace LL // We dare to bind a reference to Promise because it's // specifically designed for cross-thread communication. [&promise, callable = std::move(callable)]() - { + mutable { try { // call the caller's callable and trigger promise with result @@ -542,7 +542,7 @@ namespace LL time, // &promise is designed for cross-thread access [&promise, callable = std::move(callable)]() - { + mutable { try { callable(); diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 979a888814..b5ed8d8647 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -5020,8 +5020,7 @@ void LLAppViewer::idle() audio_update_wind(false); // this line actually commits the changes we've made to source positions, etc. - const F32 max_audio_decode_time = 0.002f; // 2 ms decode time - gAudiop->idle(max_audio_decode_time); + gAudiop->idle(); } } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 98b2bc703b..145aba4a71 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -661,7 +661,7 @@ bool idle_startup() #else void* window_handle = NULL; #endif - bool init = gAudiop->init(kAUDIO_NUM_SOURCES, window_handle, LLAppViewer::instance()->getSecondLifeTitle()); + bool init = gAudiop->init(window_handle, LLAppViewer::instance()->getSecondLifeTitle()); if(init) { gAudiop->setMuted(TRUE); diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h index 782285ce36..febae36ae8 100644 --- a/indra/newview/llvieweraudio.h +++ b/indra/newview/llvieweraudio.h @@ -33,8 +33,6 @@ // comment out to turn off wind #define kAUDIO_ENABLE_WIND //#define kAUDIO_ENABLE_WATER 1 // comment out to turn off water -#define kAUDIO_NUM_BUFFERS 30 -#define kAUDIO_NUM_SOURCES 30 void init_audio(); void audio_update_volume(bool force_update = true); -- cgit v1.2.3 From 30252bceb068bc1b687b18a85ab5e1b5a98c1184 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 31 May 2022 12:49:53 -0700 Subject: SL-16182: LLAudioDecodeMgr: Get general worker thread count directly from ThreadPool --- indra/llaudio/llaudiodecodemgr.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index cc5abee08a..4c4f4d3d0e 100755 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -35,6 +35,7 @@ #include "llendianswizzle.h" #include "llassetstorage.h" #include "llrefcount.h" +#include "threadpool.h" #include "workqueue.h" #include "llvorbisencode.h" @@ -575,8 +576,10 @@ void LLAudioDecodeMgr::Impl::startMoreDecodes() // *NOTE: main_queue->postTo casts this refcounted smart pointer to a weak // pointer LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); + const LL::ThreadPool::ptr_t general_thread_pool = LL::ThreadPool::getInstance("General"); llassert_always(main_queue); llassert_always(general_queue); + llassert_always(general_thread_pool); // Set max decodes to double the thread count of the general work queue. // This ensures the general work queue is full, but prevents theoretical // buildup of buffers in memory due to disk writes once the @@ -585,9 +588,9 @@ void LLAudioDecodeMgr::Impl::startMoreDecodes() // without modifying/removing LLVorbisDecodeState, at which point we should // consider decoding the audio during the asset download process. // -Cosmic,2022-05-11 - const size_t MAX_DECODES = 4 * 2; + const size_t max_decodes = general_thread_pool->getWidth() * 2; - while (!mDecodeQueue.empty() && mDecodes.size() < MAX_DECODES) + while (!mDecodeQueue.empty() && mDecodes.size() < max_decodes) { const LLUUID decode_id = mDecodeQueue.front(); mDecodeQueue.pop_front(); -- cgit v1.2.3 From 462b1c6544425c0a37f27da32fbf770e9e7373f9 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 14 Jun 2022 13:00:53 -0700 Subject: SL-16182: Fix Mac compiler errors --- indra/llaudio/llaudiodecodemgr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/llaudio/llaudiodecodemgr.cpp b/indra/llaudio/llaudiodecodemgr.cpp index 4c4f4d3d0e..bc082bf39a 100755 --- a/indra/llaudio/llaudiodecodemgr.cpp +++ b/indra/llaudio/llaudiodecodemgr.cpp @@ -533,7 +533,7 @@ void LLVorbisDecodeState::flushBadFile() class LLAudioDecodeMgr::Impl { friend class LLAudioDecodeMgr; - LLAudioDecodeMgr::Impl(); + Impl(); public: void processQueue(); @@ -609,7 +609,7 @@ void LLAudioDecodeMgr::Impl::startMoreDecodes() mDecodes[decode_id] = LLPointer(NULL); main_queue->postTo( general_queue, - [decode_id, this]() // Work done on general queue + [decode_id]() // Work done on general queue { LLPointer decode_state = beginDecodingAndWritingAudio(decode_id); -- cgit v1.2.3 From beae4564e365e4f61cb7ee535701fa9e82afc7ef Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 15 Jun 2022 16:00:21 +0300 Subject: SL-17584 Make setShaders crashes more informative --- indra/llrender/llshadermgr.cpp | 2 +- indra/newview/llviewershadermgr.cpp | 21 ++++++++++----------- indra/newview/llviewershadermgr.h | 6 +++++- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index c100c182dd..c64f46f38a 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -665,7 +665,7 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade if (file == NULL) { - LL_SHADER_LOADING_WARNS() << "GLSL Shader file not found: " << open_file_name << LL_ENDL; + LL_WARNS("ShaderLoading") << "GLSL Shader file not found: " << open_file_name << LL_ENDL; return 0; } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index e926c5c3ba..1c9360a843 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -556,15 +556,14 @@ void LLViewerShaderMgr::setShaders() mShaderLevel[SHADER_DEFERRED] = deferred_class; mShaderLevel[SHADER_TRANSFORM] = transform_class; - BOOL loaded = loadBasicShaders(); - if (loaded) + std::string shader_name = loadBasicShaders(); + if (shader_name.empty()) { LL_INFOS() << "Loaded basic shaders." << LL_ENDL; } else { - LL_ERRS() << "Unable to load basic shaders, verify graphics driver installed and current." << LL_ENDL; - llassert(loaded); + LL_ERRS() << "Unable to load basic shader " << shader_name << ", verify graphics driver installed and current." << LL_ENDL; reentrance = false; // For hygiene only, re-try probably helps nothing return; } @@ -572,7 +571,7 @@ void LLViewerShaderMgr::setShaders() gPipeline.mShadersLoaded = true; // Load all shaders to set max levels - loaded = loadShadersEnvironment(); + BOOL loaded = loadShadersEnvironment(); if (loaded) { @@ -859,7 +858,7 @@ void LLViewerShaderMgr::unloadShaders() gPipeline.mShadersLoaded = false; } -BOOL LLViewerShaderMgr::loadBasicShaders() +std::string LLViewerShaderMgr::loadBasicShaders() { // Load basic dependency shaders first // All of these have to load for any shaders to function @@ -945,8 +944,8 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // Note usage of GL_VERTEX_SHADER_ARB if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0) { - LL_SHADER_LOADING_WARNS() << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; - return FALSE; + LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL; + return shaders[i].first; } } @@ -1005,12 +1004,12 @@ BOOL LLViewerShaderMgr::loadBasicShaders() // Note usage of GL_FRAGMENT_SHADER_ARB if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0) { - LL_SHADER_LOADING_WARNS() << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; - return FALSE; + LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL; + return shaders[i].first; } } - return TRUE; + return std::string(); } BOOL LLViewerShaderMgr::loadShadersEnvironment() diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 93bb29a355..f8a261805b 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -49,7 +49,11 @@ public: void setShaders(); void unloadShaders(); S32 getShaderLevel(S32 type); - BOOL loadBasicShaders(); + + // loadBasicShaders in case of a failure returns + // name of a file error happened at, otherwise + // returns an empty string + std::string loadBasicShaders(); BOOL loadShadersEffects(); BOOL loadShadersDeferred(); BOOL loadShadersObject(); -- cgit v1.2.3 From ed36165f291c4aed94058ef5b890044f55a7bf9b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 15 Jun 2022 18:03:11 +0300 Subject: SL-17584 Frame buffer object is now nessesary to run viewer --- indra/llrender/llgl.cpp | 14 ++++++++------ indra/llrender/llrendertarget.cpp | 2 +- indra/newview/lldynamictexture.cpp | 4 ++-- indra/newview/llfloaterpreference.cpp | 5 +---- indra/newview/llviewermenu.cpp | 17 ++--------------- 5 files changed, 14 insertions(+), 28 deletions(-) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 18168d1c3f..df7c84e761 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -747,6 +747,14 @@ bool LLGLManager::initGL() LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL; return false; } + + if (!mHasFramebufferObject) + { + mHasRequirements = FALSE; + + LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_framebuffer_object" << LL_ENDL; + return false; + } stop_glerror(); @@ -762,12 +770,6 @@ bool LLGLManager::initGL() //HACK always disable texture multisample, use FXAA instead mHasTextureMultisample = FALSE; -#if LL_WINDOWS - if (mIsIntel && mGLVersion <= 3.f) - { //never try to use framebuffer objects on older intel drivers (crashy) - mHasFramebufferObject = FALSE; - } -#endif if (mHasFramebufferObject) { diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 0408010513..fffc15efc3 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -133,7 +133,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo mUsage = usage; mUseDepth = depth; - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) + if (sUseFBO || use_fbo) { if (depth) { diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 63e7887d81..361a7666fa 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -125,7 +125,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) llassert(mFullHeight <= static_cast(gPipeline.mPhysicsDisplay.getHeight())); } - if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD) + if (gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD) { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -212,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsAMD; + bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD; if (use_fbo) { diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 8d19aa36bb..1a76766322 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1200,7 +1200,6 @@ void LLFloaterPreference::refreshEnabledState() BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && bumpshiny && shaders && - gGLManager.mHasFramebufferObject && (ctrl_wind_light->get()) ? TRUE : FALSE; ctrl_deferred->setEnabled(enabled); @@ -1251,7 +1250,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && ((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) && - gGLManager.mHasFramebufferObject && (ctrl_wind_light->get()) ? TRUE : FALSE; ctrl_deferred->setEnabled(enabled); @@ -1385,8 +1383,7 @@ void LLFloaterPreferenceGraphicsAdvanced::disableUnavailableSettings() } // disabled deferred - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") || - !gGLManager.mHasFramebufferObject) + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) { ctrl_shadows->setEnabled(FALSE); ctrl_shadows->setValue(0); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index e3de4267dc..5b300e96c6 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2311,18 +2311,6 @@ class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t } }; -///////////////////////////////////// -// Enable Framebuffer Objects /// -///////////////////////////////////// -class LLAdvancedEnableRenderFBO: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gGLManager.mHasFramebufferObject; - return new_value; - } -}; - ///////////////////////////////////// // Enable Deferred Rendering /// ///////////////////////////////////// @@ -2330,7 +2318,7 @@ class LLAdvancedEnableRenderDeferred: public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && + bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0; return new_value; } @@ -2343,7 +2331,7 @@ class LLAdvancedEnableRenderDeferredOptions: public view_listener_t { bool handleEvent(const LLSD& userdata) { - bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && + bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred"); return new_value; } @@ -9264,7 +9252,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); // Develop > Render view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion"); - view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO"); view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred"); view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions"); view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate"); -- cgit v1.2.3 From 75668d45221a48728b67c63ba3ef41c728f51214 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 16 Jun 2022 23:47:26 +0300 Subject: SL-17585 Crash at LLAppViewer::initConfiguration --- .../newview/installers/windows/installer_template.nsi | 2 ++ indra/newview/llappviewer.cpp | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 7513908cb4..da46587403 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -622,6 +622,8 @@ Function RemoveProgFilesOnInst Push $0 StrCpy $0 0 +ClearErrors + PREINSTALLREMOVE: # Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index b5ed8d8647..cd2174eea4 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -2489,10 +2489,24 @@ bool LLAppViewer::initConfiguration() //Load settings files list std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); LLXMLNodePtr root; - BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); + BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); if (!success) { - LL_ERRS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; + LL_WARNS() << "Cannot load default configuration file " << settings_file_list << LL_ENDL; + if (gDirUtilp->fileExists(settings_file_list)) + { + LL_ERRS() << "Cannot load default configuration file settings_files.xml. " + << "Please reinstall viewer from https://secondlife.com/support/downloads/ " + << "and contact https://support.secondlife.com if issue persists after reinstall." + << LL_ENDL; + } + else + { + LL_ERRS() << "Default configuration file settings_files.xml not found. " + << "Please reinstall viewer from https://secondlife.com/support/downloads/ " + << "and contact https://support.secondlife.com if issue persists after reinstall." + << LL_ENDL; + } } mSettingsLocationList = new SettingsFiles(); -- cgit v1.2.3 From 9f3e815adc5abb32272e7413e20168dcb73ef60e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 17 Jun 2022 20:43:04 +0300 Subject: SL-17585 Ensure nothing went wrong with installation during 'File' operations --- .../installers/windows/installer_template.nsi | 31 +++++++++++++++------ indra/newview/installers/windows/lang_da.nsi | Bin 11992 -> 12802 bytes indra/newview/installers/windows/lang_de.nsi | 4 +++ indra/newview/installers/windows/lang_en-us.nsi | Bin 11666 -> 12480 bytes indra/newview/installers/windows/lang_es.nsi | Bin 12976 -> 13790 bytes indra/newview/installers/windows/lang_fr.nsi | Bin 13492 -> 14302 bytes indra/newview/installers/windows/lang_it.nsi | Bin 12714 -> 13528 bytes indra/newview/installers/windows/lang_ja.nsi | Bin 9880 -> 10698 bytes indra/newview/installers/windows/lang_pl.nsi | Bin 12312 -> 13122 bytes indra/newview/installers/windows/lang_pt-br.nsi | Bin 13136 -> 13970 bytes indra/newview/installers/windows/lang_ru.nsi | Bin 12450 -> 13264 bytes indra/newview/installers/windows/lang_tr.nsi | Bin 12360 -> 13174 bytes indra/newview/installers/windows/lang_zh.nsi | Bin 9324 -> 10144 bytes 13 files changed, 27 insertions(+), 8 deletions(-) diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index da46587403..7d5d4fc16f 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -351,11 +351,26 @@ DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "IsHostApp" DeleteRegValue HKEY_CLASSES_ROOT "Applications\$VIEWER_EXE" "NoStartPage" ClearErrors +INSTALL_FILES_START: + Call RemoveProgFilesOnInst # Remove existing files to prevent certain errors when running the new version of the viewer # This placeholder is replaced by the complete list of all the files in the installer, by viewer_manifest.py %%INSTALL_FILES%% +IfErrors 0 INSTALL_FILES_DONE + StrCmp $SKIP_DIALOGS "true" INSTALL_FILES_DONE + MessageBox MB_ABORTRETRYIGNORE $(ErrorSecondLifeInstallRetry) IDABORT INSTALL_FILES_CANCEL IDRETRY INSTALL_FILES_START + # MB_ABORTRETRYIGNORE does not accept IDIGNORE + Goto INSTALL_FILES_DONE + +INSTALL_FILES_CANCEL: + Call RemoveProgFilesOnInst + MessageBox MB_OK $(ErrorSecondLifeInstallSupport) + Quit + +INSTALL_FILES_DONE: + # Pass the installer's language to the client to use as a default StrCpy $SHORTCUT_LANG_PARAM "--set InstallLanguage $(LanguageCode)" @@ -624,7 +639,7 @@ StrCpy $0 0 ClearErrors -PREINSTALLREMOVE: +PREINSTALL_REMOVE: # Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575 Delete "$INSTDIR\$INSTEXE" @@ -644,17 +659,17 @@ RMDir /r "$INSTDIR\llplugin" IntOp $0 $0 + 1 -IfErrors 0 PREINSTALLDONE - IntCmp $0 1 PREINSTALLREMOVE #try again once - StrCmp $SKIP_DIALOGS "true" PREINSTALLDONE - MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALLFAIL IDRETRY PREINSTALLREMOVE +IfErrors 0 PREINSTALL_DONE + IntCmp $0 1 PREINSTALL_REMOVE #try again once + StrCmp $SKIP_DIALOGS "true" PREINSTALL_DONE + MessageBox MB_ABORTRETRYIGNORE $(CloseSecondLifeInstRM) IDABORT PREINSTALL_FAIL IDRETRY PREINSTALL_REMOVE # MB_ABORTRETRYIGNORE does not accept IDIGNORE - Goto PREINSTALLDONE + Goto PREINSTALL_DONE -PREINSTALLFAIL: +PREINSTALL_FAIL: Quit -PREINSTALLDONE: +PREINSTALL_DONE: # We are no longer including release notes with the viewer, so remove them. Delete "$SMPROGRAMS\$INSTSHORTCUT\SL Release Notes.lnk" diff --git a/indra/newview/installers/windows/lang_da.nsi b/indra/newview/installers/windows/lang_da.nsi index 648ddbfb85..73f23086be 100644 Binary files a/indra/newview/installers/windows/lang_da.nsi and b/indra/newview/installers/windows/lang_da.nsi differ diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi index 188c30197a..d9a5e90a78 100755 --- a/indra/newview/installers/windows/lang_de.nsi +++ b/indra/newview/installers/windows/lang_de.nsi @@ -73,6 +73,10 @@ LangString CloseSecondLifeUnInstMB ${LANG_GERMAN} "Second Life kann nicht entfer ; CheckNetworkConnection LangString CheckNetworkConnectionDP ${LANG_GERMAN} "Prüfe Netzwerkverbindung..." +; error during installation +LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Second Life installer encountered issues during installation. Some files may not have been copied correctly." +LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." + ; ask to remove user's data files LangString RemoveDataFilesMB ${LANG_GERMAN} "Möchten Sie alle anderen zu Second Life gehörigen Dateien ebenfalls ENTFERNEN?$\n$\nWir empfehlen, die Einstellungen und Cache-Dateien zu behalten, wenn Sie andere Versionen von Second Life installiert haben oder eine Deinstallation durchführen, um Second Life auf eine neuere Version zu aktualisieren." diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi index 0639d51e10..2eaf97d023 100644 Binary files a/indra/newview/installers/windows/lang_en-us.nsi and b/indra/newview/installers/windows/lang_en-us.nsi differ diff --git a/indra/newview/installers/windows/lang_es.nsi b/indra/newview/installers/windows/lang_es.nsi index ee30651a38..364cc9f67e 100755 Binary files a/indra/newview/installers/windows/lang_es.nsi and b/indra/newview/installers/windows/lang_es.nsi differ diff --git a/indra/newview/installers/windows/lang_fr.nsi b/indra/newview/installers/windows/lang_fr.nsi index 7cd90ec314..2f34c0c87a 100755 Binary files a/indra/newview/installers/windows/lang_fr.nsi and b/indra/newview/installers/windows/lang_fr.nsi differ diff --git a/indra/newview/installers/windows/lang_it.nsi b/indra/newview/installers/windows/lang_it.nsi index 194062da9a..51214d3a9c 100755 Binary files a/indra/newview/installers/windows/lang_it.nsi and b/indra/newview/installers/windows/lang_it.nsi differ diff --git a/indra/newview/installers/windows/lang_ja.nsi b/indra/newview/installers/windows/lang_ja.nsi index a54005ba14..296703d1a3 100755 Binary files a/indra/newview/installers/windows/lang_ja.nsi and b/indra/newview/installers/windows/lang_ja.nsi differ diff --git a/indra/newview/installers/windows/lang_pl.nsi b/indra/newview/installers/windows/lang_pl.nsi index 355d806866..299645bbb7 100644 Binary files a/indra/newview/installers/windows/lang_pl.nsi and b/indra/newview/installers/windows/lang_pl.nsi differ diff --git a/indra/newview/installers/windows/lang_pt-br.nsi b/indra/newview/installers/windows/lang_pt-br.nsi index 97f5d2b44a..542c8654b5 100755 Binary files a/indra/newview/installers/windows/lang_pt-br.nsi and b/indra/newview/installers/windows/lang_pt-br.nsi differ diff --git a/indra/newview/installers/windows/lang_ru.nsi b/indra/newview/installers/windows/lang_ru.nsi index 65a9f4846d..4e53a4957d 100755 Binary files a/indra/newview/installers/windows/lang_ru.nsi and b/indra/newview/installers/windows/lang_ru.nsi differ diff --git a/indra/newview/installers/windows/lang_tr.nsi b/indra/newview/installers/windows/lang_tr.nsi index e71886cc66..bae5029ad1 100755 Binary files a/indra/newview/installers/windows/lang_tr.nsi and b/indra/newview/installers/windows/lang_tr.nsi differ diff --git a/indra/newview/installers/windows/lang_zh.nsi b/indra/newview/installers/windows/lang_zh.nsi index f5f0c6cbdf..7922d9df52 100755 Binary files a/indra/newview/installers/windows/lang_zh.nsi and b/indra/newview/installers/windows/lang_zh.nsi differ -- cgit v1.2.3 From e3ef358bb9d7c78a6c7df3ea5aea3bc501a4ae09 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 17 Jun 2022 23:11:50 +0300 Subject: SL-17614 Crash at settings_setup_listeners Likely a corrupted install, warn user to reinstall viewer --- indra/newview/llviewercontrol.cpp | 329 +++++++++++++++++++++----------------- 1 file changed, 179 insertions(+), 150 deletions(-) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 4618871630..68c4608687 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -646,158 +646,187 @@ bool toggle_show_object_render_cost(const LLSD& newvalue) void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value); //////////////////////////////////////////////////////////////////////////// +LLPointer setting_get_control(LLControlGroup& group, const std::string& setting) +{ + LLPointer cntrl_ptr = group.getControl(setting); + if (cntrl_ptr.isNull()) + { + LL_ERRS() << "Unable to set up setting listener for " << setting + << ". Please reinstall viewer from https ://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." + << LL_ENDL; + } + return cntrl_ptr; +} + +void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function callback) +{ + setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) + { + callback(new_val); + }); +} + +void setting_setup_signal_listener(LLControlGroup& group, const std::string& setting, std::function callback) +{ + setting_get_control(group, setting)->getSignal()->connect([callback](LLControlVariable* control, const LLSD& new_val, const LLSD& old_val) + { + callback(); + }); +} + void settings_setup_listeners() { - gSavedSettings.getControl("FirstPersonAvatarVisible")->getSignal()->connect(boost::bind(&handleRenderAvatarMouselookChanged, _2)); - gSavedSettings.getControl("RenderFarClip")->getSignal()->connect(boost::bind(&handleRenderFarClipChanged, _2)); - gSavedSettings.getControl("RenderTerrainDetail")->getSignal()->connect(boost::bind(&handleTerrainDetailChanged, _2)); - gSavedSettings.getControl("OctreeStaticObjectSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeMaxNodeCapacity")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeAlphaDistanceFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("OctreeAttachmentSizeFactor")->getSignal()->connect(boost::bind(&handleRepartition, _2)); - gSavedSettings.getControl("RenderMaxTextureIndex")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderUseTriStrips")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleWindowResized, _2)); - gSavedSettings.getControl("RenderDepthOfField")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); - gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleLUTBufferChanged, _2)); - gSavedSettings.getControl("RenderAnisotropic")->getSignal()->connect(boost::bind(&handleAnisotropicChanged, _2)); - gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleShadowsResized, _2)); - gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderGlowResolutionPow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderAvatarCloth")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("WindLightUseAtmosShaders")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderGammaFull")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); - gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _2)); - gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _2)); - gSavedSettings.getControl("RenderAvatarPhysicsLODFactor")->getSignal()->connect(boost::bind(&handleAvatarPhysicsLODChanged, _2)); - gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _2)); - gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _2)); - gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _2)); - gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _2)); - gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _2)); - gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2)); - gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2)); - gSavedSettings.getControl("RenderLocalLights")->getSignal()->connect(boost::bind(&handleRenderLocalLightsChanged, _2)); - gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleRenderBumpChanged, _2)); - gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderVSyncEnable")->getSignal()->connect(boost::bind(&handleVSyncChanged, _2)); - gSavedSettings.getControl("RenderDeferredNoise")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); - gSavedSettings.getControl("RenderDebugGL")->getSignal()->connect(boost::bind(&handleRenderDebugGLChanged, _2)); - 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("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)); - gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&handleChatFontSizeChanged, _2)); - gSavedSettings.getControl("ChatPersistTime")->getSignal()->connect(boost::bind(&handleChatPersistTimeChanged, _2)); - gSavedSettings.getControl("ConsoleMaxLines")->getSignal()->connect(boost::bind(&handleConsoleMaxLinesChanged, _2)); - gSavedSettings.getControl("UploadBakedTexOld")->getSignal()->connect(boost::bind(&handleUploadBakedTexOldChanged, _2)); - gSavedSettings.getControl("UseOcclusion")->getSignal()->connect(boost::bind(&handleUseOcclusionChanged, _2)); - gSavedSettings.getControl("AudioLevelMaster")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelSFX")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("AudioLevelUnderwaterRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteVoice")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2)); - gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderUseVAO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderVBOMappingDisable")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("RenderPreferStreamDraw")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); - gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2)); - gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("JoystickAxis6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisScale6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("FlycamAxisDeadZone6")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("AvatarAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisScale5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone2")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone3")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone4")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("BuildAxisDeadZone5")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); - gSavedSettings.getControl("DebugViews")->getSignal()->connect(boost::bind(&handleDebugViewsChanged, _2)); - gSavedSettings.getControl("UserLogFile")->getSignal()->connect(boost::bind(&handleLogFileChanged, _2)); - gSavedSettings.getControl("RenderHideGroupTitle")->getSignal()->connect(boost::bind(handleHideGroupTitleChanged, _2)); - gSavedSettings.getControl("HighResSnapshot")->getSignal()->connect(boost::bind(handleHighResSnapshotChanged, _2)); - gSavedSettings.getControl("EnableVoiceChat")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("PTTCurrentlyEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("PushToTalkButton")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("PushToTalkToggle")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VoiceEarLocation")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VoiceInputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _2)); - gSavedSettings.getControl("VelocityInterpolate")->getSignal()->connect(boost::bind(&handleVelocityInterpolate, _2)); - gSavedSettings.getControl("QAMode")->getSignal()->connect(boost::bind(&show_debug_menus)); - gSavedSettings.getControl("UseDebugMenus")->getSignal()->connect(boost::bind(&show_debug_menus)); - gSavedSettings.getControl("AgentPause")->getSignal()->connect(boost::bind(&toggle_agent_pause, _2)); - gSavedSettings.getControl("ShowNavbarNavigationPanel")->getSignal()->connect(boost::bind(&toggle_show_navigation_panel, _2)); - gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2)); - gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2)); - gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2)); - gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2)); - gSavedSettings.getControl("SpellCheck")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); - gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged)); - gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged)); - 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)); + setting_setup_signal_listener(gSavedSettings, "FirstPersonAvatarVisible", handleRenderAvatarMouselookChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFarClip", handleRenderFarClipChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainDetail", handleTerrainDetailChanged); + setting_setup_signal_listener(gSavedSettings, "OctreeStaticObjectSizeFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeDistanceFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeMaxNodeCapacity", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition); + setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized); + setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAnisotropic", handleAnisotropicChanged); + setting_setup_signal_listener(gSavedSettings, "RenderShadowResolutionScale", handleShadowsResized); + setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAvatarPhysicsLODFactor", handleAvatarPhysicsLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTerrainLODFactor", handleTerrainLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderTreeLODFactor", handleTreeLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFlexTimeFactor", handleFlexLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderGamma", handleGammaChanged); + setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged); + setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged); + setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged); + setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDebugGL", handleRenderDebugGLChanged); + 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, "RenderDeferredSSAO", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged); + setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged); + setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged); + setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); + setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged); + setting_setup_signal_listener(gSavedSettings, "UploadBakedTexOld", handleUploadBakedTexOldChanged); + setting_setup_signal_listener(gSavedSettings, "UseOcclusion", handleUseOcclusionChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMaster", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelSFX", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelUI", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelAmbient", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMusic", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMedia", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelVoice", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelDoppler", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelRolloff", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelUnderwaterRolloff", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteAudio", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteMusic", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteMedia", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged); + setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "JoystickAxis6", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisScale6", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "FlycamAxisDeadZone6", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisScale5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "AvatarAxisDeadZone5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisScale5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone0", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone1", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone2", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone3", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone4", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "BuildAxisDeadZone5", handleJoystickChanged); + setting_setup_signal_listener(gSavedSettings, "DebugViews", handleDebugViewsChanged); + setting_setup_signal_listener(gSavedSettings, "UserLogFile", handleLogFileChanged); + setting_setup_signal_listener(gSavedSettings, "RenderHideGroupTitle", handleHideGroupTitleChanged); + setting_setup_signal_listener(gSavedSettings, "HighResSnapshot", handleHighResSnapshotChanged); + setting_setup_signal_listener(gSavedSettings, "EnableVoiceChat", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "PTTCurrentlyEnabled", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "PushToTalkButton", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "PushToTalkToggle", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VoiceEarLocation", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VoiceInputAudioDevice", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VoiceOutputAudioDevice", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "AudioLevelMic", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "LipSyncEnabled", handleVoiceClientPrefsChanged); + setting_setup_signal_listener(gSavedSettings, "VelocityInterpolate", handleVelocityInterpolate); + setting_setup_signal_listener(gSavedSettings, "QAMode", show_debug_menus); + setting_setup_signal_listener(gSavedSettings, "UseDebugMenus", show_debug_menus); + setting_setup_signal_listener(gSavedSettings, "AgentPause", toggle_agent_pause); + setting_setup_signal_listener(gSavedSettings, "ShowNavbarNavigationPanel", toggle_show_navigation_panel); + setting_setup_signal_listener(gSavedSettings, "ShowMiniLocationPanel", toggle_show_mini_location_panel); + setting_setup_signal_listener(gSavedSettings, "ShowObjectRenderingCost", toggle_show_object_render_cost); + setting_setup_signal_listener(gSavedSettings, "ForceShowGrid", handleForceShowGrid); + setting_setup_signal_listener(gSavedSettings, "RenderTransparentWater", handleRenderTransparentWaterChanged); + setting_setup_signal_listener(gSavedSettings, "SpellCheck", handleSpellCheckChanged); + setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged); + setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged); + setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged); + setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged); + + setting_setup_signal_listener(gSavedPerAccountSettings, "AvatarHoverOffsetZ", handleAvatarHoverOffsetChanged); } #if TEST_CACHED_CONTROL -- cgit v1.2.3 From 791b7ff0e99c40b9de1b542f1231d21faebada05 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 20 Jun 2022 17:06:55 +0300 Subject: SL-17585 Don't bother users with dialogs if we are already quiting --- doc/contributions.txt | 1 + indra/newview/installers/windows/installer_template.nsi | 3 +++ indra/newview/installers/windows/lang_de.nsi | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/doc/contributions.txt b/doc/contributions.txt index 0acf92b189..596cd4072e 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -1118,6 +1118,7 @@ Nicky Dasmijn SL-13141 SL-13642 SL-16438 + SL-17585 Nicky Perian OPEN-1 STORM-1087 diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 7d5d4fc16f..60e26274cb 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -365,6 +365,9 @@ IfErrors 0 INSTALL_FILES_DONE Goto INSTALL_FILES_DONE INSTALL_FILES_CANCEL: + # We are quiting, cleanup. + # Silence warnings from RemoveProgFilesOnInst. + StrCpy $SKIP_DIALOGS "true" Call RemoveProgFilesOnInst MessageBox MB_OK $(ErrorSecondLifeInstallSupport) Quit diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi index d9a5e90a78..7cc70e4c76 100755 --- a/indra/newview/installers/windows/lang_de.nsi +++ b/indra/newview/installers/windows/lang_de.nsi @@ -74,8 +74,8 @@ LangString CloseSecondLifeUnInstMB ${LANG_GERMAN} "Second Life kann nicht entfer LangString CheckNetworkConnectionDP ${LANG_GERMAN} "Prüfe Netzwerkverbindung..." ; error during installation -LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Second Life installer encountered issues during installation. Some files may not have been copied correctly." -LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." +LangString ErrorSecondLifeInstallRetry ${LANG_GERMAN} "Second Life konnte nicht korrekt installiert werden, einige Dateien wurden eventuell nicht korrekt von der Installationroutine kopiert." +LangString ErrorSecondLifeInstallSupport ${LANG_GERMAN} "Bitte laden Sie den Viewer erneut von https://secondlife.com/support/downloads/ und versuchen Sie die Installation erneut. Sollte das Problem weiterhin bestehen, dann kontaktieren Sie unseren Support unter https://support.secondlife.com." ; ask to remove user's data files LangString RemoveDataFilesMB ${LANG_GERMAN} "Möchten Sie alle anderen zu Second Life gehörigen Dateien ebenfalls ENTFERNEN?$\n$\nWir empfehlen, die Einstellungen und Cache-Dateien zu behalten, wenn Sie andere Versionen von Second Life installiert haben oder eine Deinstallation durchführen, um Second Life auf eine neuere Version zu aktualisieren." -- cgit v1.2.3 From 076a89506243e8d4037f34c2a78278ff6ee0f1f7 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 21 Jun 2022 17:55:29 +0300 Subject: SL-17635 remove unused variables --- indra/llmath/llvolume.cpp | 4 ---- indra/llmessage/lldatapacker.cpp | 6 ------ indra/llmessage/llthrottle.cpp | 2 -- indra/llprimitive/llmodel.cpp | 5 ----- indra/llui/lllayoutstack.cpp | 2 -- indra/llwindow/llwindowmacosx.cpp | 9 +-------- indra/newview/llfasttimerview.cpp | 14 -------------- indra/newview/llinventorymodel.cpp | 7 ++----- indra/newview/lllegacyatmospherics.cpp | 20 -------------------- indra/newview/llmeshrepository.cpp | 11 ----------- indra/newview/llmodelpreview.cpp | 5 ----- indra/newview/llpatchvertexarray.cpp | 2 -- indra/newview/llpresetsmanager.cpp | 2 -- indra/newview/llsceneview.cpp | 10 ---------- indra/newview/llviewertexturelist.cpp | 5 ++--- indra/newview/llvopartgroup.cpp | 6 ------ indra/newview/llvovolume.cpp | 10 ---------- indra/newview/llworld.cpp | 5 +---- 18 files changed, 6 insertions(+), 119 deletions(-) diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 5099920f32..3de5e04177 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -1624,9 +1624,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, //genNGon(params, llfloor(MIN_DETAIL_FACES * detail), 4.f, 0.f); genNGon(params, llfloor(MIN_DETAIL_FACES * detail)); - F32 t = 0.f; - F32 tStep = 1.0f / mPath.size(); - F32 toggle = 0.5f; for (S32 i=0;i<(S32)mPath.size();i++) { @@ -1635,7 +1632,6 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split, toggle = -0.5f; else toggle = 0.5f; - t += tStep; } } diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp index 96c1297e0d..b6adc102d2 100644 --- a/indra/llmessage/lldatapacker.cpp +++ b/indra/llmessage/lldatapacker.cpp @@ -127,13 +127,7 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, total_bits++; } - S32 min_val; U32 max_val; - if (is_signed) - { - min_val = 1 << int_bits; - min_val *= -1; - } max_val = 1 << int_bits; F32 fixed_val; diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp index 7605da4d3f..935af2aa5a 100644 --- a/indra/llmessage/llthrottle.cpp +++ b/indra/llmessage/llthrottle.cpp @@ -374,7 +374,6 @@ BOOL LLThrottleGroup::dynamicAdjust() } mDynamicAdjustTime = mt_sec; - S32 total = 0; // Update historical information for (i = 0; i < TC_EOF; i++) { @@ -391,7 +390,6 @@ BOOL LLThrottleGroup::dynamicAdjust() } mBitsSentThisPeriod[i] = 0; - total += ll_round(mBitsSentHistory[i]); } // Look for busy channels diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 204ff63712..cc85f3d7a8 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -881,8 +881,6 @@ LLSD LLModel::writeModel( LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BOOL as_slm) { - U32 bytes = 0; - std::string::size_type cur_offset = 0; LLSD header; @@ -904,7 +902,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO header["skin"]["offset"] = (LLSD::Integer) cur_offset; header["skin"]["size"] = (LLSD::Integer) size; cur_offset += size; - bytes += size; } } @@ -920,7 +917,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset; header["physics_convex"]["size"] = (LLSD::Integer) size; cur_offset += size; - bytes += size; } } @@ -942,7 +938,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite, BO header[model_names[i]]["offset"] = (LLSD::Integer) cur_offset; header[model_names[i]]["size"] = (LLSD::Integer) size; cur_offset += size; - bytes += size; } } diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index aac28e04b9..77938edf27 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -395,7 +395,6 @@ void LLLayoutStack::updateLayout() space_to_distribute += panelp ? ll_round((F32)mPanelSpacing * panelp->getVisibleAmount()) : 0; S32 remaining_space = space_to_distribute; - F32 fraction_distributed = 0.f; if (space_to_distribute > 0 && total_visible_fraction > 0.f) { // give space proportionally to visible auto resize panels BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) @@ -404,7 +403,6 @@ void LLLayoutStack::updateLayout() { F32 fraction_to_distribute = (panelp->mFractionalSize * panelp->getAutoResizeFactor()) / (total_visible_fraction); S32 delta = ll_round((F32)space_to_distribute * fraction_to_distribute); - fraction_distributed += fraction_to_distribute; panelp->mTargetDim += delta; remaining_space -= delta; } diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index bc4f07941b..5c8fd62d3b 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -621,8 +621,6 @@ void LLWindowMacOSX::getMouseDeltas(float* delta) BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits, BOOL fullscreen, BOOL enable_vsync) { - BOOL glNeedsInit = FALSE; - mFullscreen = fullscreen; if (mWindow == NULL) @@ -637,9 +635,6 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync); mContext = getCGLContextObj(mGLView); - // Since we just created the context, it needs to be set up. - glNeedsInit = TRUE; - gGLManager.mVRAM = getVramSize(mGLView); } @@ -1721,9 +1716,7 @@ void LLSplashScreenMacOSX::updateImpl(const std::string& mesg) { if(mWindow != NULL) { - CFStringRef string = NULL; - - string = CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8); + CFStringCreateWithCString(NULL, mesg.c_str(), kCFStringEncodingUTF8); } } diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp index 1605e4133d..9bb3bac104 100644 --- a/indra/newview/llfasttimerview.cpp +++ b/indra/newview/llfasttimerview.cpp @@ -504,20 +504,6 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t is.close(); } - //get time domain - LLSD::Real cur_total_time = 0.0; - - for (U32 i = 0; i < cur_data.size(); ++i) - { - cur_total_time += cur_data[i]["Total"]["Time"].asReal(); - } - - LLSD::Real base_total_time = 0.0; - for (U32 i = 0; i < base_data.size(); ++i) - { - base_total_time += base_data[i]["Total"]["Time"].asReal(); - } - //allocate raw scratch space LLPointer scratch = new LLImageRaw(1024, 512, 3); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 37500176ea..88cf89d4d4 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -3132,7 +3132,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32 gInventory.accountForUpdate(update); } - U32 changes = 0x0; if (account) { mask |= LLInventoryObserver::CREATE; @@ -3140,7 +3139,7 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account, U32 //as above, this loop never seems to loop more than once per call for (item_array_t::iterator it = items.begin(); it != items.end(); ++it) { - changes |= gInventory.updateItem(*it, mask); + gInventory.updateItem(*it, mask); } gInventory.notifyObservers(); gViewerWindow->getWindow()->decBusyCount(); @@ -4551,12 +4550,10 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore: } // as above, this loop never seems to loop more than once per call - U32 changes(0U); for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); ++it) { - changes |= gInventory.updateItem(*it); + gInventory.updateItem(*it); } - // *HUH: Have computed 'changes', nothing uses it. gInventory.notifyObservers(); gViewerWindow->getWindow()->decBusyCount(); diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp index 1364067949..ce4ec668f1 100644 --- a/indra/newview/lllegacyatmospherics.cpp +++ b/indra/newview/lllegacyatmospherics.cpp @@ -386,7 +386,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) return; } - const BOOL hide_clip_plane = TRUE; LLColor4 target_fog(0.f, 0.2f, 0.5f, 0.f); const F32 water_height = gAgent.getRegion() ? gAgent.getRegion()->getWaterHeight() : 0.f; @@ -472,33 +471,17 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) render_fog_color = sky_fog_color; - F32 fog_density = 0.f; fog_distance = mFogRatio * distance; if (camera_height > water_height) { LLColor4 fog(render_fog_color); mGLFogCol = fog; - - if (hide_clip_plane) - { - // For now, set the density to extend to the cull distance. - const F32 f_log = 2.14596602628934723963618357029f; // sqrt(fabs(log(0.01f))) - fog_density = f_log/fog_distance; - } - else - { - const F32 f_log = 4.6051701859880913680359829093687f; // fabs(log(0.01f)) - fog_density = (f_log)/fog_distance; - } } else { LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); F32 depth = water_height - camera_height; - - // get the water param manager variables - float water_fog_density = pwater->getModifiedWaterFogDensity(depth <= 0.0f); LLColor4 water_fog_color(pwater->getWaterFogColor()); @@ -512,9 +495,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in) // set the gl fog color mGLFogCol = fogCol; - - // set the density based on what the shaders use - fog_density = water_fog_density * gSavedSettings.getF32("WaterGLFogDensityScale"); } mFogColor = sky_fog_color; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index d28e929b48..92b062a51f 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2054,17 +2054,6 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_ if (volume->unpackVolumeFaces(stream, data_size)) { - //load volume faces into decomposition buffer - S32 vertex_count = 0; - S32 index_count = 0; - - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = volume->getVolumeFace(i); - vertex_count += face.mNumVertices; - index_count += face.mNumIndices; - } - d->mPhysicsShapeMesh.clear(); std::vector& pos = d->mPhysicsShapeMesh.mPositions; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index d012a9b328..d64f1a36f5 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -2583,8 +2583,6 @@ void LLModelPreview::clearBuffers() void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) { - U32 tri_count = 0; - U32 vertex_count = 0; U32 mesh_count = 0; @@ -2720,10 +2718,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) mVertexBuffer[lod][mdl].push_back(vb); - vertex_count += num_vertices; - tri_count += num_indices / 3; ++mesh_count; - } } } diff --git a/indra/newview/llpatchvertexarray.cpp b/indra/newview/llpatchvertexarray.cpp index 6e3e375488..a7011dfad5 100644 --- a/indra/newview/llpatchvertexarray.cpp +++ b/indra/newview/llpatchvertexarray.cpp @@ -69,11 +69,9 @@ void LLPatchVertexArray::create(U32 surface_width, U32 patch_width, F32 meters_p // (The -1 is there because an LLSurface has a buffer of 1 on // its East and North edges). U32 power_of_two = 1; - U32 surface_order = 0; while (power_of_two < (surface_width-1)) { power_of_two *= 2; - surface_order += 1; } if (power_of_two == (surface_width-1)) diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp index c267c3c699..30d0a22ef0 100644 --- a/indra/newview/llpresetsmanager.cpp +++ b/indra/newview/llpresetsmanager.cpp @@ -332,7 +332,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n else { ECameraPreset new_camera_preset = (ECameraPreset)gSavedSettings.getU32("CameraPresetType"); - bool new_camera_offsets = false; if (IS_CAMERA) { if (isDefaultCameraPreset(name)) @@ -354,7 +353,6 @@ bool LLPresetsManager::savePreset(const std::string& subdirectory, std::string n { new_camera_preset = CAMERA_PRESET_CUSTOM; } - new_camera_offsets = (!isDefaultCameraPreset(name) || (ECameraPreset)gSavedSettings.getU32("CameraPresetType") != new_camera_preset); } for (std::vector::iterator it = name_list.begin(); it != name_list.end(); ++it) { diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp index f7aa63e34d..e250f9bc7a 100644 --- a/indra/newview/llsceneview.cpp +++ b/indra/newview/llsceneview.cpp @@ -266,14 +266,11 @@ void LLSceneView::draw() U32 count = triangles[idx].size(); - U32 total = 0; - gGL.begin(LLRender::LINE_STRIP); //plot triangles for (U32 i = 0; i < count; ++i) { U32 tri_count = triangles[idx][i]; - total += tri_count; F32 y = (F32) (tri_count-tri_domain[0])/triangle_range*tri_rect.getHeight()+tri_rect.mBottom; F32 x = (F32) i / count * tri_rect.getWidth() + tri_rect.mLeft; @@ -290,15 +287,8 @@ void LLSceneView::draw() gGL.end(); gGL.flush(); - U32 total_visible = 0; count = visible_triangles[idx].size(); - for (U32 i = 0; i < count; ++i) - { - U32 tri_count = visible_triangles[idx][i]; - total_visible += tri_count; - } - std::string label = llformat("%s Object Triangle Counts (Ktris) -- Visible: %.2f/%.2f (%.2f KB Visible)", category[idx], total_visible_triangles[idx]/1024.f, total_triangles[idx]/1024.f, total_visible_bytes[idx]/1024.f); diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 208574f0a3..baca7b6648 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1148,15 +1148,14 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time) total_update_count--; } } - - S32 fetch_count = 0; + size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count)); S32 min_count = max_priority_count + min_update_count; for (entries_list_t::iterator iter3 = entries.begin(); iter3 != entries.end(); ) { LLViewerFetchedTexture* imagep = *iter3++; - fetch_count += (imagep->updateFetch() ? 1 : 0); + imagep->updateFetch(); if (min_count <= min_update_count) { mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType()); diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index 068e8a131d..f3affbeb33 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -845,9 +845,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater()); - U32 index_count = 0; - U32 vertex_count = 0; - group->clearDrawMap(); LLVertexBuffer* buffer = group->mVertexBuffer; @@ -913,9 +910,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) llassert(facep->getIndicesCount() == 6); - vertex_count += facep->getGeomCount(); - index_count += facep->getIndicesCount(); - S32 idx = draw_vec.size()-1; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f47fb6287c..832803ea6e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1748,16 +1748,6 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) } } - bool rigged = false; - - if (!isAnimatedObject()) - { - rigged = isRiggedMesh() && isAttachment(); - } - else - { - rigged = isRiggedMesh() && getControlAvatar() && getControlAvatar()->mPlaying; - } if (any_valid_boxes) { diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 8abb49fba8..aa32ef04b2 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -763,14 +763,13 @@ void LLWorld::updateParticles() void LLWorld::renderPropertyLines() { S32 region_count = 0; - S32 vertex_count = 0; for (region_list_t::iterator iter = mVisibleRegionList.begin(); iter != mVisibleRegionList.end(); ++iter) { LLViewerRegion* regionp = *iter; region_count++; - vertex_count += regionp->renderPropertyLines(); + regionp->renderPropertyLines(); } } @@ -778,7 +777,6 @@ void LLWorld::renderPropertyLines() void LLWorld::updateNetStats() { F64Bits bits; - U32 packets = 0; for (region_list_t::iterator iter = mActiveRegionList.begin(); iter != mActiveRegionList.end(); ++iter) @@ -786,7 +784,6 @@ void LLWorld::updateNetStats() LLViewerRegion* regionp = *iter; regionp->updateNetStats(); bits += regionp->mBitsReceived; - packets += llfloor( regionp->mPacketsReceived ); regionp->mBitsReceived = (F32Bits)0.f; regionp->mPacketsReceived = 0.f; } -- cgit v1.2.3 From dbe0cb58653b3199f6abcf640d38e8fb99b2e073 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 11 Apr 2022 10:36:13 -0700 Subject: SL-17021: Clean up some unneeded member variables from lloctree No performance difference measured --- indra/llmath/lloctree.h | 64 +++++++++++++++--------------------------- indra/newview/llvieweroctree.h | 1 - 2 files changed, 23 insertions(+), 42 deletions(-) diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index a9a54a8113..7e73fb6b57 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -85,8 +85,8 @@ public: typedef LLOctreeTraveler oct_traveler; typedef LLTreeTraveler tree_traveler; typedef std::vector< LLPointer > element_list; // note: don't remove the whitespace between "> >" - typedef LLPointer* element_iter; - typedef const LLPointer* const_element_iter; + typedef typename element_list::iterator element_iter; + typedef typename element_list::const_iterator const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; typedef LLOctreeNode** child_list; typedef LLOctreeNode** child_iter; @@ -108,9 +108,6 @@ public: mOctant(octant) { llassert(size[0] >= gOctreeMinSize*0.5f); - //always keep a NULL terminated list to avoid out of bounds exceptions in debug builds - mData.push_back(NULL); - mDataEnd = &mData[0]; mCenter = center; mSize = size; @@ -121,8 +118,6 @@ public: mOctant = ((oct_node*) mParent)->getOctant(mCenter); } - mElementCount = 0; - clearChildren(); } @@ -130,15 +125,14 @@ public: { BaseType::destroyListeners(); - for (U32 i = 0; i < mElementCount; ++i) + const U32 element_count = getElementCount(); + for (U32 i = 0; i < element_count; ++i) { mData[i]->setBinIndex(-1); mData[i] = NULL; } mData.clear(); - mData.push_back(NULL); - mDataEnd = &mData[0]; for (U32 i = 0; i < getChildCount(); i++) { @@ -238,14 +232,12 @@ public: void accept(oct_traveler* visitor) { visitor->visit(this); } virtual bool isLeaf() const { return mChildCount == 0; } - U32 getElementCount() const { return mElementCount; } - bool isEmpty() const { return mElementCount == 0; } - element_list& getData() { return mData; } - const element_list& getData() const { return mData; } - element_iter getDataBegin() { return &mData[0]; } - element_iter getDataEnd() { return mDataEnd; } - const_element_iter getDataBegin() const { return &mData[0]; } - const_element_iter getDataEnd() const { return mDataEnd; } + U32 getElementCount() const { return (U32)mData.size(); } + bool isEmpty() const { return mData.empty(); } + element_iter getDataBegin() { return mData.begin(); } + element_iter getDataEnd() { return mData.end(); } + const_element_iter getDataBegin() const { return mData.cbegin(); } + const_element_iter getDataEnd() const { return mData.cend(); } U32 getChildCount() const { return mChildCount; } oct_node* getChild(U32 index) { return mChild[index]; } @@ -326,11 +318,8 @@ public: if ((((getElementCount() < gOctreeMaxCapacity || getSize()[0] <= gOctreeMinSize) && contains(data->getBinRadius())) || (data->getBinRadius() > getSize()[0] && parent && parent->getElementCount() >= gOctreeMaxCapacity))) { //it belongs here - mData.push_back(NULL); - mData[mElementCount] = data; - mElementCount++; - mDataEnd = &mData[mElementCount]; - data->setBinIndex(mElementCount-1); + mData.push_back(data); + data->setBinIndex(getElementCount() - 1); BaseType::insert(data); return true; } @@ -366,11 +355,8 @@ public: if( lt == 0x7 ) { - mData.push_back(NULL); - mData[mElementCount] = data; - mElementCount++; - mDataEnd = &mData[mElementCount]; - data->setBinIndex(mElementCount-1); + mData.push_back(data); + data->setBinIndex(getElementCount() - 1); BaseType::insert(data); return true; } @@ -429,28 +415,25 @@ public: } void _remove(T* data, S32 i) - { //precondition -- mElementCount > 0, idx is in range [0, mElementCount) + { //precondition -- getElementCount() > 0, idx is in range [0, getElementCount()) - mElementCount--; data->setBinIndex(-1); - if (mElementCount > 0) + const U32 new_element_count = getElementCount() - 1; + if (new_element_count > 0) { - if (mElementCount != i) + if (new_element_count != i) { - mData[i] = mData[mElementCount]; //might unref data, do not access data after this point + mData[i] = mData[new_element_count]; //might unref data, do not access data after this point mData[i]->setBinIndex(i); } - mData[mElementCount] = NULL; + mData[new_element_count] = NULL; mData.pop_back(); - mDataEnd = &mData[mElementCount]; } else { mData.clear(); - mData.push_back(NULL); - mDataEnd = &mData[0]; } this->notifyRemoval(data); @@ -463,7 +446,7 @@ public: S32 i = data->getBinIndex(); - if (i >= 0 && i < mElementCount) + if (i >= 0 && i < getElementCount()) { if (mData[i] == data) { //found it @@ -506,7 +489,8 @@ public: void removeByAddress(T* data) { - for (U32 i = 0; i < mElementCount; ++i) + const U32 element_count = getElementCount(); + for (U32 i = 0; i < element_count; ++i) { if (mData[i] == data) { //we have data @@ -677,8 +661,6 @@ protected: U32 mChildCount; element_list mData; - element_iter mDataEnd; - U32 mElementCount; }; //just like a regular node, except it might expand on insert and compress on balance diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index e6974b0f84..29f3d8cba9 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -245,7 +245,6 @@ public: const LLVector4a* getObjectExtents() const {return mObjectExtents;} //octree wrappers to make code more readable - element_list& getData() { return mOctreeNode->getData(); } element_iter getDataBegin() { return mOctreeNode->getDataBegin(); } element_iter getDataEnd() { return mOctreeNode->getDataEnd(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } -- cgit v1.2.3 From 162280cd981b97ffef927553ec230cddcda878ce Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 12 Apr 2022 14:05:51 -0700 Subject: SL-17021: Templatize LLOctreeNode and related classes to allow for option to store elements in octrees as raw pointers. Use for faster allocation in LLVolumeFace::createOctree. --- indra/llmath/lloctree.h | 89 +++++++++++++++++++----------------- indra/llmath/llvolume.cpp | 21 ++++++--- indra/llmath/llvolume.h | 7 ++- indra/llmath/llvolumeoctree.cpp | 18 ++++---- indra/llmath/llvolumeoctree.h | 20 ++++---- indra/newview/llspatialpartition.cpp | 6 +-- indra/newview/llvieweroctree.h | 16 +++---- 7 files changed, 96 insertions(+), 81 deletions(-) diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 7e73fb6b57..318ee65cc0 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -48,52 +48,59 @@ extern float gOctreeMinSize; #define LL_OCTREE_MAX_CAPACITY 128 #endif*/ -template class LLOctreeNode; - -template +// T is the type of the element referenced by the octree node. +// T_PTR determines how pointers to elements are stored internally. +// LLOctreeNode> assumes ownership of inserted elements and +// deletes elements removed from the tree. +// LLOctreeNode doesn't take ownership of inserted elements, so the API +// user is responsible for managing the storage lifecycle of elements added to +// the tree. +template class LLOctreeNode; + +template class LLOctreeListener: public LLTreeListener { public: typedef LLTreeListener BaseType; - typedef LLOctreeNode oct_node; + typedef LLOctreeNode oct_node; virtual void handleChildAddition(const oct_node* parent, oct_node* child) = 0; virtual void handleChildRemoval(const oct_node* parent, const oct_node* child) = 0; }; -template +template class LLOctreeTraveler { public: - virtual void traverse(const LLOctreeNode* node); - virtual void visit(const LLOctreeNode* branch) = 0; + virtual void traverse(const LLOctreeNode* node); + virtual void visit(const LLOctreeNode* branch) = 0; }; -template -class LLOctreeTravelerDepthFirst : public LLOctreeTraveler +template +class LLOctreeTravelerDepthFirst : public LLOctreeTraveler { public: - virtual void traverse(const LLOctreeNode* node) override; + virtual void traverse(const LLOctreeNode* node) override; }; -template +template class alignas(16) LLOctreeNode : public LLTreeNode { LL_ALIGN_NEW public: - typedef LLOctreeTraveler oct_traveler; - typedef LLTreeTraveler tree_traveler; - typedef std::vector< LLPointer > element_list; // note: don't remove the whitespace between "> >" + typedef LLOctreeTraveler oct_traveler; + typedef LLTreeTraveler tree_traveler; + typedef std::vector element_list; typedef typename element_list::iterator element_iter; typedef typename element_list::const_iterator const_element_iter; typedef typename std::vector*>::iterator tree_listener_iter; - typedef LLOctreeNode** child_list; - typedef LLOctreeNode** child_iter; + typedef LLOctreeNode** child_list; + typedef LLOctreeNode** child_iter; - typedef LLTreeNode BaseType; - typedef LLOctreeNode oct_node; - typedef LLOctreeListener oct_listener; + typedef LLTreeNode BaseType; + typedef LLOctreeNode oct_node; + typedef LLOctreeListener oct_listener; enum { @@ -255,7 +262,7 @@ public: U8 idx = mChildMap[i]; if (idx != NO_CHILD_NODES) { - LLOctreeNode* child = mChild[idx]; + oct_node* child = mChild[idx]; if (child->getOctant() != i) { @@ -273,7 +280,7 @@ public: oct_node* getNodeAt(const LLVector4a& pos, const F32& rad) { - LLOctreeNode* node = this; + oct_node* node = this; if (node->isInside(pos, rad)) { @@ -295,7 +302,7 @@ public: } else if (!node->contains(rad) && node->getParent()) { //if we got here, data does not exist in this node - return ((LLOctreeNode*) node->getParent())->getNodeAt(pos, rad); + return ((oct_node*) node->getParent())->getNodeAt(pos, rad); } return node; @@ -310,7 +317,7 @@ public: OCT_ERRS << "!!! INVALID ELEMENT ADDED TO OCTREE BRANCH !!!" << LL_ENDL; return false; } - LLOctreeNode* parent = getOctParent(); + oct_node* parent = getOctParent(); //is it here? if (isInside(data->getPositionGroup())) @@ -343,7 +350,7 @@ public: size.mul(0.5f); //push center in direction of data - LLOctreeNode::pushCenter(center, size, data); + oct_node::pushCenter(center, size, data); // handle case where floating point number gets too small LLVector4a val; @@ -382,7 +389,7 @@ public: llassert(size[0] >= gOctreeMinSize*0.5f); //make the new kid - child = new LLOctreeNode(center, size, this); + child = new oct_node(center, size, this); addChild(child); child->insert(data); @@ -502,7 +509,7 @@ public: for (U32 i = 0; i < getChildCount(); i++) { //we don't contain data, so pass this guy down - LLOctreeNode* child = (LLOctreeNode*) getChild(i); + oct_node* child = (oct_node*) getChild(i); child->removeByAddress(data); } } @@ -656,7 +663,7 @@ protected: oct_node* mParent; U8 mOctant; - LLOctreeNode* mChild[8]; + oct_node* mChild[8]; U8 mChildMap[8]; U32 mChildCount; @@ -664,12 +671,12 @@ protected: }; //just like a regular node, except it might expand on insert and compress on balance -template -class LLOctreeRoot : public LLOctreeNode +template +class LLOctreeRoot : public LLOctreeNode { public: - typedef LLOctreeNode BaseType; - typedef LLOctreeNode oct_node; + typedef LLOctreeNode BaseType; + typedef LLOctreeNode oct_node; LLOctreeRoot(const LLVector4a& center, const LLVector4a& size, @@ -750,7 +757,7 @@ public: oct_node* node = this->getNodeAt(data); if (node == this) { - LLOctreeNode::insert(data); + oct_node::insert(data); } else if (node->isInside(data->getPositionGroup())) { @@ -770,13 +777,13 @@ public: LLVector4a center, size; center = this->getCenter(); size = this->getSize(); - LLOctreeNode::pushCenter(center, size, data); + oct_node::pushCenter(center, size, data); this->setCenter(center); size.mul(2.f); this->setSize(size); this->updateMinMax(); } - LLOctreeNode::insert(data); + oct_node::insert(data); } else { @@ -788,7 +795,7 @@ public: //expand this node LLVector4a newcenter(center); - LLOctreeNode::pushCenter(newcenter, size, data); + oct_node::pushCenter(newcenter, size, data); this->setCenter(newcenter); LLVector4a size2 = size; size2.mul(2.f); @@ -798,11 +805,11 @@ public: llassert(size[0] >= gOctreeMinSize); //copy our children to a new branch - LLOctreeNode* newnode = new LLOctreeNode(center, size, this); + oct_node* newnode = new oct_node(center, size, this); for (U32 i = 0; i < this->getChildCount(); i++) { - LLOctreeNode* child = this->getChild(i); + oct_node* child = this->getChild(i); newnode->addChild(child); } @@ -828,8 +835,8 @@ public: //======================== // LLOctreeTraveler //======================== -template -void LLOctreeTraveler::traverse(const LLOctreeNode* node) +template +void LLOctreeTraveler::traverse(const LLOctreeNode* node) { node->accept(this); for (U32 i = 0; i < node->getChildCount(); i++) @@ -838,8 +845,8 @@ void LLOctreeTraveler::traverse(const LLOctreeNode* node) } } -template -void LLOctreeTravelerDepthFirst::traverse(const LLOctreeNode* node) +template +void LLOctreeTravelerDepthFirst::traverse(const LLOctreeNode* node) { for (U32 i = 0; i < node->getChildCount(); i++) { diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 3de5e04177..414e96f67a 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -370,7 +370,7 @@ BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, cons } } -class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst +class LLVolumeOctreeRebound : public LLOctreeTravelerDepthFirst { public: const LLVolumeFace* mFace; @@ -380,7 +380,7 @@ public: mFace = face; } - virtual void visit(const LLOctreeNode* branch) + virtual void visit(const LLOctreeNode* branch) { //this is a depth first traversal, so it's safe to assum all children have complete //bounding data LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME @@ -398,8 +398,7 @@ public: min = *(tri->mV[0]); max = *(tri->mV[0]); - for (LLOctreeNode::const_element_iter iter = - branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) + for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { //for each triangle in node //stretch by triangles in node @@ -4874,6 +4873,8 @@ void LLVolumeFace::freeData() delete mOctree; mOctree = NULL; + mOctreeTriangles.clear(); + mOctreeTriangles.shrink_to_fit(); } BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) @@ -4883,6 +4884,8 @@ BOOL LLVolumeFace::create(LLVolume* volume, BOOL partial_build) //tree for this face is no longer valid delete mOctree; mOctree = NULL; + mOctreeTriangles.clear(); + mOctreeTriangles.shrink_to_fit(); LL_CHECK_MEMORY BOOL ret = FALSE ; @@ -5556,12 +5559,18 @@ void LLVolumeFace::createOctree(F32 scaler, const LLVector4a& center, const LLVe return; } - mOctree = new LLOctreeRoot(center, size, NULL); + mOctree = new LLOctreeRoot(center, size, NULL); new LLVolumeOctreeListener(mOctree); + // Clear old triangles, but keep the underlying storage pointer + mOctreeTriangles.clear(); + const U32 num_triangles = mNumIndices / 3; + // Initialize all the triangles we need + mOctreeTriangles.resize(num_triangles); for (U32 i = 0; i < mNumIndices; i+= 3) { //for each triangle - LLPointer tri = new LLVolumeTriangle(); + const U32 triangle_index = i / 3; + LLVolumeTriangle* tri = &mOctreeTriangles[triangle_index]; const LLVector4a& v0 = mPositions[mIndices[i]]; const LLVector4a& v1 = mPositions[mIndices[i+1]]; diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index c0b224b1ff..da155c7b41 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -35,7 +35,8 @@ class LLVolumeParams; class LLProfile; class LLPath; -template class LLOctreeNode; +template class LLPointer; +template class LLOctreeNode; class LLVolumeFace; class LLVolume; @@ -974,7 +975,9 @@ public: // vertices per joint. LLJointRiggingInfoTab mJointRiggingInfoTab; - LLOctreeNode* mOctree; + // This octree stores raw pointer references to triangles in mOctreeTriangles + LLOctreeNode* mOctree; + std::vector mOctreeTriangles; //whether or not face has been cache optimized BOOL mOptimized; diff --git a/indra/llmath/llvolumeoctree.cpp b/indra/llmath/llvolumeoctree.cpp index fb232d5f6c..6894d04d3c 100644 --- a/indra/llmath/llvolumeoctree.cpp +++ b/indra/llmath/llvolumeoctree.cpp @@ -75,7 +75,7 @@ BOOL LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end, c } -LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode* node) +LLVolumeOctreeListener::LLVolumeOctreeListener(LLOctreeNode* node) { node->addListener(this); } @@ -85,13 +85,12 @@ LLVolumeOctreeListener::~LLVolumeOctreeListener() } -void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode* parent, - LLOctreeNode* child) +void LLVolumeOctreeListener::handleChildAddition(const LLOctreeNode* parent, + LLOctreeNode* child) { new LLVolumeOctreeListener(child); } - LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& start, const LLVector4a& dir, const LLVolumeFace* face, F32* closest_t, LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent) @@ -108,7 +107,7 @@ LLOctreeTriangleRayIntersect::LLOctreeTriangleRayIntersect(const LLVector4a& sta mEnd.setAdd(mStart, mDir); } -void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode* node) +void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode* node) { LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) node->getListener(0); @@ -122,9 +121,9 @@ void LLOctreeTriangleRayIntersect::traverse(const LLOctreeNode } } -void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode* node) +void LLOctreeTriangleRayIntersect::visit(const LLOctreeNode* node) { - for (LLOctreeNode::const_element_iter iter = + for (typename LLOctreeNode::const_element_iter iter = node->getDataBegin(); iter != node->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; @@ -219,7 +218,7 @@ const F32& LLVolumeTriangle::getBinRadius() const //TEST CODE -void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) +void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) { LLVolumeOctreeListener* node = (LLVolumeOctreeListener*) branch->getListener(0); @@ -256,7 +255,7 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) } //children fit, check data - for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); + for (typename LLOctreeNode::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { const LLVolumeTriangle* tri = *iter; @@ -273,4 +272,3 @@ void LLVolumeOctreeValidate::visit(const LLOctreeNode* branch) } } - diff --git a/indra/llmath/llvolumeoctree.h b/indra/llmath/llvolumeoctree.h index b2bc440368..d65bca5e52 100644 --- a/indra/llmath/llvolumeoctree.h +++ b/indra/llmath/llvolumeoctree.h @@ -77,11 +77,11 @@ public: }; -class alignas(16) LLVolumeOctreeListener : public LLOctreeListener +class alignas(16) LLVolumeOctreeListener : public LLOctreeListener { LL_ALIGN_NEW public: - LLVolumeOctreeListener(LLOctreeNode* node); + LLVolumeOctreeListener(LLOctreeNode* node); ~LLVolumeOctreeListener(); LLVolumeOctreeListener(const LLVolumeOctreeListener& rhs) @@ -96,11 +96,9 @@ public: } //LISTENER FUNCTIONS - virtual void handleChildAddition(const LLOctreeNode* parent, - LLOctreeNode* child); + virtual void handleChildAddition(const LLOctreeNode* parent, LLOctreeNode* child); virtual void handleStateChange(const LLTreeNode* node) { } - virtual void handleChildRemoval(const LLOctreeNode* parent, - const LLOctreeNode* child) { } + virtual void handleChildRemoval(const LLOctreeNode* parent, const LLOctreeNode* child) { } virtual void handleInsertion(const LLTreeNode* node, LLVolumeTriangle* tri) { } virtual void handleRemoval(const LLTreeNode* node, LLVolumeTriangle* tri) { } virtual void handleDestruction(const LLTreeNode* node) { } @@ -111,7 +109,7 @@ public: LL_ALIGN_16(LLVector4a mExtents[2]); // extents (min, max) of this node and all its children }; -class LLOctreeTriangleRayIntersect : public LLOctreeTraveler +class LLOctreeTriangleRayIntersect : public LLOctreeTraveler { public: const LLVolumeFace* mFace; @@ -129,14 +127,14 @@ public: const LLVolumeFace* face, F32* closest_t, LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent); - void traverse(const LLOctreeNode* node); + void traverse(const LLOctreeNode* node); - virtual void visit(const LLOctreeNode* node); + virtual void visit(const LLOctreeNode* node); }; -class LLVolumeOctreeValidate : public LLOctreeTraveler +class LLVolumeOctreeValidate : public LLOctreeTraveler { - virtual void visit(const LLOctreeNode* branch); + virtual void visit(const LLOctreeNode* branch); }; #endif diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index c16a1854be..9cfbe99df4 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -3087,7 +3087,7 @@ public: } - void visit(const LLOctreeNode* branch) + void visit(const LLOctreeNode* branch) { LLVolumeOctreeListener* vl = (LLVolumeOctreeListener*) branch->getListener(0); @@ -3129,7 +3129,7 @@ public: } gGL.begin(LLRender::TRIANGLES); - for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); + for (LLOctreeNode::const_element_iter iter = branch->getDataBegin(); iter != branch->getDataEnd(); ++iter) { @@ -3846,7 +3846,7 @@ BOOL LLSpatialPartition::isVisible(const LLVector3& v) } LL_ALIGN_PREFIX(16) -class LLOctreeIntersect : public LLOctreeTraveler +class LLOctreeIntersect : public LLOctreeTraveler> { public: LL_ALIGN_16(LLVector4a mStart); diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h index 29f3d8cba9..7666062f99 100644 --- a/indra/newview/llvieweroctree.h +++ b/indra/newview/llvieweroctree.h @@ -45,11 +45,11 @@ class LLViewerOctreeGroup; class LLViewerOctreeEntry; class LLViewerOctreePartition; -typedef LLOctreeListener OctreeListener; -typedef LLTreeNode TreeNode; -typedef LLOctreeNode OctreeNode; -typedef LLOctreeRoot OctreeRoot; -typedef LLOctreeTraveler OctreeTraveler; +typedef LLOctreeListener> OctreeListener; +typedef LLTreeNode TreeNode; +typedef LLOctreeNode> OctreeNode; +typedef LLOctreeRoot> OctreeRoot; +typedef LLOctreeTraveler> OctreeTraveler; #if LL_OCTREE_PARANOIA_CHECK #define assert_octree_valid(x) x->validate() @@ -179,7 +179,7 @@ protected: //defines an octree group for an octree node, which contains multiple entries. //LL_ALIGN_PREFIX(16) class LLViewerOctreeGroup -: public LLOctreeListener +: public OctreeListener { LL_ALIGN_NEW friend class LLViewerOctreeCull; @@ -198,8 +198,8 @@ public: }; public: - typedef LLOctreeNode::element_iter element_iter; - typedef LLOctreeNode::element_list element_list; + typedef OctreeNode::element_iter element_iter; + typedef OctreeNode::element_list element_list; LLViewerOctreeGroup(OctreeNode* node); LLViewerOctreeGroup(const LLViewerOctreeGroup& rhs) -- cgit v1.2.3 From 916da8cfb8b394239c523ee9b70c698dabb4ba98 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 19 Apr 2022 17:29:15 -0700 Subject: SL-17021: Fix triangle mesh overlays being generated twice when avatar animation is frozen --- indra/newview/llvovolume.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 832803ea6e..89056c64bb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4852,7 +4852,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons if (is_paused) { S32 frames_paused = LLFrameTimer::getFrameCount() - avatar->getMotionController().getPausedFrame(); - if (frames_paused > 2) + if (frames_paused > 1) { return; } -- cgit v1.2.3 From 0a08645eb6a86a3279beb925ebba88393bb89936 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Apr 2022 10:25:05 -0700 Subject: SL-17021: Do not do software skinning/octree building of a face during picking unless eligible for narrow-phase intersect check (fast broad-phase intersect pre-check not yet implemented) --- indra/newview/llvovolume.cpp | 28 +++++++++++++++++++++++----- indra/newview/llvovolume.h | 7 +++++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 89056c64bb..fce233969b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4585,7 +4585,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& { if ((pick_rigged) || (getAvatar() && (getAvatar()->isSelf()) && (LLFloater::isVisible(gFloaterTools)))) { - updateRiggedVolume(true); + updateRiggedVolume(true, LLRiggedVolume::DO_NOT_UPDATE_FACES); volume = mRiggedVolume; transform = false; } @@ -4660,6 +4660,7 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& continue; } + updateRiggedVolume(true, i); face_hit = volume->lineSegmentIntersect(local_start, local_end, i, &p, &tc, &n, &tn); @@ -4783,7 +4784,7 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update) +void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. @@ -4818,10 +4819,10 @@ void LLVOVolume::updateRiggedVolume(bool force_update) updateRelativeXform(); } - mRiggedVolume->update(skin, avatar, volume); + mRiggedVolume->update(skin, avatar, volume, face_index); } -void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume) +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool copy = false; @@ -4871,7 +4872,24 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons S32 rigged_vert_count = 0; S32 rigged_face_count = 0; LLVector4a box_min, box_max; - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + S32 face_begin; + S32 face_end; + if (face_index == DO_NOT_UPDATE_FACES) + { + face_begin = 0; + face_end = 0; + } + else if (face_index == UPDATE_ALL_FACES) + { + face_begin = 0; + face_end = volume->getNumVolumeFaces(); + } + else + { + face_begin = face_index; + face_end = face_begin + 1; + } + for (S32 i = face_begin; i < face_end; ++i) { const LLVolumeFace& vol_face = volume->getVolumeFace(i); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 4cb7a5481c..00a0a1dfd0 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -65,7 +65,10 @@ public: { } - void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume); + using FaceIndex = S32; + static const FaceIndex UPDATE_ALL_FACES = -1; + static const FaceIndex DO_NOT_UPDATE_FACES = -2; + void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES); std::string mExtraDebugText; }; @@ -363,7 +366,7 @@ public: //rigged volume update (for raycasting) - void updateRiggedVolume(bool force_update = false); + void updateRiggedVolume(bool force_update = false, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES); LLRiggedVolume* getRiggedVolume(); //returns true if volume should be treated as a rigged volume -- cgit v1.2.3 From 1d3b85356f516fa2f5a5d49572743dc2a03ac86a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Apr 2022 16:19:42 -0700 Subject: SL-17021: Only calculate the octree for a skinned mesh if intersection falls inside an on-the-fly calculated bounding box. Technically not a broadphase check, but better than calculating an octree for a bunch of meshes. --- indra/newview/llvovolume.cpp | 17 ++++++++--------- indra/newview/llvovolume.h | 7 ++++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index fce233969b..6a53e704c3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4660,7 +4660,9 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& continue; } - updateRiggedVolume(true, i); + // This calculates the bounding box of the skinned mesh from scratch. It's actually quite expensive, but not nearly as expensive as building a full octree. + // rebuild_face_octrees = false because an octree for this face will be built later only if needed for narrow phase picking. + updateRiggedVolume(true, i, false); face_hit = volume->lineSegmentIntersect(local_start, local_end, i, &p, &tc, &n, &tn); @@ -4784,7 +4786,7 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index) +void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. @@ -4819,10 +4821,10 @@ void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex updateRelativeXform(); } - mRiggedVolume->update(skin, avatar, volume, face_index); + mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees); } -void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index) +void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; bool copy = false; @@ -4974,15 +4976,12 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons } + if (rebuild_face_octrees) { delete dst_face.mOctree; dst_face.mOctree = NULL; - LLVector4a size; - size.setSub(dst_face.mExtents[1], dst_face.mExtents[0]); - size.splat(size.getLength3().getF32()*0.5f); - - dst_face.createOctree(1.f); + dst_face.createOctree(); } } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 00a0a1dfd0..f0213848c6 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -68,7 +68,7 @@ public: using FaceIndex = S32; static const FaceIndex UPDATE_ALL_FACES = -1; static const FaceIndex DO_NOT_UPDATE_FACES = -2; - void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES); + void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES, bool rebuild_face_octrees = true); std::string mExtraDebugText; }; @@ -365,8 +365,9 @@ public: S32 getMDCImplCount() { return mMDCImplCount; } - //rigged volume update (for raycasting) - void updateRiggedVolume(bool force_update = false, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES); + // Rigged volume update (for raycasting) + // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting + void updateRiggedVolume(bool force_update = false, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true); LLRiggedVolume* getRiggedVolume(); //returns true if volume should be treated as a rigged volume -- cgit v1.2.3 From b97aec0da2e1ec97a8bfd408bdce61d91b4fcdab Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Apr 2022 17:40:44 -0700 Subject: SL-17021: Change meaning of first argument to LLVOVolume::updateRiggedVolume from 'force_update' to 'foce_treat_as_rigged' --- indra/newview/llvovolume.cpp | 10 +++++----- indra/newview/llvovolume.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 6a53e704c3..5440159eb3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1691,7 +1691,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global) // updates needed, set REBUILD_RIGGED accordingly. // Without the flag, this will remove unused rigged volumes, which we are not currently very aggressive about. - updateRiggedVolume(); + updateRiggedVolume(false); } LLVolume* volume = mRiggedVolume; @@ -1983,7 +1983,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable) if (mDrawable->isState(LLDrawable::REBUILD_RIGGED)) { - updateRiggedVolume(); + updateRiggedVolume(false); genBBoxes(FALSE); mDrawable->clearState(LLDrawable::REBUILD_RIGGED); } @@ -4786,13 +4786,13 @@ void LLVOVolume::clearRiggedVolume() } } -void LLVOVolume::updateRiggedVolume(bool force_update, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) +void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index, bool rebuild_face_octrees) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; //Update mRiggedVolume to match current animation frame of avatar. //Also update position/size in octree. - if ((!force_update) && (!treatAsRigged())) + if ((!force_treat_as_rigged) && (!treatAsRigged())) { clearRiggedVolume(); @@ -5916,7 +5916,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) else { drawablep->clearState(LLDrawable::RIGGED); - vobj->updateRiggedVolume(); + vobj->updateRiggedVolume(false); } } } diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index f0213848c6..64514c51b0 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -367,7 +367,7 @@ public: // Rigged volume update (for raycasting) // By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting - void updateRiggedVolume(bool force_update = false, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true); + void updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true); LLRiggedVolume* getRiggedVolume(); //returns true if volume should be treated as a rigged volume -- cgit v1.2.3 From 1167ea994c44a2c45f68109325ae1862b0ca09c3 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Wed, 22 Jun 2022 18:00:49 +0300 Subject: SL-17634 Replace deprecated carbon Gestalt calls --- doc/contributions.txt | 1 + indra/llcommon/CMakeLists.txt | 11 ++++---- indra/llcommon/llsys.cpp | 21 ++------------ indra/llcommon/llsys_objc.h | 33 ++++++++++++++++++++++ indra/llcommon/llsys_objc.mm | 64 +++++++++++++++++++++++++++++++++++++++++++ indra/newview/CMakeLists.txt | 2 ++ 6 files changed, 108 insertions(+), 24 deletions(-) create mode 100644 indra/llcommon/llsys_objc.h create mode 100644 indra/llcommon/llsys_objc.mm diff --git a/doc/contributions.txt b/doc/contributions.txt index 596cd4072e..04958bb321 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -400,6 +400,7 @@ Cinder Roxley STORM-2127 STORM-2144 SL-3404 + SL-17634 Clara Young Coaldust Numbers VWR-1095 diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index ca8b5e946f..fd8fbf70c8 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -265,6 +265,11 @@ set(llcommon_HEADER_FILES workqueue.h StackWalker.h ) + +if (DARWIN) + list(APPEND llcommon_HEADER_FILES llsys_objc.h) + list(APPEND llcommon_SOURCE_FILES llsys_objc.mm) +endif (DARWIN) set_source_files_properties(${llcommon_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE) @@ -312,12 +317,6 @@ target_link_libraries( ${TRACY_LIBRARY} ) -if (DARWIN) - include(CMakeFindFrameworks) - find_library(CARBON_LIBRARY Carbon) - target_link_libraries(llcommon ${CARBON_LIBRARY}) -endif (DARWIN) - add_dependencies(llcommon stage_third_party_libs) if (LL_TESTS) diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index f717b2cf34..6d0483903b 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -64,6 +64,7 @@ using namespace llsd; # include // GetPerformanceInfo() et al. # include #elif LL_DARWIN +# include "llsys_objc.h" # include # include # include @@ -74,12 +75,6 @@ using namespace llsd; # include # include # include - -// disable warnings about Gestalt calls being deprecated -// until Apple get's on the ball and provides an alternative -// -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - #elif LL_LINUX # include # include @@ -278,12 +273,9 @@ LLOSInfo::LLOSInfo() : { const char * DARWIN_PRODUCT_NAME = "Mac OS X"; - SInt32 major_version, minor_version, bugfix_version; - OSErr r1 = Gestalt(gestaltSystemVersionMajor, &major_version); - OSErr r2 = Gestalt(gestaltSystemVersionMinor, &minor_version); - OSErr r3 = Gestalt(gestaltSystemVersionBugFix, &bugfix_version); + S32 major_version, minor_version, bugfix_version = 0; - if((r1 == noErr) && (r2 == noErr) && (r3 == noErr)) + if (LLGetDarwinOSInfo(major_version, minor_version, bugfix_version)) { mMajorVer = major_version; mMinorVer = minor_version; @@ -1315,10 +1307,3 @@ BOOL gzip_file(const std::string& srcfile, const std::string& dstfile) if (dst != NULL) gzclose(dst); return retval; } - -#if LL_DARWIN -// disable warnings about Gestalt calls being deprecated -// until Apple get's on the ball and provides an alternative -// -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" -#endif diff --git a/indra/llcommon/llsys_objc.h b/indra/llcommon/llsys_objc.h new file mode 100644 index 0000000000..35599a574b --- /dev/null +++ b/indra/llcommon/llsys_objc.h @@ -0,0 +1,33 @@ +/** + * @file llsys_objc.h + * @brief Header file for llsys_objc.mm + * + * $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$ + */ + +#ifndef LL_LLSYS_OBJC_H +#define LL_LLSYS_OBJC_H + +bool LLGetDarwinOSInfo(int &major, int &minor, int &patch); + + +#endif // LL_LLSYS_OBJC_H diff --git a/indra/llcommon/llsys_objc.mm b/indra/llcommon/llsys_objc.mm new file mode 100644 index 0000000000..cdb1e320d5 --- /dev/null +++ b/indra/llcommon/llsys_objc.mm @@ -0,0 +1,64 @@ +/** + * @file llsys_objc.mm + * @brief obj-c implementation of the system information functions + * + * $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$ + */ + +#import "llsys_objc.h" +#import + +static int intAtStringIndex(NSArray *array, int index) +{ + return [(NSString *)[array objectAtIndex:index] integerValue]; +} + +bool LLGetDarwinOSInfo(int &major, int &minor, int &patch) +{ + if (NSAppKitVersionNumber > NSAppKitVersionNumber10_8) + { + NSOperatingSystemVersion osVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; + major = osVersion.majorVersion; + minor = osVersion.minorVersion; + patch = osVersion.patchVersion; + } + else + { + NSString* versionString = [[NSDictionary dictionaryWithContentsOfFile: + @"/System/Library/CoreServices/SystemVersion.plist"] objectForKey:@"ProductVersion"]; + NSArray* versions = [versionString componentsSeparatedByString:@"."]; + NSUInteger count = [versions count]; + if (count > 0) + { + major = intAtStringIndex(versions, 0); + if (count > 1) + { + minor = intAtStringIndex(versions, 1); + if (count > 2) + { + patch = intAtStringIndex(versions, 2); + } + } + } + } + return true; +} diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 964615320d..ae8d8d51a4 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1413,12 +1413,14 @@ if (DARWIN) find_library(COCOA_LIBRARY Cocoa) find_library(IOKIT_LIBRARY IOKit) find_library(COREAUDIO_LIBRARY CoreAudio) + find_library(CARBON_LIBRARY Carbon) set(viewer_LIBRARIES ${COCOA_LIBRARY} ${AGL_LIBRARY} ${IOKIT_LIBRARY} ${COREAUDIO_LIBRARY} + ${CARBON_LIBRARY} ) if (USE_BUGSPLAT) -- cgit v1.2.3 From b7ff4d316d646ffbcdfda3c8539d45433c55c5c9 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 23 May 2022 16:29:39 -0700 Subject: SL-17329: Add advanced developer menu button to purge the disk cache --- indra/newview/llviewermenu.cpp | 30 ++++++++++++++++++++++ indra/newview/skins/default/xui/en/menu_viewer.xml | 12 +++++++++ 2 files changed, 42 insertions(+) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 5b300e96c6..78783de6ac 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -53,6 +53,7 @@ #include "llcompilequeue.h" #include "llconsole.h" #include "lldebugview.h" +#include "lldiskcache.h" #include "llenvironment.h" #include "llfilepicker.h" #include "llfirstuse.h" @@ -2088,6 +2089,32 @@ class LLAdvancedDropPacket : public view_listener_t } }; +////////////////////// +// PURGE DISK CACHE // +////////////////////// + + +class LLAdvancedPurgeDiskCache : public view_listener_t +{ + bool handleEvent(const LLSD& userdata) + { + LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); + LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); + llassert_always(main_queue); + llassert_always(general_queue); + main_queue->postTo( + general_queue, + []() // Work done on general queue + { + LLDiskCache::getInstance()->purge(); + // Nothing needed to return + }, + [](){}); // Callback to main thread is empty as there is nothing left to do + + return true; + } +}; + //////////////////// // EVENT Recorder // @@ -9350,6 +9377,9 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog"); view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket"); + // Advanced > Cache + view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache"); + // Advanced > Recorder view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot"); view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop"); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index 8d7cfe1116..cb3bbcfba0 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3326,6 +3326,18 @@ function="World.EnvPreset" function="Advanced.DropPacket" />
+ + + + + -- cgit v1.2.3 From ccdeac322351f9ae60dc7955ff8b3db30dba5b77 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 23 May 2022 17:37:21 -0700 Subject: SL-17329: Do logging of individual files after the disk cache purge finishes so it doesn't affect the time measurement. The time resolution of the debug log is in seconds, so it's not particularly useful. Arguably, one could remove this fine logging in favor of Tracy markers. Or have both. Depends on the use case. --- indra/llfilesystem/lldiskcache.cpp | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp index ee43a599f7..74955df50a 100644 --- a/indra/llfilesystem/lldiskcache.cpp +++ b/indra/llfilesystem/lldiskcache.cpp @@ -131,28 +131,45 @@ void LLDiskCache::purge() LL_INFOS() << "Purging cache to a maximum of " << mMaxSizeBytes << " bytes" << LL_ENDL; + std::vector file_removed; + if (mEnableCacheDebugInfo) + { + file_removed.reserve(file_info.size()); + } uintmax_t file_size_total = 0; for (file_info_t& entry : file_info) { file_size_total += entry.second.first; + bool should_remove = file_size_total > mMaxSizeBytes; + if (mEnableCacheDebugInfo) + { + file_removed.push_back(should_remove); + } std::string action = ""; - if (file_size_total > mMaxSizeBytes) + if (should_remove) { - action = "DELETE:"; boost::filesystem::remove(entry.second.second, ec); if (ec.failed()) { LL_WARNS() << "Failed to delete cache file " << entry.second.second << ": " << ec.message() << LL_ENDL; } } - else - { - action = " KEEP:"; - } + } - if (mEnableCacheDebugInfo) + if (mEnableCacheDebugInfo) + { + auto end_time = std::chrono::high_resolution_clock::now(); + auto execute_time = std::chrono::duration_cast(end_time - start_time).count(); + + // Log afterward so it doesn't affect the time measurement + // Logging thousands of file results can take hundreds of milliseconds + for (size_t i = 0; i < file_info.size(); ++i) { + const file_info_t& entry = file_info[i]; + const bool removed = file_removed[i]; + const std::string action = removed ? "DELETE:" : "KEEP:"; + // have to do this because of LL_INFO/LL_END weirdness std::ostringstream line; @@ -163,12 +180,7 @@ void LLDiskCache::purge() line << " (" << file_size_total << "/" << mMaxSizeBytes << ")"; LL_INFOS() << line.str() << LL_ENDL; } - } - if (mEnableCacheDebugInfo) - { - auto end_time = std::chrono::high_resolution_clock::now(); - auto execute_time = std::chrono::duration_cast(end_time - start_time).count(); LL_INFOS() << "Total dir size after purge is " << dirFileSize(mCacheDir) << LL_ENDL; LL_INFOS() << "Cache purge took " << execute_time << " ms to execute for " << file_info.size() << " files" << LL_ENDL; } -- cgit v1.2.3 From 0d250e632c7816ada792b2ec8a63a3b0267daf8d Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 1 Jun 2022 13:41:13 -0700 Subject: SL-17329: Fix texture cache not respecting DiskCachePercentOfTotal --- indra/newview/llappviewer.cpp | 31 ++++++++++++++----------------- indra/newview/lltexturecache.cpp | 3 ++- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index cd2174eea4..50600a979d 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4259,12 +4259,17 @@ bool LLAppViewer::initCache() // initialize the new disk cache using saved settings const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName"); + const U32 MB = 1024 * 1024; + const U64 MIN_CACHE_SIZE = 256 * MB; + const U64 MAX_CACHE_SIZE = 9984ll * MB; + const U64 setting_cache_total_size = (U64)gSavedSettings.getU32("CacheSize") * MB; + const U64 cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); + const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); + const F64 texture_cache_percent = 100.0 - disk_cache_percent; + // note that the maximum size of this cache is defined as a percentage of the // total cache size - the 'CacheSize' pref - for all caches. - const unsigned int cache_total_size_mb = gSavedSettings.getU32("CacheSize"); - const double disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); - const unsigned int disk_cache_mb = cache_total_size_mb * disk_cache_percent / 100; - const uintmax_t disk_cache_bytes = disk_cache_mb * 1024 * 1024; + const U32 disk_cache_size = cache_total_size * disk_cache_percent / 100; const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); bool texture_cache_mismatch = false; @@ -4315,7 +4320,7 @@ bool LLAppViewer::initCache() } const std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, cache_dir_name); - LLDiskCache::initParamSingleton(cache_dir, disk_cache_bytes, enable_cache_debug_info); + LLDiskCache::initParamSingleton(cache_dir, disk_cache_size, enable_cache_debug_info); if (!read_only) { @@ -4338,22 +4343,14 @@ bool LLAppViewer::initCache() LLSplashScreen::update(LLTrans::getString("StartupInitializingTextureCache")); // Init the texture cache - // Allocate 80% of the cache size for textures - const S32 MB = 1024 * 1024; - const S64 MIN_CACHE_SIZE = 256 * MB; - const S64 MAX_CACHE_SIZE = 9984ll * MB; - - S64 cache_size = (S64)(gSavedSettings.getU32("CacheSize")) * MB; - cache_size = llclamp(cache_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); + // Allocate the remaining percent which is not allocated to the disk cache + const U32 texture_cache_size = cache_total_size * texture_cache_percent / 100; - S64 texture_cache_size = cache_size; - - S64 extra = LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch); - texture_cache_size -= extra; + LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch); LLVOCache::getInstance()->initCache(LL_PATH_CACHE, gSavedSettings.getU32("CacheNumberOfRegionsForObjects"), getObjectCacheVersion()); - return true; + return true; } void LLAppViewer::addOnIdleCallback(const boost::function& cb) diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index d4fc6f3de2..9403e73b87 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -1042,7 +1042,8 @@ void LLTextureCache::setReadOnly(BOOL read_only) mReadOnly = read_only ; } -//called in the main thread. +// Called in the main thread. +// Returns the unused amount of max_size if any S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache_mismatch) { llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. -- cgit v1.2.3 From 9511040af547e9d50a0dc7d34837f6439a7c1106 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 1 Jun 2022 13:43:00 -0700 Subject: SL-17329: Increase percent of CacheSize allocated to the disk cache from 20% to 40% --- indra/newview/app_settings/settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index dbc2131ce8..362d6b9670 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1371,7 +1371,7 @@ Type F32 Value - 20.0 + 40.0 DiskCacheDirName -- cgit v1.2.3 From 6e686f1ef6fc5ee0b4e4d86f5aae42b58332312a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 22 Jun 2022 14:04:28 -0700 Subject: SL-17021: Fix inconsistent header definition for LLAudioEngine_OpenAL --- indra/llaudio/llaudioengine_openal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llaudio/llaudioengine_openal.h b/indra/llaudio/llaudioengine_openal.h index 366f9259e3..a3cab97cd2 100644 --- a/indra/llaudio/llaudioengine_openal.h +++ b/indra/llaudio/llaudioengine_openal.h @@ -40,7 +40,7 @@ class LLAudioEngine_OpenAL : public LLAudioEngine LLAudioEngine_OpenAL(); virtual ~LLAudioEngine_OpenAL(); - virtual bool init(const S32 num_channels, void *user_data, const std::string &app_title); + virtual bool init(void *user_data, const std::string &app_title); virtual std::string getDriverName(bool verbose); virtual void allocateListener(); -- cgit v1.2.3 From 662cc980fcd9a00b8566543f190c58590ccf706f Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 23 Jun 2022 13:35:29 +0300 Subject: SL-17643 FIXED noninteractive viewer crashes on locations with parcel audio --- indra/newview/llviewerparcelmgr.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 3bd504709b..756bf12ff3 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1881,8 +1881,13 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - // Check for video - LLViewerParcelMedia::getInstance()->update(parcel); + if (gNonInteractive) + { + return; + } + + // Check for video + LLViewerParcelMedia::getInstance()->update(parcel); // Then check for music if (gAudiop) -- cgit v1.2.3 From 264ad0ce0cf1970b8faf07baca7a871aae9bd1d7 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Thu, 23 Jun 2022 15:17:49 +0300 Subject: mac build fix --- indra/llwindow/CMakeLists.txt | 6 ++++++ indra/newview/CMakeLists.txt | 2 -- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt index 70eb99c86c..55befaef51 100644 --- a/indra/llwindow/CMakeLists.txt +++ b/indra/llwindow/CMakeLists.txt @@ -197,4 +197,10 @@ if (SDL_FOUND) endif (SDL_FOUND) target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES}) + +if (DARWIN) + include(CMakeFindFrameworks) + find_library(CARBON_LIBRARY Carbon) + target_link_libraries(llwindow ${CARBON_LIBRARY}) +endif (DARWIN) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ae8d8d51a4..964615320d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -1413,14 +1413,12 @@ if (DARWIN) find_library(COCOA_LIBRARY Cocoa) find_library(IOKIT_LIBRARY IOKit) find_library(COREAUDIO_LIBRARY CoreAudio) - find_library(CARBON_LIBRARY Carbon) set(viewer_LIBRARIES ${COCOA_LIBRARY} ${AGL_LIBRARY} ${IOKIT_LIBRARY} ${COREAUDIO_LIBRARY} - ${CARBON_LIBRARY} ) if (USE_BUGSPLAT) -- cgit v1.2.3 From 4f834711660e17055cdbc285f0d426aec94ddc13 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 24 Jun 2022 09:20:40 -0700 Subject: SL-17329: Fix cache sizes due to overflow. Improve typing. --- indra/newview/llappviewer.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 50600a979d..0adbdb3647 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4262,14 +4262,14 @@ bool LLAppViewer::initCache() const U32 MB = 1024 * 1024; const U64 MIN_CACHE_SIZE = 256 * MB; const U64 MAX_CACHE_SIZE = 9984ll * MB; - const U64 setting_cache_total_size = (U64)gSavedSettings.getU32("CacheSize") * MB; - const U64 cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); - const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); - const F64 texture_cache_percent = 100.0 - disk_cache_percent; + const uintmax_t setting_cache_total_size = (uintmax_t)gSavedSettings.getU32("CacheSize") * MB; + const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); + const F32 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); + const F32 texture_cache_percent = 100.0 - disk_cache_percent; // note that the maximum size of this cache is defined as a percentage of the // total cache size - the 'CacheSize' pref - for all caches. - const U32 disk_cache_size = cache_total_size * disk_cache_percent / 100; + const uintmax_t disk_cache_size = cache_total_size * disk_cache_percent / 100; const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); bool texture_cache_mismatch = false; @@ -4344,7 +4344,7 @@ bool LLAppViewer::initCache() // Init the texture cache // Allocate the remaining percent which is not allocated to the disk cache - const U32 texture_cache_size = cache_total_size * texture_cache_percent / 100; + const S64 texture_cache_size = S64(cache_total_size * texture_cache_percent / 100); LLAppViewer::getTextureCache()->initCache(LL_PATH_CACHE, texture_cache_size, texture_cache_mismatch); -- cgit v1.2.3 From db5806f004a789f6b5ed65c691473ae5ea2aa97e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 24 Jun 2022 13:31:33 -0700 Subject: SL-17329: Address Mac build error --- indra/newview/llappviewer.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 0adbdb3647..b74cb4aa65 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4260,16 +4260,16 @@ bool LLAppViewer::initCache() const std::string cache_dir_name = gSavedSettings.getString("DiskCacheDirName"); const U32 MB = 1024 * 1024; - const U64 MIN_CACHE_SIZE = 256 * MB; - const U64 MAX_CACHE_SIZE = 9984ll * MB; - const uintmax_t setting_cache_total_size = (uintmax_t)gSavedSettings.getU32("CacheSize") * MB; + const uintmax_t MIN_CACHE_SIZE = 256 * MB; + const uintmax_t MAX_CACHE_SIZE = 9984ll * MB; + const uintmax_t setting_cache_total_size = uintmax_t(gSavedSettings.getU32("CacheSize")) * MB; const uintmax_t cache_total_size = llclamp(setting_cache_total_size, MIN_CACHE_SIZE, MAX_CACHE_SIZE); - const F32 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); - const F32 texture_cache_percent = 100.0 - disk_cache_percent; + const F64 disk_cache_percent = gSavedSettings.getF32("DiskCachePercentOfTotal"); + const F64 texture_cache_percent = 100.0 - disk_cache_percent; // note that the maximum size of this cache is defined as a percentage of the // total cache size - the 'CacheSize' pref - for all caches. - const uintmax_t disk_cache_size = cache_total_size * disk_cache_percent / 100; + const uintmax_t disk_cache_size = uintmax_t(cache_total_size * disk_cache_percent / 100); const bool enable_cache_debug_info = gSavedSettings.getBOOL("EnableDiskCacheDebugInfo"); bool texture_cache_mismatch = false; -- cgit v1.2.3 From 7bf25aa8b8d168142a208e2b02af047c445aacb0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 24 Jun 2022 13:32:14 -0700 Subject: SL-17329: Remove unused extra variable initialization --- indra/llfilesystem/lldiskcache.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp index 74955df50a..48d6ed8a68 100644 --- a/indra/llfilesystem/lldiskcache.cpp +++ b/indra/llfilesystem/lldiskcache.cpp @@ -146,7 +146,6 @@ void LLDiskCache::purge() { file_removed.push_back(should_remove); } - std::string action = ""; if (should_remove) { boost::filesystem::remove(entry.second.second, ec); -- cgit v1.2.3 From 73dc249ab62224f2754f44ddc4db30c1fdc8698c Mon Sep 17 00:00:00 2001 From: Rider Linden Date: Fri, 24 Jun 2022 16:33:54 -0700 Subject: SL-17663: Pass the water settings to the settings injector when an experience changes water settings. --- indra/newview/llenvironment.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index b76dc6a961..1300cf3658 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -2641,7 +2641,7 @@ void LLEnvironment::setExperienceEnvironment(LLUUID experience_id, LLSD data, F3 if (!water.isUndefined()) { - environment->injectWaterSettings(sky, experience_id, LLSettingsBase::Seconds(transition_time)); + environment->injectWaterSettings(water, experience_id, LLSettingsBase::Seconds(transition_time)); } if (updateenvironment) -- cgit v1.2.3 From 61407e3f69dc66979a0b33f855541081efdc550c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 29 Jun 2022 21:50:46 +0300 Subject: DRTVWR-548 resolved a merge issue --- indra/newview/llviewercontrol.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 68c4608687..bc46a61fb0 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -477,13 +477,6 @@ static bool handleRenderBumpChanged(const LLSD& newval) return true; } -static bool handleRenderDebugGLChanged(const LLSD& newvalue) -{ - gDebugGL = newvalue.asBoolean() || gDebugSession; - gGL.clearErrors(); - return true; -} - static bool handleRenderDebugPipelineChanged(const LLSD& newvalue) { gDebugPipeline = newvalue.asBoolean(); @@ -718,7 +711,6 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged); setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged); setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged); - setting_setup_signal_listener(gSavedSettings, "RenderDebugGL", handleRenderDebugGLChanged); setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged); setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged); setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged); -- cgit v1.2.3 From c2c22b90535cca4aaacfd8ba539d5445de68af0e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 29 Jun 2022 23:48:23 +0300 Subject: SL-17570 Color picker should properly focus it's parent when closing This reverts MAINT-1401, but looks like that was fixed properly later --- indra/newview/llcolorswatch.cpp | 18 +++++++++++++++--- indra/newview/llfloatercolorpicker.cpp | 6 +----- indra/newview/llfloatercolorpicker.h | 5 ----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp index 80d810d159..036ff17074 100644 --- a/indra/newview/llcolorswatch.cpp +++ b/indra/newview/llcolorswatch.cpp @@ -290,9 +290,14 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op ) pickerp->getCurG (), pickerp->getCurB (), subject->mColor.mV[VALPHA] ); // keep current alpha - subject->mColor = updatedColor; - subject->setControlValue(updatedColor.getValue()); - pickerp->setRevertOnCancel(TRUE); + + bool color_changed = subject->mColor != updatedColor; + if (color_changed) + { + subject->mColor = updatedColor; + subject->setControlValue(updatedColor.getValue()); + } + if (pick_op == COLOR_CANCEL && subject->mOnCancelCallback) { subject->mOnCancelCallback( subject, LLSD()); @@ -306,6 +311,13 @@ void LLColorSwatchCtrl::onColorChanged ( void* data, EColorPickOp pick_op ) // just commit change subject->onCommit (); } + + if (pick_op == COLOR_CANCEL || pick_op == COLOR_SELECT) + { + // both select and cancel close LLFloaterColorPicker + // but COLOR_CHANGE does not + subject->setFocus(TRUE); + } } } } diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 1a784223c2..1f0e8ee5fa 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -173,7 +173,6 @@ void LLFloaterColorPicker::showUI () openFloater(getKey()); setVisible ( TRUE ); setFocus ( TRUE ); - setRevertOnCancel(FALSE); // HACK: if system color picker is required - close the SL one we made and use default system dialog if ( gSavedSettings.getBOOL ( "UseDefaultColorPicker" ) ) @@ -391,10 +390,7 @@ void LLFloaterColorPicker::onClickCancel ( void* data ) if ( self ) { - if(self->getRevertOnCancel()) - { - self->cancelSelection (); - } + self->cancelSelection(); self->closeFloater(); } } diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h index 16974a872e..39dbc5b763 100644 --- a/indra/newview/llfloatercolorpicker.h +++ b/indra/newview/llfloatercolorpicker.h @@ -104,9 +104,6 @@ class LLFloaterColorPicker void setMouseDownInSwatch (BOOL mouse_down_in_swatch); BOOL getMouseDownInSwatch () { return mMouseDownInSwatch; } - void setRevertOnCancel (BOOL revertOnCancel) { mRevertOnCancel = revertOnCancel; }; - BOOL getRevertOnCancel () { return mRevertOnCancel; } - BOOL isColorChanged (); // called when text entries (RGB/HSL etc.) are changed by user @@ -149,8 +146,6 @@ class LLFloaterColorPicker BOOL mMouseDownInHueRegion; BOOL mMouseDownInSwatch; - BOOL mRevertOnCancel; - const S32 mRGBViewerImageLeft; const S32 mRGBViewerImageTop; const S32 mRGBViewerImageWidth; -- cgit v1.2.3 From 23534c4f1c1dd3e4dbbcd5b5b3aa2bd44f5c6350 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 29 Jun 2022 23:56:01 +0300 Subject: SL-17570 Slightly better support for system's picker --- indra/newview/llfloatercolorpicker.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp index 1f0e8ee5fa..ba91277c79 100644 --- a/indra/newview/llfloatercolorpicker.cpp +++ b/indra/newview/llfloatercolorpicker.cpp @@ -184,15 +184,23 @@ void LLFloaterColorPicker::showUI () // code that will get switched in for default system color picker if ( swatch ) { + // Todo: this needs to be threaded for viewer not to timeout LLColor4 curCol = swatch->get (); send_agent_pause(); - getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] ); + bool commit = getWindow()->dialogColorPicker( &curCol [ 0 ], &curCol [ 1 ], &curCol [ 2 ] ); send_agent_resume(); - setOrigRgb ( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] ); - setCurRgb( curCol [ 0 ], curCol [ 1 ], curCol [ 2 ] ); - - LLColorSwatchCtrl::onColorChanged ( swatch, LLColorSwatchCtrl::COLOR_CHANGE ); + if (commit) + { + setOrigRgb(curCol[0], curCol[1], curCol[2]); + setCurRgb(curCol[0], curCol[1], curCol[2]); + + LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_SELECT); + } + else + { + LLColorSwatchCtrl::onColorChanged(swatch, LLColorSwatchCtrl::COLOR_CANCEL); + } } closeFloater(); -- cgit v1.2.3 From e72c803df01e95d4ce73c0b207b1da9ea89eb144 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 9 Jul 2022 00:19:14 +0300 Subject: SL-17741 Paste is not disabled when copying 'no copy' items We should allow to copy 'no copy' items for the ability to paste them as links, but regular 'paste' should be disabled in such case Also fixed library items enabling 'paste as link', we can not link library items. --- indra/llui/llfolderviewmodel.h | 2 +- indra/newview/llconversationmodel.h | 2 +- indra/newview/llinventorybridge.cpp | 72 +++++++++++++++++++------------- indra/newview/llinventorybridge.h | 6 +-- indra/newview/llpanelobjectinventory.cpp | 6 +-- 5 files changed, 51 insertions(+), 37 deletions(-) diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 093e213be3..618169a8fe 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -172,7 +172,7 @@ public: virtual BOOL removeItem() = 0; virtual void removeBatch(std::vector& batch) = 0; - virtual BOOL isItemCopyable() const = 0; + virtual bool isItemCopyable(bool can_copy_as_link = true) const = 0; virtual BOOL copyToClipboard() const = 0; virtual BOOL cutToClipboard() = 0; virtual bool isCutToClipboard() { return false; }; diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 787deeb594..7c6980a7e6 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -87,7 +87,7 @@ public: virtual BOOL removeItem() { return FALSE; } virtual void removeBatch(std::vector& batch) { } virtual void move( LLFolderViewModelItem* parent_listener ) { } - virtual BOOL isItemCopyable() const { return FALSE; } + virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; } virtual BOOL copyToClipboard() const { return FALSE; } virtual BOOL cutToClipboard() { return FALSE; } virtual BOOL isClipboardPasteable() const { return FALSE; } diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a0de3a2af1..8ef0be4a00 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -614,7 +614,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const if (cat) { LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, item_id); - if (!cat_br.isItemCopyable()) + if (!cat_br.isItemCopyable(false)) return FALSE; // Skip to the next item in the clipboard continue; @@ -622,7 +622,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const // Each item must be copyable to be pastable LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id); - if (!item_br.isItemCopyable()) + if (!item_br.isItemCopyable(false)) { return FALSE; } @@ -654,6 +654,11 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const { return FALSE; } + + if (gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID())) + { + return FALSE; + } } const LLViewerInventoryCategory *cat = model->getCategory(objects.at(i)); if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) @@ -869,7 +874,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Paste")); } - if (gSavedSettings.getBOOL("InventoryLinking")) + static LLCachedControl inventory_linking(gSavedSettings, "InventoryLinking", true); + if (inventory_linking) { items.push_back(std::string("Paste As Link")); if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) @@ -2043,7 +2049,8 @@ BOOL LLItemBridge::removeItem() // we can't do this check because we may have items in a folder somewhere that is // not yet in memory, so we don't want false negatives. (If disabled, then we // know we only have links in the Outfits folder which we explicitly fetch.) - if (!gSavedSettings.getBOOL("InventoryLinking")) + static LLCachedControl inventory_linking(gSavedSettings, "InventoryLinking", true); + if (!inventory_linking) { if (!item->getIsLinkType()) { @@ -2086,22 +2093,24 @@ BOOL LLItemBridge::confirmRemoveItem(const LLSD& notification, const LLSD& respo return FALSE; } -BOOL LLItemBridge::isItemCopyable() const +bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const { - LLViewerInventoryItem* item = getItem(); - if (item) - { - // Can't copy worn objects. - // Worn objects are tied to their inworld conterparts - // Copy of modified worn object will return object with obsolete asset and inventory - if(get_is_item_worn(mUUID)) - { - return FALSE; - } + LLViewerInventoryItem* item = getItem(); + if (item) + { + return false; + } + // Can't copy worn objects. + // Worn objects are tied to their inworld conterparts + // Copy of modified worn object will return object with obsolete asset and inventory + if (get_is_item_worn(mUUID)) + { + return false; + } - return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking"); - } - return FALSE; + static LLCachedControl inventory_linking(gSavedSettings, "InventoryLinking", true); + return (can_copy_as_link && inventory_linking) + || item->getPermissions().allowCopyBy(gAgent.getID()); } LLViewerInventoryItem* LLItemBridge::getItem() const @@ -2305,7 +2314,7 @@ BOOL LLFolderBridge::isUpToDate() const return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN; } -BOOL LLFolderBridge::isItemCopyable() const +bool LLFolderBridge::isItemCopyable(bool can_copy_as_link) const { // Folders are copyable if items in them are, recursively, copyable. @@ -2320,22 +2329,26 @@ BOOL LLFolderBridge::isItemCopyable() const { LLInventoryItem* item = *iter; LLItemBridge item_br(mInventoryPanel.get(), mRoot, item->getUUID()); - if (!item_br.isItemCopyable()) - return FALSE; -} + if (!item_br.isItemCopyable(false)) + { + return false; + } + } // Check the folders LLInventoryModel::cat_array_t cat_array_copy = *cat_array; for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) -{ + { LLViewerInventoryCategory* category = *iter; LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, category->getUUID()); - if (!cat_br.isItemCopyable()) - return FALSE; - } - - return TRUE; - } + if (!cat_br.isItemCopyable(false)) + { + return false; + } + } + + return true; +} BOOL LLFolderBridge::isClipboardPasteable() const { @@ -3752,6 +3765,7 @@ void LLFolderBridge::perform_pasteFromClipboard() LLInventoryObject *obj = model->getObject(item_id); if (obj) { + if (move_is_into_lost_and_found) { if (LLAssetType::AT_CATEGORY == obj->getType()) diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 0b0ef273e1..bdffecf1c6 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -119,7 +119,7 @@ public: //virtual BOOL removeItem() = 0; virtual void removeBatch(std::vector& batch); virtual void move(LLFolderViewModelItem* new_parent_bridge) {} - virtual BOOL isItemCopyable() const { return FALSE; } + virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; } virtual BOOL copyToClipboard() const; virtual BOOL cutToClipboard(); virtual bool isCutToClipboard(); @@ -245,7 +245,7 @@ public: virtual BOOL isItemRenameable() const; virtual BOOL renameItem(const std::string& new_name); virtual BOOL removeItem(); - virtual BOOL isItemCopyable() const; + virtual bool isItemCopyable(bool can_copy_as_link = true) const; virtual bool hasChildren() const { return FALSE; } virtual BOOL isUpToDate() const { return TRUE; } virtual LLUIImagePtr getIconOverlay() const; @@ -318,7 +318,7 @@ public: virtual BOOL isItemRemovable() const; virtual BOOL isItemMovable() const ; virtual BOOL isUpToDate() const; - virtual BOOL isItemCopyable() const; + virtual bool isItemCopyable(bool can_copy_as_link = true) const; virtual BOOL isClipboardPasteable() const; virtual BOOL isClipboardPasteableAsLink() const; diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 0d987df6ca..df35dd752a 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -131,7 +131,7 @@ public: virtual BOOL removeItem(); virtual void removeBatch(std::vector& batch); virtual void move(LLFolderViewModelItem* parent_listener); - virtual BOOL isItemCopyable() const; + virtual bool isItemCopyable(bool can_copy_as_link = true) const; virtual BOOL copyToClipboard() const; virtual BOOL cutToClipboard(); virtual BOOL isClipboardPasteable() const; @@ -439,10 +439,10 @@ void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener) { } -BOOL LLTaskInvFVBridge::isItemCopyable() const +bool LLTaskInvFVBridge::isItemCopyable(bool can_link) const { LLInventoryItem* item = findItem(); - if(!item) return FALSE; + if(!item) return false; return gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE); } -- cgit v1.2.3 From a3326a4afc8f212264b1d301401e6591d194aa3f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 11 Jul 2022 23:39:55 +0300 Subject: SL-17752 Crash at removeMutedAVsLights --- indra/newview/pipeline.cpp | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c297f0f080..5bf62f0524 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1773,15 +1773,20 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); - iter != gPipeline.mNearbyLights.end(); iter++) - { - if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) - { - gPipeline.mLights.erase(iter->drawable); - gPipeline.mNearbyLights.erase(iter); - } - } + light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); + + while (iter != gPipeline.mNearbyLights.end()) + { + if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) + { + gPipeline.mLights.erase(iter->drawable); + iter = gPipeline.mNearbyLights.erase(iter); + } + else + { + iter++; + } + } } U32 LLPipeline::addObject(LLViewerObject *vobj) -- cgit v1.2.3 From fca85429c5763ab0bd2a1d4c1be40443e469e375 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 12 Jul 2022 00:07:43 +0300 Subject: SL-17753 Crash at LLStatusBar::getNearbyMediaPanel optionallyStartMusic was called before status bar was initialized --- indra/newview/llviewerparcelmgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index e69b0347f8..9095a6b5b7 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1959,7 +1959,7 @@ void LLViewerParcelMgr::optionallyStartMusic(const std::string &music_url, const static LLCachedControl tentative_autoplay(gSavedSettings, "MediaTentativeAutoPlay", true); // only play music when you enter a new parcel if the UI control for this // was not *explicitly* stopped by the user. (part of SL-4878) - LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel(); + LLPanelNearByMedia* nearby_media_panel = gStatusBar ? gStatusBar->getNearbyMediaPanel() : NULL; LLViewerAudio* viewer_audio = LLViewerAudio::getInstance(); // ask mode //todo constants -- cgit v1.2.3 From 5f8f4754ab66eafeda7349d913ae3acfb71062a0 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 13 Jul 2022 17:22:01 +0300 Subject: SL-17723 Remove use of UDP image fetch --- indra/llmessage/message_prehash.cpp | 3 - indra/llmessage/message_prehash.h | 2 - indra/newview/llstartup.cpp | 2 - indra/newview/lltexturefetch.cpp | 588 +--------------------------------- indra/newview/lltexturefetch.h | 19 +- indra/newview/lltextureview.cpp | 1 - indra/newview/llviewertexturelist.cpp | 146 --------- indra/newview/llviewertexturelist.h | 2 - 8 files changed, 8 insertions(+), 755 deletions(-) diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 219b1855d2..c7fdb58a98 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -666,7 +666,6 @@ char const* const _PREHASH_GroupRolesCount = LLMessageStringTable::getInstance() char const* const _PREHASH_SimulatorBlock = LLMessageStringTable::getInstance()->getString("SimulatorBlock"); char const* const _PREHASH_GroupID = LLMessageStringTable::getInstance()->getString("GroupID"); char const* const _PREHASH_AgentVel = LLMessageStringTable::getInstance()->getString("AgentVel"); -char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage"); char const* const _PREHASH_NetStats = LLMessageStringTable::getInstance()->getString("NetStats"); char const* const _PREHASH_AgentPos = LLMessageStringTable::getInstance()->getString("AgentPos"); char const* const _PREHASH_AgentSit = LLMessageStringTable::getInstance()->getString("AgentSit"); @@ -1047,7 +1046,6 @@ char const* const _PREHASH_SortOrder = LLMessageStringTable::getInstance()->getS char const* const _PREHASH_Hunter = LLMessageStringTable::getInstance()->getString("Hunter"); char const* const _PREHASH_SunAngVelocity = LLMessageStringTable::getInstance()->getString("SunAngVelocity"); char const* const _PREHASH_BinaryBucket = LLMessageStringTable::getInstance()->getString("BinaryBucket"); -char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket"); char const* const _PREHASH_StartGroupProposal = LLMessageStringTable::getInstance()->getString("StartGroupProposal"); char const* const _PREHASH_EnergyLevel = LLMessageStringTable::getInstance()->getString("EnergyLevel"); char const* const _PREHASH_PriceForListing = LLMessageStringTable::getInstance()->getString("PriceForListing"); @@ -1236,7 +1234,6 @@ char const* const _PREHASH_ForceScriptControlRelease = LLMessageStringTable::get char const* const _PREHASH_ParcelRelease = LLMessageStringTable::getInstance()->getString("ParcelRelease"); char const* const _PREHASH_VFileType = LLMessageStringTable::getInstance()->getString("VFileType"); char const* const _PREHASH_EjectGroupMemberReply = LLMessageStringTable::getInstance()->getString("EjectGroupMemberReply"); -char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData"); char const* const _PREHASH_SimulatorViewerTimeMessage = LLMessageStringTable::getInstance()->getString("SimulatorViewerTimeMessage"); char const* const _PREHASH_Rotation = LLMessageStringTable::getInstance()->getString("Rotation"); char const* const _PREHASH_Selection = LLMessageStringTable::getInstance()->getString("Selection"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 8f6ee5a327..706ec475d9 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -666,7 +666,6 @@ extern char const* const _PREHASH_GroupRolesCount; extern char const* const _PREHASH_SimulatorBlock; extern char const* const _PREHASH_GroupID; extern char const* const _PREHASH_AgentVel; -extern char const* const _PREHASH_RequestImage; extern char const* const _PREHASH_NetStats; extern char const* const _PREHASH_AgentPos; extern char const* const _PREHASH_AgentSit; @@ -1047,7 +1046,6 @@ extern char const* const _PREHASH_SortOrder; extern char const* const _PREHASH_Hunter; extern char const* const _PREHASH_SunAngVelocity; extern char const* const _PREHASH_BinaryBucket; -extern char const* const _PREHASH_ImagePacket; extern char const* const _PREHASH_StartGroupProposal; extern char const* const _PREHASH_EnergyLevel; extern char const* const _PREHASH_PriceForListing; diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 0829b1a213..f975c71706 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2503,8 +2503,6 @@ void use_circuit_callback(void**, S32 result) void register_viewer_callbacks(LLMessageSystem* msg) { msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data ); - msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader ); - msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket ); msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update ); msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update ); msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update ); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 0edaf40c66..3099092abb 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -282,7 +282,6 @@ static const char* e_state_name[] = "LOAD_FROM_TEXTURE_CACHE", "CACHE_POST", "LOAD_FROM_NETWORK", - "LOAD_FROM_SIMULATOR", "WAIT_HTTP_RESOURCE", "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", @@ -456,7 +455,6 @@ public: LOAD_FROM_TEXTURE_CACHE, CACHE_POST, LOAD_FROM_NETWORK, - LOAD_FROM_SIMULATOR, WAIT_HTTP_RESOURCE, // Waiting for HTTP resources WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources SEND_HTTP_REQ, // Commit to sending as HTTP @@ -497,8 +495,6 @@ private: // Locks: Mw void clearPackets(); - // Locks: Mw - void setupPacketData(); // Locks: Mw (ctor invokes without lock) U32 calcWorkPriority(); @@ -506,10 +502,6 @@ private: // Locks: Mw void removeFromCache(); - // Threads: Ttf - // Locks: Mw - bool processSimulatorPackets(); - // Threads: Ttf bool writeToCacheComplete(); @@ -612,8 +604,7 @@ private: BOOL mHaveAllData; BOOL mInLocalCache; BOOL mInCache; - bool mCanUseHTTP, - mCanUseNET ; //can get from asset server. + bool mCanUseHTTP; S32 mRetryAttempt; S32 mActiveCount; LLCore::HttpStatus mGetStatus; @@ -885,7 +876,6 @@ const char* sStateDescs[] = { "LOAD_FROM_TEXTURE_CACHE", "CACHE_POST", "LOAD_FROM_NETWORK", - "LOAD_FROM_SIMULATOR", "WAIT_HTTP_RESOURCE", "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", @@ -897,7 +887,7 @@ const char* sStateDescs[] = { "DONE" }; -const std::set LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR, +const std::set LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::WAIT_HTTP_REQ, LLTextureFetchWorker::DECODE_IMAGE_UPDATE, LLTextureFetchWorker::WAIT_ON_WRITE }; // static @@ -972,8 +962,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mResourceWaitCount(0U), mFetchRetryPolicy(10.0,3600.0,2.0,10) { - mCanUseNET = mUrl.empty() ; - calcWorkPriority(); mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; // LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL; @@ -1037,39 +1025,6 @@ void LLTextureFetchWorker::clearPackets() mFirstPacket = 0; } -// Locks: Mw -void LLTextureFetchWorker::setupPacketData() -{ - S32 data_size = 0; - if (mFormattedImage.notNull()) - { - data_size = mFormattedImage->getDataSize(); - } - if (data_size > 0) - { - // Only used for simulator requests - mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1; - if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size) - { - LL_WARNS(LOG_TXT) << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL; - removeFromCache(); - resetFormattedData(); - clearPackets(); - } - else if (mFileSize > 0) - { - mLastPacket = mFirstPacket-1; - mTotalPackets = (mFileSize - FIRST_PACKET_SIZE + MAX_IMG_PACKET_SIZE-1) / MAX_IMG_PACKET_SIZE + 1; - } - else - { - // This file was cached using HTTP so we have to refetch the first packet - resetFormattedData(); - clearPackets(); - } - } -} - // Locks: Mw (ctor invokes without lock) U32 LLTextureFetchWorker::calcWorkPriority() { @@ -1177,13 +1132,13 @@ bool LLTextureFetchWorker::doWork(S32 param) if(mImagePriority < F_ALMOST_ZERO) { - if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR) + if (mState == INIT || mState == LOAD_FROM_NETWORK) { LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL; return true; // abort } } - if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP) + if(mState > CACHE_POST && !mCanUseHTTP) { //nowhere to get data, abort. LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL; @@ -1408,14 +1363,14 @@ bool LLTextureFetchWorker::doWork(S32 param) else { mCanUseHTTP = false ; - LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL; + LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL; } } else { // This will happen if not logged in or if a region deoes not have HTTP Texture enabled //LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL; - LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL; + LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL; mCanUseHTTP = false; } } @@ -1434,84 +1389,12 @@ bool LLTextureFetchWorker::doWork(S32 param) } // don't return, fall through to next state } - else if (mSentRequest == UNSENT && mCanUseNET) - { - // Add this to the network queue and sit here. - // LLTextureFetch::update() will send off a request which will change our state - mWriteToCacheState = CAN_WRITE ; - mRequestedSize = mDesiredSize; - mRequestedDiscard = mDesiredDiscard; - mSentRequest = QUEUED; - mFetcher->addToNetworkQueue(this); - recordTextureStart(false); - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - - return false; - } else { - // Shouldn't need to do anything here - //llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); - // Make certain this is in the network queue - //mFetcher->addToNetworkQueue(this); - //recordTextureStart(false); - //setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - return false; } } - if (mState == LOAD_FROM_SIMULATOR) - { - if (mFormattedImage.isNull()) - { - mFormattedImage = new LLImageJ2C; - } - if (processSimulatorPackets()) - { - // Capture some measure of total size for metrics - F64 byte_count = 0; - if (mLastPacket >= mFirstPacket) - { - for (S32 i=mFirstPacket; i<=mLastPacket; i++) - { - llassert_always((i>=0) && (imSize; - } - } - } - - LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL; - mFetcher->removeFromNetworkQueue(this, false); - if (mFormattedImage.isNull() || !mFormattedImage->getDataSize()) - { - // processSimulatorPackets() failed -// LL_WARNS(LOG_TXT) << "processSimulatorPackets() failed to load buffer" << LL_ENDL; - LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL; - return true; // failed - } - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - if (mLoadedDiscard < 0) - { - LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard - << ", should be >=0" << LL_ENDL; - } - setState(DECODE_IMAGE); - mWriteToCacheState = SHOULD_WRITE; - - recordTextureDone(false, byte_count); - } - else - { - mFetcher->addToNetworkQueue(this); // failsafe - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - recordTextureStart(false); - } - return false; - } - if (mState == WAIT_HTTP_RESOURCE) { // NOTE: @@ -1553,8 +1436,6 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_WARNS(LOG_TXT) << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL; return true; // abort } - - mFetcher->removeFromNetworkQueue(this, false); S32 cur_size = 0; if (mFormattedImage.notNull()) @@ -1701,17 +1582,6 @@ bool LLTextureFetchWorker::doWork(S32 param) } return true; } - - // roll back to try UDP - if (mCanUseNET) - { - setState(INIT); - mCanUseHTTP = false; - mUrl.clear(); - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - releaseHttpSemaphore(); - return false; - } } else if (http_service_unavail == mGetStatus) { @@ -2280,69 +2150,6 @@ void LLTextureFetchWorker::removeFromCache() } -////////////////////////////////////////////////////////////////////////////// - -// Threads: Ttf -// Locks: Mw -bool LLTextureFetchWorker::processSimulatorPackets() -{ - if (mFormattedImage.isNull() || mRequestedSize < 0) - { - // not sure how we got here, but not a valid state, abort! - llassert_always(mDecodeHandle == 0); - mFormattedImage = NULL; - return true; - } - - if (mLastPacket >= mFirstPacket) - { - S32 buffer_size = mFormattedImage->getDataSize(); - for (S32 i = mFirstPacket; i<=mLastPacket; i++) - { - llassert_always((i>=0) && (imSize; - } - bool have_all_data = mLastPacket >= mTotalPackets-1; - if (mRequestedSize <= 0) - { - // We received a packed but haven't requested anything yet (edge case) - // Return true (we're "done") since we didn't request anything - return true; - } - if (buffer_size >= mRequestedSize || have_all_data) - { - /// We have enough (or all) data - if (have_all_data) - { - mHaveAllData = TRUE; - } - S32 cur_size = mFormattedImage->getDataSize(); - if (buffer_size > cur_size) - { - /// We have new data - U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size); - S32 offset = 0; - if (cur_size > 0 && mFirstPacket > 0) - { - memcpy(buffer, mFormattedImage->getData(), cur_size); - offset = cur_size; - } - for (S32 i=mFirstPacket; i<=mLastPacket; i++) - { - memcpy(buffer + offset, mPackets[i]->mData, mPackets[i]->mSize); - offset += mPackets[i]->mSize; - } - // NOTE: setData releases current data - mFormattedImage->setData(buffer, buffer_size); - } - mLoadedDiscard = mRequestedDiscard; - return true; - } - } - return false; -} - ////////////////////////////////////////////////////////////////////////////// // Threads: Ttf @@ -2813,40 +2620,6 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const } -// Threads: T* (but Ttf in practice) - -// protected -void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) -{ - lockQueue(); // +Mfq - bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ; - unlockQueue(); // -Mfq - - LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq - if (in_request_map) - { - // only add to the queue if in the request map - // i.e. a delete has not been requested - mNetworkQueue.insert(worker->mID); - } - for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); - iter1 != mCancelQueue.end(); ++iter1) - { - iter1->second.erase(worker->mID); - } -} // -Mfnq - -// Threads: T* -void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel) -{ - LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq - size_t erased = mNetworkQueue.erase(worker->mID); - if (cancel && erased > 0) - { - mCancelQueue[worker->mHost].insert(worker->mID); - } -} // -Mfnq - // Threads: T* // // protected @@ -2880,7 +2653,6 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; worker->scheduleDelete(); @@ -2908,7 +2680,6 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; worker->scheduleDelete(); @@ -3197,17 +2968,6 @@ S32 LLTextureFetch::update(F32 max_time_ms) S32 res = LLWorkerThread::update(max_time_ms); - if (!mDebugPause) - { - // this is the startup state when send_complete_agent_movement() message is sent. - // Before this, the RequestImages message sent by sendRequestListToSimulators - // won't work so don't bother trying - if (LLStartUp::getStartupState() > STATE_AGENT_SEND) - { - sendRequestListToSimulators(); - } - } - if (!mThreaded) { commonUpdate(); @@ -3298,202 +3058,6 @@ void LLTextureFetch::threadedUpdate() ////////////////////////////////////////////////////////////////////////////// -// Threads: Tmain -void LLTextureFetch::sendRequestListToSimulators() -{ - // All requests - const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps - - // Sim requests - const S32 IMAGES_PER_REQUEST = 50; - const F32 SIM_LAZY_FLUSH_TIMEOUT = 10.0f; // temp - const F32 MIN_REQUEST_TIME = 1.0f; - const F32 MIN_DELTA_PRIORITY = 1000.f; - - // Periodically, gather the list of textures that need data from the network - // And send the requests out to the simulators - static LLFrameTimer timer; - if (timer.getElapsedTimeF32() < REQUEST_DELTA_TIME) - { - return; - } - timer.reset(); - - // Send requests - typedef std::set request_list_t; - typedef std::map< LLHost, request_list_t > work_request_map_t; - work_request_map_t requests; - { - LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq - for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); ) - { - queue_t::iterator curiter = iter++; - LLTextureFetchWorker* req = getWorker(*curiter); - if (!req) - { - mNetworkQueue.erase(curiter); - continue; // paranoia - } - if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) && - (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR)) - { - // We already received our URL, remove from the queue - LL_WARNS(LOG_TXT) << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL; - mNetworkQueue.erase(curiter); - continue; - } - if (req->mID == mDebugID) - { - mDebugCount++; // for setting breakpoints - } - if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM && - req->mTotalPackets > 0 && - req->mLastPacket >= req->mTotalPackets-1) - { - // We have all the packets... make sure this is high priority -// req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority); - continue; - } - F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32(); - { - F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority); - if ((req->mSimRequestedDiscard != req->mDesiredDiscard) || - (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) || - (elapsed >= SIM_LAZY_FLUSH_TIMEOUT)) - { - requests[req->mHost].insert(req); - } - } - } - } // -Mfnq - - for (work_request_map_t::iterator iter1 = requests.begin(); - iter1 != requests.end(); ++iter1) - { - LLHost host = iter1->first; - // invalid host = use agent host - if (host.isInvalid()) - { - host = gAgent.getRegionHost(); - } - - S32 sim_request_count = 0; - - for (request_list_t::iterator iter2 = iter1->second.begin(); - iter2 != iter1->second.end(); ++iter2) - { - LLTextureFetchWorker* req = *iter2; - if (gMessageSystem) - { - if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM) - { - // Initialize packet data based on data read from cache - req->lockWorkMutex(); // +Mw - req->setupPacketData(); - req->unlockWorkMutex(); // -Mw - } - if (0 == sim_request_count) - { - gMessageSystem->newMessageFast(_PREHASH_RequestImage); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - } - S32 packet = req->mLastPacket + 1; - gMessageSystem->nextBlockFast(_PREHASH_RequestImage); - gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID); - gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard); - gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority); - gMessageSystem->addU32Fast(_PREHASH_Packet, packet); - gMessageSystem->addU8Fast(_PREHASH_Type, req->mType); -// LL_INFOS(LOG_TXT) << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard -// << " Packet: " << packet << " Priority: " << req->mImagePriority << LL_ENDL; - - static LLCachedControl log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false); - static LLCachedControl log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false); - if (log_to_viewer_log || log_to_sim) - { - mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime()); - mTextureInfo.setRequestOffset(req->mID, 0); - mTextureInfo.setRequestSize(req->mID, 0); - mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP); - } - - req->lockWorkMutex(); // +Mw - req->mSentRequest = LLTextureFetchWorker::SENT_SIM; - req->mSimRequestedDiscard = req->mDesiredDiscard; - req->mRequestedPriority = req->mImagePriority; - req->mRequestedDeltaTimer.reset(); - req->unlockWorkMutex(); // -Mw - sim_request_count++; - if (sim_request_count >= IMAGES_PER_REQUEST) - { -// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; - - gMessageSystem->sendSemiReliable(host, NULL, NULL); - sim_request_count = 0; - } - } - } - if (gMessageSystem && sim_request_count > 0 && sim_request_count < IMAGES_PER_REQUEST) - { -// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; - gMessageSystem->sendSemiReliable(host, NULL, NULL); - sim_request_count = 0; - } - } - - // Send cancelations - { - LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq - if (gMessageSystem && !mCancelQueue.empty()) - { - for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); - iter1 != mCancelQueue.end(); ++iter1) - { - LLHost host = iter1->first; - if (host.isInvalid()) - { - host = gAgent.getRegionHost(); - } - S32 request_count = 0; - for (queue_t::iterator iter2 = iter1->second.begin(); - iter2 != iter1->second.end(); ++iter2) - { - if (0 == request_count) - { - gMessageSystem->newMessageFast(_PREHASH_RequestImage); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - } - gMessageSystem->nextBlockFast(_PREHASH_RequestImage); - gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2); - gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1); - gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0); - gMessageSystem->addU32Fast(_PREHASH_Packet, 0); - gMessageSystem->addU8Fast(_PREHASH_Type, 0); -// LL_INFOS(LOG_TXT) << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL; - - request_count++; - if (request_count >= IMAGES_PER_REQUEST) - { - gMessageSystem->sendSemiReliable(host, NULL, NULL); - request_count = 0; - } - } - if (request_count > 0 && request_count < IMAGES_PER_REQUEST) - { - gMessageSystem->sendSemiReliable(host, NULL, NULL); - } - } - mCancelQueue.clear(); - } - } // -Mfnq -} - -////////////////////////////////////////////////////////////////////////////// - // Threads: T* // Locks: Mw bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) @@ -3556,138 +3120,6 @@ void LLTextureFetchWorker::setState(e_state new_state) mState = new_state; } -// Threads: T* -bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, - U16 data_size, U8* data) -{ - LLTextureFetchWorker* worker = getWorker(id); - bool res = true; - - ++mPacketCount; - - if (!worker) - { -// LL_WARNS(LOG_TXT) << "Received header for non active worker: " << id << LL_ENDL; - res = false; - } - else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK || - worker->mSentRequest != LLTextureFetchWorker::SENT_SIM) - { -// LL_WARNS(LOG_TXT) << "receiveImageHeader for worker: " << id -// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] -// << " sent: " << worker->mSentRequest << LL_ENDL; - res = false; - } - else if (worker->mLastPacket != -1) - { - // check to see if we've gotten this packet before -// LL_WARNS(LOG_TXT) << "Received duplicate header for: " << id << LL_ENDL; - res = false; - } - else if (!data_size) - { -// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; - res = false; - } - if (!res) - { - mNetworkQueueMutex.lock(); // +Mfnq - ++mBadPacketCount; - mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock(); // -Mfnq - return false; - } - - LLViewerStatsRecorder::instance().textureFetch(data_size); - LLViewerStatsRecorder::instance().log(0.1f); - - worker->lockWorkMutex(); - - - // Copy header data into image object - worker->mImageCodec = codec; - worker->mTotalPackets = packets; - worker->mFileSize = (S32)totalbytes; - llassert_always(totalbytes > 0); - llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize); - res = worker->insertPacket(0, data, data_size); - worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); - worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR); - worker->unlockWorkMutex(); // -Mw - return res; -} - - -// Threads: T* -bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data) -{ - LLTextureFetchWorker* worker = getWorker(id); - bool res = true; - - ++mPacketCount; - - if (!worker) - { -// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL; - res = false; - } - else if (worker->mLastPacket == -1) - { -// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " before header for: " << id << LL_ENDL; - res = false; - } - else if (!data_size) - { -// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; - res = false; - } - if (!res) - { - mNetworkQueueMutex.lock(); // +Mfnq - ++mBadPacketCount; - mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock(); // -Mfnq - return false; - } - - LLViewerStatsRecorder::instance().textureFetch(data_size); - LLViewerStatsRecorder::instance().log(0.1f); - - worker->lockWorkMutex(); - - - res = worker->insertPacket(packet_num, data, data_size); - - if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) || - (worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK)) - { - worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); - worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR); - } - else - { -// LL_WARNS(LOG_TXT) << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id -// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << LL_ENDL; - removeFromNetworkQueue(worker, true); // failsafe - } - - if (packet_num >= (worker->mTotalPackets - 1)) - { - static LLCachedControl log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false); - static LLCachedControl log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false); - - if (log_to_viewer_log || log_to_sim) - { - U64Microseconds timeNow = LLTimer::getTotalTime(); - mTextureInfoMainThread.setRequestSize(id, worker->mFileSize); - mTextureInfoMainThread.setRequestCompleteTimeAndLog(id, timeNow); - } - } - worker->unlockWorkMutex(); // -Mw - - return res; -} - ////////////////////////////////////////////////////////////////////////////// // Threads: T* @@ -3726,13 +3158,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32(); if (worker->mFileSize > 0) { - if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) - { - S32 data_size = FIRST_PACKET_SIZE + (worker->mLastPacket-1) * MAX_IMG_PACKET_SIZE; - data_size = llmax(data_size, 0); - data_progress = (F32)data_size / (F32)worker->mFileSize; - } - else if (worker->mFormattedImage.notNull()) + if (worker->mFormattedImage.notNull()) { data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize; } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index bf6732963f..d087db275b 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -101,12 +101,6 @@ public: // Threads: T* bool updateRequestPriority(const LLUUID& id, F32 priority); - // Threads: T* - bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data); - - // Threads: T* - bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data); - // Threads: T* (but not safe) void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; } @@ -227,12 +221,6 @@ public: // ---------------------------------- protected: - // Threads: T* (but Ttf in practice) - void addToNetworkQueue(LLTextureFetchWorker* worker); - - // Threads: T* - void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); - // Threads: T* void addToHTTPQueue(const LLUUID& id); @@ -251,9 +239,6 @@ protected: bool runCondition(); private: - // Threads: Tmain - void sendRequestListToSimulators(); - // Threads: Ttf /*virtual*/ void startThread(void); @@ -319,7 +304,7 @@ public: private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only - LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. + LLMutex mNetworkQueueMutex; //to protect mHTTPTextureQueue LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; @@ -330,10 +315,8 @@ private: // Set of requests that require network data typedef std::set queue_t; - queue_t mNetworkQueue; // Mfnq queue_t mHTTPTextureQueue; // Mfnq typedef std::map > cancel_queue_t; - cancel_queue_t mCancelQueue; // Mfnq F32 mTextureBandwidth; // F32 mMaxBandwidth; // Mfnq LLTextureInfo mTextureInfo; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index b74577315e..cf9211767e 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -234,7 +234,6 @@ void LLTextureBar::draw() { "DSK", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE { "DSK", LLColor4::blue }, // CACHE_POST { "NET", LLColor4::green }, // LOAD_FROM_NETWORK - { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2 { "REQ", LLColor4::yellow },// SEND_HTTP_REQ diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index bbbf9ea7a3..37cd42079a 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -1501,152 +1501,6 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem) /////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data) -{ - static LLCachedControl log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; - - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - - // Receive image header, copy into image object and decompresses - // if this is a one-packet image. - - LLUUID id; - - char ip_string[256]; - u32_to_ip_string(msg->getSenderIP(),ip_string); - - U32Bytes received_size ; - if (msg->getReceiveCompressedSize()) - { - received_size = (U32Bytes)msg->getReceiveCompressedSize() ; - } - else - { - received_size = (U32Bytes)msg->getReceiveSize() ; - } - add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, received_size); - add(LLStatViewer::TEXTURE_PACKETS, 1); - - U8 codec; - U16 packets; - U32 totalbytes; - msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); - msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec); - msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets); - msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes); - - S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); - if (!data_size) - { - return; - } - if (data_size < 0) - { - // msg->getSizeFast() is probably trying to tell us there - // was an error. - LL_ERRS() << "image header chunk size was negative: " - << data_size << LL_ENDL; - return; - } - - // this buffer gets saved off in the packet list - U8 *data = new U8[data_size]; - msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); - - LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - if (!image) - { - delete [] data; - return; - } - if(log_texture_traffic) - { - gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ; - } - - //image->getLastPacketTimer()->reset(); - bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data); - if (!res) - { - delete[] data; - } -} - -// static -void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data) -{ - static LLCachedControl log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; - - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - - // Receives image packet, copy into image object, - // checks if all packets received, decompresses if so. - - LLUUID id; - U16 packet_num; - - char ip_string[256]; - u32_to_ip_string(msg->getSenderIP(),ip_string); - - U32Bytes received_size ; - if (msg->getReceiveCompressedSize()) - { - received_size = (U32Bytes)msg->getReceiveCompressedSize() ; - } - else - { - received_size = (U32Bytes)msg->getReceiveSize() ; - } - - add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, F64Bytes(received_size)); - add(LLStatViewer::TEXTURE_PACKETS, 1); - - //llprintline("Start decode, image header..."); - msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); - msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num); - S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); - - if (!data_size) - { - return; - } - if (data_size < 0) - { - // msg->getSizeFast() is probably trying to tell us there - // was an error. - LL_ERRS() << "image data chunk size was negative: " - << data_size << LL_ENDL; - return; - } - if (data_size > MTUBYTES) - { - LL_ERRS() << "image data chunk too large: " << data_size << " bytes" << LL_ENDL; - return; - } - U8 *data = new U8[data_size]; - msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); - - LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - if (!image) - { - delete [] data; - return; - } - if(log_texture_traffic) - { - gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ; - } - - //image->getLastPacketTimer()->reset(); - bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data); - if (!res) - { - delete[] data; - } -} - - // We've been that the asset server does not contain the requested image id. // static void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data) diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index fead2e52b2..04897e9868 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -95,8 +95,6 @@ public: static BOOL createUploadFile(const std::string& filename, const std::string& out_filename, const U8 codec); static LLPointer convertToUploadFile(LLPointer raw_image); static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); - static void receiveImageHeader(LLMessageSystem *msg, void **user_data); - static void receiveImagePacket(LLMessageSystem *msg, void **user_data); public: LLViewerTextureList(); -- cgit v1.2.3 From 2785f1f33d95348853d6c3e08a14f7627407b50c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 15 Jul 2022 20:23:12 +0300 Subject: SL-17741 Fixed wrong condition --- indra/newview/llinventorybridge.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 8ef0be4a00..458f5d2377 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2096,7 +2096,7 @@ BOOL LLItemBridge::confirmRemoveItem(const LLSD& notification, const LLSD& respo bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const { LLViewerInventoryItem* item = getItem(); - if (item) + if (!item) { return false; } -- cgit v1.2.3 From e9ac774ceb02e166c3cccf07cbc7c28bf4f001d8 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 26 May 2022 21:25:23 +0300 Subject: SL-17473 Viewer not clearing all Vertex Buffers in some cases Image thread doesn't need mBuffer and buffer isn't thread safe so no point allocating it in an image thread. --- indra/llrender/llimagegl.cpp | 2 +- indra/llrender/llrender.cpp | 77 +++++++++++++++++++++++++-------------- indra/llrender/llrender.h | 4 +- indra/llrender/llvertexbuffer.cpp | 2 +- indra/llrender/llvertexbuffer.h | 1 - indra/newview/llviewerwindow.cpp | 2 +- indra/newview/llvoavatar.cpp | 3 +- indra/newview/pipeline.cpp | 8 +++- 8 files changed, 64 insertions(+), 35 deletions(-) diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index 9bd3a0a6b0..46f0095c92 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -2432,7 +2432,7 @@ void LLImageGLThread::run() // We must perform setup on this thread before actually servicing our // WorkQueue, likewise cleanup afterwards. mWindow->makeContextCurrent(mContext); - gGL.init(); + gGL.init(false); ThreadPool::run(); gGL.shutdown(); mWindow->destroySharedContext(mContext); diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index a03a27cf94..72cca1f2a2 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -869,7 +869,7 @@ LLRender::~LLRender() shutdown(); } -void LLRender::init() +void LLRender::init(bool needs_vertex_buffer) { #if LL_WINDOWS if (gGLManager.mHasDebugOutput && gDebugGL) @@ -897,15 +897,27 @@ void LLRender::init() #endif } + if (needs_vertex_buffer) + { + initVertexBuffer(); + } +} - llassert_always(mBuffer.isNull()) ; - stop_glerror(); - mBuffer = new LLVertexBuffer(immediate_mask, 0); - mBuffer->allocateBuffer(4096, 0, TRUE); - mBuffer->getVertexStrider(mVerticesp); - mBuffer->getTexCoord0Strider(mTexcoordsp); - mBuffer->getColorStrider(mColorsp); - stop_glerror(); +void LLRender::initVertexBuffer() +{ + llassert_always(mBuffer.isNull()); + stop_glerror(); + mBuffer = new LLVertexBuffer(immediate_mask, 0); + mBuffer->allocateBuffer(4096, 0, TRUE); + mBuffer->getVertexStrider(mVerticesp); + mBuffer->getTexCoord0Strider(mTexcoordsp); + mBuffer->getColorStrider(mColorsp); + stop_glerror(); +} + +void LLRender::resetVertexBuffer() +{ + mBuffer = NULL; } void LLRender::shutdown() @@ -923,7 +935,7 @@ void LLRender::shutdown() delete mLightState[i]; } mLightState.clear(); - mBuffer = NULL ; + resetVertexBuffer(); } void LLRender::refreshState(void) @@ -1625,25 +1637,34 @@ void LLRender::flush() mCount = 0; - if (mBuffer->useVBOs() && !mBuffer->isLocked()) - { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata) - mBuffer->getVertexStrider(mVerticesp, 0, count); - mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count); - mBuffer->getColorStrider(mColorsp, 0, count); - } - - mBuffer->flush(); - mBuffer->setBuffer(immediate_mask); + if (mBuffer) + { + if (mBuffer->useVBOs() && !mBuffer->isLocked()) + { //hack to only flush the part of the buffer that was updated (relies on stream draw using buffersubdata) + mBuffer->getVertexStrider(mVerticesp, 0, count); + mBuffer->getTexCoord0Strider(mTexcoordsp, 0, count); + mBuffer->getColorStrider(mColorsp, 0, count); + } + + mBuffer->flush(); + mBuffer->setBuffer(immediate_mask); + + if (mMode == LLRender::QUADS && sGLCoreProfile) + { + mBuffer->drawArrays(LLRender::TRIANGLES, 0, count); + mQuadCycle = 1; + } + else + { + mBuffer->drawArrays(mMode, 0, count); + } + } + else + { + // mBuffer is present in main thread and not present in an image thread + LL_ERRS() << "A flush call from outside main rendering thread" << LL_ENDL; + } - if (mMode == LLRender::QUADS && sGLCoreProfile) - { - mBuffer->drawArrays(LLRender::TRIANGLES, 0, count); - mQuadCycle = 1; - } - else - { - mBuffer->drawArrays(mMode, 0, count); - } mVerticesp[0] = mVerticesp[count]; mTexcoordsp[0] = mTexcoordsp[count]; diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index e2489876e4..9c36c230fb 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -354,7 +354,9 @@ public: LLRender(); ~LLRender(); - void init() ; + void init(bool needs_vertex_buffer); + void initVertexBuffer(); + void resetVertexBuffer(); void shutdown(); // Refreshes renderer state to the cached values diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 6338cab96a..be3e6ddff0 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -1055,7 +1055,7 @@ void LLVertexBuffer::releaseIndices() bool LLVertexBuffer::createGLBuffer(U32 size) { - if (mGLBuffer) + if (mGLBuffer || mMappedData) { destroyGLBuffer(); } diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index baf8407fc6..3b3fe44984 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -265,7 +265,6 @@ public: bool getTangentStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getTangentStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getColorStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getTextureIndexStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getEmissiveStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getWeightStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getWeight4Strider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 24e4a02b61..bc69fd80db 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1998,7 +1998,7 @@ LLViewerWindow::LLViewerWindow(const Params& p) } LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; - gGL.init() ; + gGL.init(true); if (LLFeatureManager::getInstance()->isSafe() || (gSavedSettings.getS32("LastFeatureVersion") != LLFeatureManager::getInstance()->getVersion()) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 314c22eb6c..b0a7aff2d4 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2810,6 +2810,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) if (detailed_update) { U32 draw_order = 0; + S32 attachment_selected = LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment(); for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); iter != mAttachmentPoints.end(); ++iter) @@ -2849,7 +2850,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update) } // if selecting any attachments, update all of them as non-damped - if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() && LLSelectMgr::getInstance()->getSelection()->isAttachment()) + if (attachment_selected) { gPipeline.updateMoveNormalAsync(attached_object->mDrawable); } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 5bf62f0524..bc63c3ffe3 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7243,6 +7243,7 @@ void LLPipeline::doResetVertexBuffers(bool forced) mResetVertexBuffers = false; mCubeVB = NULL; + mDeferredVB = NULL; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -7276,10 +7277,11 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLPathingLib::getInstance()->cleanupVBOManager(); } LLVOPartGroup::destroyGL(); + gGL.resetVertexBuffer(); SUBSYSTEM_CLEANUP(LLVertexBuffer); - if (LLVertexBuffer::sGLCount > 0) + if (LLVertexBuffer::sGLCount != 0) { LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL; } @@ -7300,6 +7302,10 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping); + gGL.initVertexBuffer(); + + mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); + mDeferredVB->allocateBuffer(8, 0, true); LLVOPartGroup::restoreGL(); } -- cgit v1.2.3 From e9288e8112d663cb3bea644071adf3b2471ef5f4 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 16 Jul 2022 02:21:13 +0300 Subject: SL-17473 Viewer not clearing all Vertex Buffers #2 --- indra/newview/llsky.h | 1 - indra/newview/llvoground.h | 1 - indra/newview/llworld.cpp | 38 +++++++++++++++++++++++++++----------- indra/newview/llworld.h | 11 ++++++----- indra/newview/pipeline.cpp | 12 +++++++++++- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h index 8c0d70c16c..ec0de1fbfd 100644 --- a/indra/newview/llsky.h +++ b/indra/newview/llsky.h @@ -39,7 +39,6 @@ class LLViewerCamera; class LLVOWLSky; -class LLVOWLClouds; class LLSky diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h index a53f309e46..e7033290c7 100644 --- a/indra/newview/llvoground.h +++ b/indra/newview/llvoground.h @@ -49,7 +49,6 @@ public: /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - void cleanupGL(); }; #endif // LL_LLVOGROUND_H diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index 8abb49fba8..5d6e8611a7 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -93,7 +93,7 @@ LLWorld::LLWorld() : mLastPacketsLost(0), mSpaceTimeUSec(0) { - for (S32 i = 0; i < 8; i++) + for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++) { mEdgeWaterObjects[i] = NULL; } @@ -126,7 +126,7 @@ void LLWorld::resetClass() LLViewerPartSim::getInstance()->destroyClass(); mDefaultWaterTexturep = NULL ; - for (S32 i = 0; i < 8; i++) + for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++) { mEdgeWaterObjects[i] = NULL; } @@ -753,6 +753,8 @@ void LLWorld::clearAllVisibleObjects() //clear all cached visible objects. (*iter)->clearCachedVisibleObjects(); } + clearHoleWaterObjects(); + clearEdgeWaterObjects(); } void LLWorld::updateParticles() @@ -923,7 +925,7 @@ void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool inc } S32 dir; - for (dir = 0; dir < 8; dir++) + for (dir = 0; dir < EDGE_WATER_OBJECTS_COUNT; dir++) { LLVOWater* waterp = mEdgeWaterObjects[dir]; if (waterp && waterp->mDrawable) @@ -934,6 +936,26 @@ void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool inc } } +void LLWorld::clearHoleWaterObjects() +{ + for (std::list >::iterator iter = mHoleWaterObjects.begin(); + iter != mHoleWaterObjects.end(); ++iter) + { + LLVOWater* waterp = (*iter).get(); + gObjectList.killObject(waterp); + } + mHoleWaterObjects.clear(); +} + +void LLWorld::clearEdgeWaterObjects() +{ + for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++) + { + gObjectList.killObject(mEdgeWaterObjects[i]); + mEdgeWaterObjects[i] = NULL; + } +} + void LLWorld::updateWaterObjects() { if (!gAgent.getRegion()) @@ -977,13 +999,7 @@ void LLWorld::updateWaterObjects() } } - for (std::list >::iterator iter = mHoleWaterObjects.begin(); - iter != mHoleWaterObjects.end(); ++ iter) - { - LLVOWater* waterp = (*iter).get(); - gObjectList.killObject(waterp); - } - mHoleWaterObjects.clear(); + clearHoleWaterObjects(); // Use the water height of the region we're on for areas where there is no region F32 water_height = gAgent.getRegion()->getWaterHeight(); @@ -1024,7 +1040,7 @@ void LLWorld::updateWaterObjects() (S32)(512 - (region_y - min_y)) }; S32 dir; - for (dir = 0; dir < 8; dir++) + for (dir = 0; dir < EDGE_WATER_OBJECTS_COUNT; dir++) { S32 dim[2] = { 0 }; switch (gDirAxes[dir][0]) diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 5c43cdf4e2..b6d3fcf7b1 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -122,12 +122,9 @@ public: void updateRegions(F32 max_update_time); void updateVisibilities(); void updateParticles(); - void updateClouds(const F32 dt); - LLCloudGroup * findCloudGroup(const LLCloudPuff &puff); void renderPropertyLines(); - void resetStats(); void updateNetStats(); // Update network statistics for all the regions... void printPacketsLost(); @@ -140,7 +137,7 @@ public: void setLandFarClip(const F32 far_clip); LLViewerTexture *getDefaultWaterTexture(); - void updateWaterObjects(); + void updateWaterObjects(); void precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water); @@ -175,6 +172,9 @@ public: bool isRegionListed(const LLViewerRegion* region) const; private: + void clearHoleWaterObjects(); + void clearEdgeWaterObjects(); + region_list_t mActiveRegionList; region_list_t mRegionList; region_list_t mVisibleRegionList; @@ -206,7 +206,8 @@ private: // std::list > mHoleWaterObjects; - LLPointer mEdgeWaterObjects[8]; + static const S32 EDGE_WATER_OBJECTS_COUNT = 8; + LLPointer mEdgeWaterObjects[EDGE_WATER_OBJECTS_COUNT]; LLPointer mDefaultWaterTexturep; }; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index bc63c3ffe3..64ecb8b297 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -685,7 +685,9 @@ void LLPipeline::cleanup() mFaceSelectImagep = NULL; - mMovedBridge.clear(); + mMovedList.clear(); + mMovedBridge.clear(); + mShiftList.clear(); mInitialized = false; @@ -2822,6 +2824,14 @@ void LLPipeline::clearRebuildDrawables() drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); } mMovedList.clear(); + + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); + iter != mShiftList.end(); ++iter) + { + LLDrawable *drawablep = *iter; + drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD | LLDrawable::ON_SHIFT_LIST); + } + mShiftList.clear(); } void LLPipeline::rebuildPriorityGroups() -- cgit v1.2.3 From 38cc06e43a92a10d73ab149944b3cff19b8da8ad Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 18 Jul 2022 16:53:43 +0300 Subject: SL-17785 FIXED World Map scrolls too slowly when searching for a region. --- indra/newview/llfloaterworldmap.cpp | 4 ++-- indra/newview/llworldmapview.cpp | 19 ++++++++++++++----- indra/newview/llworldmapview.h | 3 +++ 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index e7b1efb41d..6bb0ed73e4 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -1333,9 +1333,9 @@ void LLFloaterWorldMap::centerOnTarget(BOOL animate) } F64 map_scale = (F64)mMapView->getScale(); - mMapView->setPan(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)), + mMapView->setPanWithInterpTime(-llfloor((F32)(pos_global.mdV[VX] * map_scale / REGION_WIDTH_METERS)), -llfloor((F32)(pos_global.mdV[VY] * map_scale / REGION_WIDTH_METERS)), - !animate); + !animate, 0.1f); mWaitingForTracker = FALSE; } diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 2ac4b30d2e..6e994b4e68 100755 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -185,7 +185,8 @@ LLWorldMapView::LLWorldMapView() : mMouseDownY(0), mSelectIDStart(0), mMapScale(0.f), - mTargetMapScale(0.f) + mTargetMapScale(0.f), + mMapIterpTime(MAP_ITERP_TIME_CONSTANT) { // LL_INFOS("WorldMap") << "Creating the Map -> LLWorldMapView::LLWorldMapView()" << LL_ENDL; @@ -283,7 +284,7 @@ void LLWorldMapView::setScale(F32 scale, bool snap) { mMapScale = 0.1f; } - + mMapIterpTime = MAP_ITERP_TIME_CONSTANT; F32 ratio = (scale / old_scale); mPanX *= ratio; mPanY *= ratio; @@ -325,6 +326,7 @@ void LLWorldMapView::translatePan(S32 delta_x, S32 delta_y) // static void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap) { + mMapIterpTime = MAP_ITERP_TIME_CONSTANT; mTargetPanX = (F32) x; mTargetPanY = (F32) y; if (snap) @@ -335,6 +337,13 @@ void LLWorldMapView::setPan(S32 x, S32 y, BOOL snap) sVisibleTilesLoaded = false; } +// static +void LLWorldMapView::setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time) +{ + setPan(x, y, snap); + mMapIterpTime = interp_time; +} + bool LLWorldMapView::showRegionInfo() { return (LLWorldMipmap::scaleToLevel(mMapScale) <= DRAW_SIMINFO_THRESHOLD ? true : false); } /////////////////////////////////////////////////////////////////////////////////// @@ -357,9 +366,9 @@ void LLWorldMapView::draw() mVisibleRegions.clear(); - // animate pan if necessary - mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); - mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(MAP_ITERP_TIME_CONSTANT)); + // animate pan if necessary + mPanX = lerp(mPanX, mTargetPanX, LLSmoothInterpolation::getInterpolant(mMapIterpTime)); + mPanY = lerp(mPanY, mTargetPanY, LLSmoothInterpolation::getInterpolant(mMapIterpTime)); //RN: snaps to zoom value because interpolation caused jitter in the text rendering if (!sZoomTimer.getStarted() && mMapScale != mTargetMapScale) diff --git a/indra/newview/llworldmapview.h b/indra/newview/llworldmapview.h index edbdded120..ce8af76a82 100644 --- a/indra/newview/llworldmapview.h +++ b/indra/newview/llworldmapview.h @@ -80,6 +80,7 @@ public: // Pan is in pixels relative to the center of the map. void translatePan( S32 delta_x, S32 delta_y ); void setPan( S32 x, S32 y, BOOL snap = TRUE ); + void setPanWithInterpTime(S32 x, S32 y, BOOL snap, F32 interp_time); // Return true if the current scale level is above the threshold for accessing region info bool showRegionInfo(); @@ -212,6 +213,8 @@ private: static F32 sMapScaleSetting; static LLVector2 sZoomPivot; static LLFrameTimer sZoomTimer; + + F32 mMapIterpTime; }; #endif -- cgit v1.2.3 From f55ca2239bbd48a4762829db47db6a063b1e9d4e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 18 Jul 2022 18:10:22 +0300 Subject: Fix mac build issue --- indra/newview/llworld.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index b6d3fcf7b1..5dee8eea0f 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -198,8 +198,6 @@ private: U32 mNumOfActiveCachedObjects; U64MicrosecondsImplicit mSpaceTimeUSec; - BOOL mClassicCloudsEnabled; - //////////////////////////// // // Data for "Fake" objects -- cgit v1.2.3 From 477f173ad55ca145ff027cb54f86c6553cf6f62d Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 19 Jul 2022 01:25:30 +0300 Subject: SL-16745 Some checkboxes are truncated after changing 'UI size' --- indra/llui/llcheckboxctrl.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 08da599ef2..362fe0c19e 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -203,11 +203,9 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) // it will work fine in case of decrease of space, but if we get more space or text // becomes longer, label will fail to grow so reinit label's dimentions. - static LLUICachedControl llcheckboxctrl_hpad("UICheckboxctrlHPad", 0); LLRect label_rect = mLabel->getRect(); - S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad; - label_rect.mRight = label_rect.mLeft + new_width; - mLabel->setRect(label_rect); + S32 new_width = rect.getWidth() - label_rect.mLeft; + mLabel->reshape(new_width, label_rect.getHeight(), TRUE); S32 label_top = label_rect.mTop; mLabel->reshapeToFitText(TRUE); -- cgit v1.2.3 From fcb3b6917c852779a846673bd8b35cdc2fda6bb7 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 19 Jul 2022 18:56:59 +0300 Subject: SL-17670 Simplify outfit snapshot floater --- indra/newview/CMakeLists.txt | 4 +- indra/newview/llappviewer.cpp | 4 +- indra/newview/llfloateroutfitsnapshot.cpp | 373 --------------------- indra/newview/llfloateroutfitsnapshot.h | 123 ------- indra/newview/llfloatersimpleoutfitsnapshot.cpp | 328 ++++++++++++++++++ indra/newview/llfloatersimpleoutfitsnapshot.h | 129 +++++++ indra/newview/llfloatersnapshot.cpp | 12 +- indra/newview/llfloatersnapshot.h | 9 +- indra/newview/lloutfitgallery.cpp | 6 +- indra/newview/llsnapshotlivepreview.cpp | 3 +- indra/newview/llsnapshotlivepreview.h | 2 +- indra/newview/llviewerassetupload.cpp | 11 - indra/newview/llviewerfloaterreg.cpp | 4 +- indra/newview/llviewermenufile.cpp | 6 +- .../default/xui/en/floater_outfit_snapshot.xml | 351 ------------------- .../xui/en/floater_simple_outfit_snapshot.xml | 50 +++ 16 files changed, 535 insertions(+), 880 deletions(-) delete mode 100644 indra/newview/llfloateroutfitsnapshot.cpp delete mode 100644 indra/newview/llfloateroutfitsnapshot.h create mode 100644 indra/newview/llfloatersimpleoutfitsnapshot.cpp create mode 100644 indra/newview/llfloatersimpleoutfitsnapshot.h delete mode 100644 indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml create mode 100644 indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index c577d062f9..adfa772269 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -285,9 +285,9 @@ set(viewer_SOURCE_FILES llfloaternotificationsconsole.cpp llfloaternotificationstabbed.cpp llfloateroutfitphotopreview.cpp - llfloateroutfitsnapshot.cpp llfloaterobjectweights.cpp llfloateropenobject.cpp + llfloatersimpleoutfitsnapshot.cpp llfloaterpathfindingcharacters.cpp llfloaterpathfindingconsole.cpp llfloaterpathfindinglinksets.cpp @@ -924,9 +924,9 @@ set(viewer_HEADER_FILES llfloaternotificationsconsole.h llfloaternotificationstabbed.h llfloateroutfitphotopreview.h - llfloateroutfitsnapshot.h llfloaterobjectweights.h llfloateropenobject.h + llfloatersimpleoutfitsnapshot.h llfloaterpathfindingcharacters.h llfloaterpathfindingconsole.h llfloaterpathfindinglinksets.h diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index f54093d9d0..997d04fb9c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -209,7 +209,7 @@ #include "llcommandlineparser.h" #include "llfloatermemleak.h" #include "llfloaterreg.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llfloatersnapshot.h" #include "llsidepanelinventory.h" #include "llatmosphere.h" @@ -1519,7 +1519,7 @@ bool LLAppViewer::doFrame() LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" ) pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots - LLFloaterOutfitSnapshot::update(); + LLFloaterSimpleOutfitSnapshot::update(); gGLActive = FALSE; } } diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp deleted file mode 100644 index dccef88e41..0000000000 --- a/indra/newview/llfloateroutfitsnapshot.cpp +++ /dev/null @@ -1,373 +0,0 @@ -/** - * @file llfloateroutfitsnapshot.cpp - * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2016, 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 "llfloatersnapshot.h" -#include "llfloateroutfitsnapshot.h" - -#include "llagent.h" -#include "llfloaterreg.h" -#include "llimagefiltersmanager.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llpostcard.h" -#include "llresmgr.h" // LLLocale -#include "llsdserialize.h" -#include "llsidetraypanelcontainer.h" -#include "llspinctrl.h" -#include "llviewercontrol.h" -#include "lltoolfocus.h" -#include "lltoolmgr.h" -#include "llwebprofile.h" - -///---------------------------------------------------------------------------- -/// Local function declarations, constants, enums, and typedefs -///---------------------------------------------------------------------------- -LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL; - -const S32 OUTFIT_SNAPSHOT_WIDTH = 256; -const S32 OUTFIT_SNAPSHOT_HEIGHT = 256; - -static LLDefaultChildRegistry::Register r("snapshot_outfit_floater_view"); - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot::Impl -///---------------------------------------------------------------------------- - -// virtual -LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found) -{ - LLPanel* panel = floater->getChild("panel_outfit_snapshot_inventory"); - LLPanelSnapshot* active_panel = dynamic_cast(panel); - if (!ok_if_not_found) - { - llassert_always(active_panel != NULL); - } - return active_panel; -} - -// virtual -LLSnapshotModel::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) -{ - return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; -} - -// virtual -LLSnapshotModel::ESnapshotLayerType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) -{ - return LLSnapshotModel::SNAPSHOT_TYPE_COLOR; -} - -// This is the main function that keeps all the GUI controls in sync with the saved settings. -// It should be called anytime a setting is changed that could affect the controls. -// No other methods should be changing any of the controls directly except for helpers called by this method. -// The basic pattern for programmatically changing the GUI settings is to first set the -// appropriate saved settings and then call this method to sync the GUI with them. -// FIXME: The above comment seems obsolete now. -// virtual -void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) -{ - LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater); - LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); - LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater); - - LLSnapshotLivePreview* previewp = getPreviewView(); - BOOL got_snap = previewp && previewp->getSnapshotUpToDate(); - - // *TODO: Separate maximum size for Web images from postcards - LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL; - - LLLocale locale(LLLocale::USER_LOCALE); - std::string bytes_string; - if (got_snap) - { - LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10); - } - - // Update displayed image resolution. - LLTextBox* image_res_tb = floater->getChild("image_res_text"); - image_res_tb->setVisible(got_snap); - if (got_snap) - { - image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth())); - image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight())); - } - - floater->getChild("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown")); - floater->getChild("file_size_label")->setColor(LLUIColorTable::instance().getColor("LabelTextColor")); - - updateResolution(floater); - - if (previewp) - { - previewp->setSnapshotType(shot_type); - previewp->setSnapshotFormat(shot_format); - previewp->setSnapshotBufferType(layer_type); - } - - LLPanelSnapshot* current_panel = Impl::getActivePanel(floater); - if (current_panel) - { - LLSD info; - info["have-snapshot"] = got_snap; - current_panel->updateControls(info); - } - LL_DEBUGS() << "finished updating controls" << LL_ENDL; -} - -// virtual -std::string LLFloaterOutfitSnapshot::Impl::getSnapshotPanelPrefix() -{ - return "panel_outfit_snapshot_"; -} - -// Show/hide upload status message. -// virtual -void LLFloaterOutfitSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg) -{ - mFloater->setSuccessLabelPanelVisible(finished && ok); - mFloater->setFailureLabelPanelVisible(finished && !ok); - - if (finished) - { - LLUICtrl* finished_lbl = mFloater->getChild(ok ? "succeeded_lbl" : "failed_lbl"); - std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str")); - finished_lbl->setValue(result_text); - - LLPanel* snapshot_panel = mFloater->getChild("panel_outfit_snapshot_inventory"); - snapshot_panel->onOpen(LLSD()); - } -} - -void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data) -{ - LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data; - - if (!view) - { - llassert(view); - return; - } - - S32 width = OUTFIT_SNAPSHOT_WIDTH; - S32 height = OUTFIT_SNAPSHOT_HEIGHT; - - LLSnapshotLivePreview* previewp = getPreviewView(); - if (previewp) - { - S32 original_width = 0, original_height = 0; - previewp->getSize(original_width, original_height); - - if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot")) - { //clamp snapshot resolution to window size when showing UI or HUD in snapshot - width = llmin(width, gViewerWindow->getWindowWidthRaw()); - height = llmin(height, gViewerWindow->getWindowHeightRaw()); - } - - - llassert(width > 0 && height > 0); - - // use the resolution from the selected pre-canned drop-down choice - LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL; - previewp->setSize(width, height); - - if (original_width != width || original_height != height) - { - // hide old preview as the aspect ratio could be wrong - checkAutoSnapshot(previewp, FALSE); - LL_DEBUGS() << "updating thumbnail" << LL_ENDL; - previewp->updateSnapshot(TRUE); - } - } -} - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot -///---------------------------------------------------------------------------- - -// Default constructor -LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key) -: LLFloaterSnapshotBase(key), -mOutfitGallery(NULL) -{ - impl = new Impl(this); -} - -LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot() -{ -} - -// virtual -BOOL LLFloaterOutfitSnapshot::postBuild() -{ - mRefreshBtn = getChild("new_snapshot_btn"); - childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); - mRefreshLabel = getChild("refresh_lbl"); - mSucceessLblPanel = getChild("succeeded_panel"); - mFailureLblPanel = getChild("failed_panel"); - - childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this); - getChild("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot")); - - childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this); - getChild("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot")); - - getChild("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame")); - childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this); - - getChild("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot")); - childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this); - - getChild("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this)); - getChild("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this)); - - // Filters - LLComboBox* filterbox = getChild("filters_combobox"); - std::vector filter_list = LLImageFiltersManager::getInstance()->getFiltersList(); - for (U32 i = 0; i < filter_list.size(); i++) - { - filterbox->add(filter_list[i]); - } - childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this); - - mThumbnailPlaceholder = getChild("thumbnail_placeholder"); - - // create preview window - LLRect full_screen_rect = getRootView()->getRect(); - LLSnapshotLivePreview::Params p; - p.rect(full_screen_rect); - LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); - LLView* parent_view = gSnapshotFloaterView->getParent(); - - parent_view->removeChild(gSnapshotFloaterView); - // make sure preview is below snapshot floater - parent_view->addChild(previewp); - parent_view->addChild(gSnapshotFloaterView); - - //move snapshot floater to special purpose snapshotfloaterview - gFloaterView->removeChild(this); - gSnapshotFloaterView->addChild(this); - - impl->mPreviewHandle = previewp->getHandle(); - previewp->setContainer(this); - impl->updateControls(this); - impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); - impl->updateLayout(this); - - previewp->mKeepAspectRatio = FALSE; - previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); - - return TRUE; -} - -// virtual -void LLFloaterOutfitSnapshot::onOpen(const LLSD& key) -{ - LLSnapshotLivePreview* preview = getPreviewView(); - if (preview) - { - LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL; - preview->updateSnapshot(TRUE); - } - focusFirstItem(FALSE); - gSnapshotFloaterView->setEnabled(TRUE); - gSnapshotFloaterView->setVisible(TRUE); - gSnapshotFloaterView->adjustToFitScreen(this, FALSE); - - impl->updateControls(this); - impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); - impl->updateLayout(this); - - LLPanel* snapshot_panel = getChild("panel_outfit_snapshot_inventory"); - snapshot_panel->onOpen(LLSD()); - postPanelSwitch(); - -} - -void LLFloaterOutfitSnapshot::onExtendFloater() -{ - impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); -} - -// static -void LLFloaterOutfitSnapshot::update() -{ - LLFloaterOutfitSnapshot* inst = findInstance(); - if (inst != NULL) - { - inst->impl->updateLivePreview(); - } -} - - -// static -LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance() -{ - return LLFloaterReg::findTypedInstance("outfit_snapshot"); -} - -// static -LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance() -{ - return LLFloaterReg::getTypedInstance("outfit_snapshot"); -} - -// virtual -void LLFloaterOutfitSnapshot::saveTexture() -{ - LL_DEBUGS() << "saveTexture" << LL_ENDL; - - LLSnapshotLivePreview* previewp = getPreviewView(); - if (!previewp) - { - llassert(previewp != NULL); - return; - } - - if (mOutfitGallery) - { - mOutfitGallery->onBeforeOutfitSnapshotSave(); - } - previewp->saveTexture(TRUE, getOutfitID().asString()); - if (mOutfitGallery) - { - mOutfitGallery->onAfterOutfitSnapshotSave(); - } - closeFloater(); -} - -///---------------------------------------------------------------------------- -/// Class LLOutfitSnapshotFloaterView -///---------------------------------------------------------------------------- - -LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p) -{ -} - -LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView() -{ -} diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h deleted file mode 100644 index bee386ec63..0000000000 --- a/indra/newview/llfloateroutfitsnapshot.h +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file llfloateroutfitsnapshot.h - * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2016, 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_LLFLOATEROUTFITSNAPSHOT_H -#define LL_LLFLOATEROUTFITSNAPSHOT_H - -#include "llfloater.h" -#include "llfloatersnapshot.h" -#include "lloutfitgallery.h" -#include "llsnapshotlivepreview.h" - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot -///---------------------------------------------------------------------------- - -class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase -{ - LOG_CLASS(LLFloaterOutfitSnapshot); - -public: - - LLFloaterOutfitSnapshot(const LLSD& key); - /*virtual*/ ~LLFloaterOutfitSnapshot(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - - static void update(); - - void onExtendFloater(); - - static LLFloaterOutfitSnapshot* getInstance(); - static LLFloaterOutfitSnapshot* findInstance(); - /*virtual*/ void saveTexture(); - - const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } - - void setOutfitID(LLUUID id) { mOutfitID = id; } - LLUUID getOutfitID() { return mOutfitID; } - void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } - - class Impl; - friend class Impl; -private: - - LLUUID mOutfitID; - LLOutfitGallery* mOutfitGallery; -}; - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot::Impl -///---------------------------------------------------------------------------- - -class LLFloaterOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase -{ - LOG_CLASS(LLFloaterOutfitSnapshot::Impl); -public: - Impl(LLFloaterSnapshotBase* floater) - : LLFloaterSnapshotBase::ImplBase(floater) - {} - ~Impl() - {} - void updateResolution(void* data); - - static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status); - - /*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true); - /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater); - /*virtual*/ std::string getSnapshotPanelPrefix(); - - /*virtual*/ void updateControls(LLFloaterSnapshotBase* floater); - -private: - /*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater); - /*virtual*/ void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null); -}; - -///---------------------------------------------------------------------------- -/// Class LLOutfitSnapshotFloaterView -///---------------------------------------------------------------------------- - -class LLOutfitSnapshotFloaterView : public LLFloaterView -{ -public: - struct Params - : public LLInitParam::Block - { - }; - -protected: - LLOutfitSnapshotFloaterView(const Params& p); - friend class LLUICtrlFactory; - -public: - virtual ~LLOutfitSnapshotFloaterView(); -}; - -extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView; - -#endif // LL_LLFLOATEROUTFITSNAPSHOT_H diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.cpp b/indra/newview/llfloatersimpleoutfitsnapshot.cpp new file mode 100644 index 0000000000..181e2ba10e --- /dev/null +++ b/indra/newview/llfloatersimpleoutfitsnapshot.cpp @@ -0,0 +1,328 @@ +/** +* @file llfloatersimpleoutfitsnapshot.cpp +* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery +* +* $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 "llfloatersimpleoutfitsnapshot.h" + +#include "llfloaterreg.h" +#include "llimagefiltersmanager.h" +#include "llstatusbar.h" // can_afford_transaction() +#include "llnotificationsutil.h" +#include "llagentbenefits.h" +#include "llviewercontrol.h" + +LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView = NULL; + +const S32 OUTFIT_SNAPSHOT_WIDTH = 256; +const S32 OUTFIT_SNAPSHOT_HEIGHT = 256; + +static LLDefaultChildRegistry::Register r("simple_snapshot_outfit_floater_view"); + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleOutfitSnapshot::Impl +///---------------------------------------------------------------------------- + +LLSnapshotModel::ESnapshotFormat LLFloaterSimpleOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; +} + +LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_TYPE_COLOR; +} + +void LLFloaterSimpleOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + updateResolution(floater); + if (previewp) + { + previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE); + previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG); + previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR); + } +} + +std::string LLFloaterSimpleOutfitSnapshot::Impl::getSnapshotPanelPrefix() +{ + return "panel_outfit_snapshot_"; +} + +void LLFloaterSimpleOutfitSnapshot::Impl::updateResolution(void* data) +{ + LLFloaterSimpleOutfitSnapshot *view = (LLFloaterSimpleOutfitSnapshot *)data; + + if (!view) + { + llassert(view); + return; + } + + S32 width = OUTFIT_SNAPSHOT_WIDTH; + S32 height = OUTFIT_SNAPSHOT_HEIGHT; + + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) + { + S32 original_width = 0, original_height = 0; + previewp->getSize(original_width, original_height); + + if (gSavedSettings.getBOOL("RenderHUDInSnapshot")) + { //clamp snapshot resolution to window size when showing UI HUD in snapshot + width = llmin(width, gViewerWindow->getWindowWidthRaw()); + height = llmin(height, gViewerWindow->getWindowHeightRaw()); + } + + llassert(width > 0 && height > 0); + + previewp->setSize(width, height); + + if (original_width != width || original_height != height) + { + // hide old preview as the aspect ratio could be wrong + checkAutoSnapshot(previewp, FALSE); + previewp->updateSnapshot(TRUE); + } + } +} + +void LLFloaterSimpleOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg) +{ + switch (status) + { + case STATUS_READY: + mFloater->setCtrlsEnabled(true); + break; + case STATUS_WORKING: + mFloater->setCtrlsEnabled(false); + break; + case STATUS_FINISHED: + mFloater->setCtrlsEnabled(true); + break; + } + + mStatus = status; +} + +///----------------------------------------------------------------re------------ +/// Class LLFloaterSimpleOutfitSnapshot +///---------------------------------------------------------------------------- + +LLFloaterSimpleOutfitSnapshot::LLFloaterSimpleOutfitSnapshot(const LLSD& key) + : LLFloaterSnapshotBase(key), + mOutfitGallery(NULL) +{ + impl = new Impl(this); +} + +LLFloaterSimpleOutfitSnapshot::~LLFloaterSimpleOutfitSnapshot() +{ +} + +BOOL LLFloaterSimpleOutfitSnapshot::postBuild() +{ + getChild("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost())); + + childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); + childSetAction("save_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onSend, this)); + childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onCancel, this)); + + mThumbnailPlaceholder = getChild("thumbnail_placeholder"); + + // create preview window + LLRect full_screen_rect = getRootView()->getRect(); + LLSnapshotLivePreview::Params p; + p.rect(full_screen_rect); + LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); + LLView* parent_view = gSnapshotFloaterView->getParent(); + + parent_view->removeChild(gSnapshotFloaterView); + // make sure preview is below snapshot floater + parent_view->addChild(previewp); + parent_view->addChild(gSnapshotFloaterView); + + //move snapshot floater to special purpose snapshotfloaterview + gFloaterView->removeChild(this); + gSnapshotFloaterView->addChild(this); + + impl->mPreviewHandle = previewp->getHandle(); + previewp->setContainer(this); + impl->updateControls(this); + impl->setAdvanced(true); + impl->setSkipReshaping(true); + + previewp->mKeepAspectRatio = FALSE; + previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); + previewp->setAllowRenderUI(false); + + return TRUE; +} +const S32 PREVIEW_OFFSET_X = 2; +const S32 PREVIEW_OFFSET_Y = 63; + +void LLFloaterSimpleOutfitSnapshot::draw() +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + + if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock())) + { + // don't render snapshot window in snapshot, even if "show ui" is turned on + return; + } + + LLFloater::draw(); + + if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible()) + { + if(previewp->getThumbnailImage()) + { + bool working = impl->getStatus() == ImplBase::STATUS_WORKING; + const LLRect& thumbnail_rect = getThumbnailPlaceholderRect(); + const S32 thumbnail_w = previewp->getThumbnailWidth(); + const S32 thumbnail_h = previewp->getThumbnailHeight(); + + S32 offset_x = PREVIEW_OFFSET_X; + S32 offset_y = PREVIEW_OFFSET_Y; + + gGL.matrixMode(LLRender::MM_MODELVIEW); + // Apply floater transparency to the texture unless the floater is focused. + F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + LLColor4 color = working ? LLColor4::grey4 : LLColor4::white; + gl_draw_scaled_image(offset_x, offset_y, + thumbnail_w, thumbnail_h, + previewp->getThumbnailImage(), color % alpha); + std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "FloaterFocusBackgroundColor" : "DkGray"; + previewp->drawPreviewRect(offset_x, offset_y, LLUIColorTable::instance().getColor(alpha_color)); + + gGL.pushUIMatrix(); + LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom); + mThumbnailPlaceholder->draw(); + gGL.popUIMatrix(); + } + } + impl->updateLayout(this); +} + +void LLFloaterSimpleOutfitSnapshot::onOpen(const LLSD& key) +{ + LLSnapshotLivePreview* preview = getPreviewView(); + if (preview) + { + preview->updateSnapshot(TRUE); + } + focusFirstItem(FALSE); + gSnapshotFloaterView->setEnabled(TRUE); + gSnapshotFloaterView->setVisible(TRUE); + gSnapshotFloaterView->adjustToFitScreen(this, FALSE); + + impl->updateControls(this); + impl->setStatus(ImplBase::STATUS_READY); +} + +void LLFloaterSimpleOutfitSnapshot::onCancel() +{ + closeFloater(); +} + +void LLFloaterSimpleOutfitSnapshot::onSend() +{ + S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); + if (can_afford_transaction(expected_upload_cost)) + { + saveTexture(); + postSave(); + } + else + { + LLSD args; + args["COST"] = llformat("%d", expected_upload_cost); + LLNotificationsUtil::add("ErrorPhotoCannotAfford", args); + inventorySaveFailed(); + } +} + +void LLFloaterSimpleOutfitSnapshot::postSave() +{ + impl->setStatus(ImplBase::STATUS_WORKING); +} + +// static +void LLFloaterSimpleOutfitSnapshot::update() +{ + LLFloaterSimpleOutfitSnapshot* inst = findInstance(); + if (inst != NULL) + { + inst->impl->updateLivePreview(); + } +} + + +// static +LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::findInstance() +{ + return LLFloaterReg::findTypedInstance("simple_outfit_snapshot"); +} + +// static +LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::getInstance() +{ + return LLFloaterReg::getTypedInstance("simple_outfit_snapshot"); +} + +void LLFloaterSimpleOutfitSnapshot::saveTexture() +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + if (!previewp) + { + llassert(previewp != NULL); + return; + } + + if (mOutfitGallery) + { + mOutfitGallery->onBeforeOutfitSnapshotSave(); + } + previewp->saveTexture(TRUE, getOutfitID().asString()); + if (mOutfitGallery) + { + mOutfitGallery->onAfterOutfitSnapshotSave(); + } + closeFloater(); +} + +///---------------------------------------------------------------------------- +/// Class LLSimpleOutfitSnapshotFloaterView +///---------------------------------------------------------------------------- + +LLSimpleOutfitSnapshotFloaterView::LLSimpleOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p) +{ +} + +LLSimpleOutfitSnapshotFloaterView::~LLSimpleOutfitSnapshotFloaterView() +{ +} diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.h b/indra/newview/llfloatersimpleoutfitsnapshot.h new file mode 100644 index 0000000000..cc9a6c5d1e --- /dev/null +++ b/indra/newview/llfloatersimpleoutfitsnapshot.h @@ -0,0 +1,129 @@ +/** +* @file llfloatersimpleoutfitsnapshot.h +* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery +* +* $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$ +*/ + +#ifndef LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H +#define LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H + +#include "llfloater.h" +#include "llfloatersnapshot.h" +#include "lloutfitgallery.h" +#include "llsnapshotlivepreview.h" + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleOutfitSnapshot +///---------------------------------------------------------------------------- + +class LLFloaterSimpleOutfitSnapshot : public LLFloaterSnapshotBase +{ + LOG_CLASS(LLFloaterSimpleOutfitSnapshot); + +public: + + LLFloaterSimpleOutfitSnapshot(const LLSD& key); + ~LLFloaterSimpleOutfitSnapshot(); + + BOOL postBuild(); + void onOpen(const LLSD& key); + void draw(); + + static void update(); + + static LLFloaterSimpleOutfitSnapshot* getInstance(); + static LLFloaterSimpleOutfitSnapshot* findInstance(); + void saveTexture(); + + const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } + + void setOutfitID(LLUUID id) { mOutfitID = id; } + LLUUID getOutfitID() { return mOutfitID; } + void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } + + void postSave(); + + class Impl; + friend class Impl; + +private: + void onSend(); + void onCancel(); + + LLUUID mOutfitID; + LLOutfitGallery* mOutfitGallery; +}; + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleOutfitSnapshot::Impl +///---------------------------------------------------------------------------- + +class LLFloaterSimpleOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase +{ + LOG_CLASS(LLFloaterSimpleOutfitSnapshot::Impl); +public: + Impl(LLFloaterSnapshotBase* floater) + : LLFloaterSnapshotBase::ImplBase(floater) + {} + ~Impl() + {} + void updateResolution(void* data); + + static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status); + + LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) { return NULL; } + LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater); + std::string getSnapshotPanelPrefix(); + + void updateControls(LLFloaterSnapshotBase* floater); + + void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null); + +private: + LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater); + void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null) {}; +}; + +///---------------------------------------------------------------------------- +/// Class LLSimpleOutfitSnapshotFloaterView +///---------------------------------------------------------------------------- + +class LLSimpleOutfitSnapshotFloaterView : public LLFloaterView +{ +public: + struct Params + : public LLInitParam::Block + { + }; + +protected: + LLSimpleOutfitSnapshotFloaterView(const Params& p); + friend class LLUICtrlFactory; + +public: + virtual ~LLSimpleOutfitSnapshotFloaterView(); +}; + +extern LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView; + +#endif // LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 83212230e5..6b9d4580dc 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -176,16 +176,20 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate LLUICtrl* thumbnail_placeholder = floaterp->getChild("thumbnail_placeholder"); thumbnail_placeholder->setVisible(mAdvanced); - thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight()); + floaterp->getChild("image_res_text")->setVisible(mAdvanced); floaterp->getChild("file_size_label")->setVisible(mAdvanced); if (floaterp->hasChild("360_label", TRUE)) { floaterp->getChild("360_label")->setVisible(mAdvanced); } - if(!floaterp->isMinimized()) + if (!mSkipReshaping) { - floaterp->reshape(floater_width, floaterp->getRect().getHeight()); + thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight()); + if (!floaterp->isMinimized()) + { + floaterp->reshape(floater_width, floaterp->getRect().getHeight()); + } } bool use_freeze_frame = floaterp->getChild("freeze_frame_check")->getValue().asBoolean(); @@ -1193,7 +1197,7 @@ S32 LLFloaterSnapshotBase::notify(const LLSD& info) // The refresh button is initially hidden. We show it after the first update, // i.e. when preview appears. - if (!mRefreshBtn->getVisible()) + if (mRefreshBtn && !mRefreshBtn->getVisible()) { mRefreshBtn->setVisible(true); } diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index 7ec133ff45..7fc62a2746 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -59,9 +59,9 @@ public: const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } - void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); } - void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); } - void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); } + void setRefreshLabelVisible(bool value) { if (mRefreshLabel) mRefreshLabel->setVisible(value); } + void setSuccessLabelPanelVisible(bool value) { if (mSucceessLblPanel) mSucceessLblPanel->setVisible(value); } + void setFailureLabelPanelVisible(bool value) { if (mFailureLblPanel) mFailureLblPanel->setVisible(value); } void inventorySaveFailed(); class ImplBase; @@ -88,6 +88,7 @@ public: mLastToolset(NULL), mAspectRatioCheckOff(false), mNeedRefresh(false), + mSkipReshaping(false), mStatus(STATUS_READY), mFloater(floater) {} @@ -120,6 +121,7 @@ public: static BOOL updatePreviewList(bool initialized); void setAdvanced(bool advanced) { mAdvanced = advanced; } + void setSkipReshaping(bool skip) { mSkipReshaping = skip; } virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0; virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); @@ -135,6 +137,7 @@ public: bool mAspectRatioCheckOff; bool mNeedRefresh; bool mAdvanced; + bool mSkipReshaping; EStatus mStatus; }; diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index 4febb72c6c..87a0423483 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -41,7 +41,7 @@ #include "llfilepicker.h" #include "llfloaterperms.h" #include "llfloaterreg.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llimagedimensionsinfo.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" @@ -1385,8 +1385,8 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id) void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id) { - LLFloaterReg::toggleInstanceOrBringToFront("outfit_snapshot"); - LLFloaterOutfitSnapshot* snapshot_floater = LLFloaterOutfitSnapshot::getInstance(); + LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot"); + LLFloaterSimpleOutfitSnapshot* snapshot_floater = LLFloaterSimpleOutfitSnapshot::getInstance(); if (snapshot_floater) { snapshot_floater->setOutfitID(selected_outfit_id); diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 8134187c21..ed7e18fadc 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -233,7 +233,7 @@ bool LLSnapshotLivePreview::setSnapshotQuality(S32 quality, bool set_by_user) return false; } -void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) +void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color) { F32 line_width ; glGetFloatv(GL_LINE_WIDTH, &line_width) ; @@ -246,7 +246,6 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) //draw four alpha rectangles to cover areas outside of the snapshot image if(!mKeepAspectRatio) { - LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ; S32 dwl = 0, dwr = 0 ; if(mThumbnailWidth > mPreviewRect.getWidth()) { diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index 683cd016d8..1f81307976 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -112,7 +112,7 @@ public: BOOL setThumbnailImageSize() ; void generateThumbnailImage(BOOL force_update = FALSE) ; void resetThumbnailImage() { mThumbnailImage = NULL ; } - void drawPreviewRect(S32 offset_x, S32 offset_y) ; + void drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color = LLColor4(0.5f, 0.5f, 0.5f, 0.8f)); void prepareFreezeFrame(); LLViewerTexture* getBigThumbnailImage(); diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 3f7e8531fb..fc83b109ba 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -811,11 +811,6 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti { floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory"))); } - LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot"); - if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown()) - { - floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory"))); - } } //========================================================================= @@ -893,11 +888,5 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory"))); } } - - LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot"); - if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown()) - { - floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory"))); - } } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index dd03d6cfdd..30f8dbae7c 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -101,7 +101,7 @@ #include "llfloaterobjectweights.h" #include "llfloateropenobject.h" #include "llfloateroutfitphotopreview.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llfloaterpathfindingcharacters.h" #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindinglinksets.h" @@ -365,7 +365,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); - LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("simple_outfit_snapshot", "floater_simple_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index f1e2c06e0c..fdf1d04c09 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -38,7 +38,7 @@ #include "llfloatermap.h" #include "llfloatermodelpreview.h" #include "llfloatersnapshot.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llimage.h" #include "llimagebmp.h" #include "llimagepng.h" @@ -664,7 +664,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t bool handleEvent(const LLSD& userdata) { LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); - LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance(); + LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance(); bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain()) || (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain()); bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened; @@ -681,7 +681,7 @@ class LLFileCloseAllWindows : public view_listener_t LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); if (floater_snapshot) floater_snapshot->closeFloater(app_quitting); - LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance(); + LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance(); if (floater_outfit_snapshot) floater_outfit_snapshot->closeFloater(app_quitting); if (gMenuHolder) gMenuHolder->hideMenus(); diff --git a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml deleted file mode 100644 index 15c480f144..0000000000 --- a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml +++ /dev/null @@ -1,351 +0,0 @@ - - - - unknown - - - Saving to Inventory - - - Saved to Inventory! - - - Failed to save to inventory. - - -- cgit v1.2.3 From 9664eb86339f1cffac51cd0a5339535a040cada5 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 27 Jul 2022 21:17:56 +0300 Subject: SL-17831 Cut spammy log message --- indra/newview/llvoicevivox.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 54f79a3a2e..5f1624d4fd 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1625,7 +1625,14 @@ bool LLVivoxVoiceClient::requestParcelVoiceInfo() } else { - LL_WARNS("Voice") << "No voice credentials" << LL_ENDL; + if (LLViewerParcelMgr::getInstance()->allowAgentVoice()) + { + LL_WARNS("Voice") << "No voice credentials" << LL_ENDL; + } + else + { + LL_DEBUGS("Voice") << "No voice credentials" << LL_ENDL; + } } // set the spatial channel. If no voice credentials or uri are -- cgit v1.2.3 From 59becbde7577d035f2e9a2a54b94ff2d554e7e73 Mon Sep 17 00:00:00 2001 From: ZiRee Date: Thu, 28 Jul 2022 16:12:17 +0000 Subject: GCC11.1 warning: moving a local object in a return statement prevents copy elision [-Werror=pessimizing-move] --- indra/llcommon/threadsafeschedule.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h index 3e0da94c02..0c3a541196 100644 --- a/indra/llcommon/threadsafeschedule.h +++ b/indra/llcommon/threadsafeschedule.h @@ -248,7 +248,7 @@ namespace LL TimePoint until = TimePoint::clock::now() + std::chrono::hours(24); pop_result popped = tryPopUntil_(lock, until, tt); if (popped == POPPED) - return std::move(tt); + return tt; // DONE: throw, just as super::pop() does if (popped == DONE) -- cgit v1.2.3 From 97b0b87f7a908750763a4a357be15dc42f8f8cd3 Mon Sep 17 00:00:00 2001 From: ZiRee Date: Thu, 28 Jul 2022 16:15:35 +0000 Subject: Creating an LLVector4 from LLColor3 causes an array out of bounds read on reading .mV[3]. Doing a detour via LLVector3 fixes this but maybe there is a less roundabout way. --- indra/newview/llsettingsvo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 7c762170a7..707b602fc6 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -694,8 +694,8 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLVector4 sunDiffuse = LLVector4(psky->getSunlightColor().mV); - LLVector4 moonDiffuse = LLVector4(psky->getMoonlightColor().mV); + LLVector4 sunDiffuse = LLVector4(LLVector3(psky->getSunlightColor().mV)); + LLVector4 moonDiffuse = LLVector4(LLVector3(psky->getMoonlightColor().mV)); shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse); shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse); -- cgit v1.2.3 From 94cb1ba16c5b301779e437f73af9e06558f15760 Mon Sep 17 00:00:00 2001 From: ZiRee Date: Thu, 28 Jul 2022 16:18:30 +0000 Subject: GCC11.1 does not like these being floats, so cast them to U32 before using them as array size: error: expression in new-declarator must have integral or enumeration type --- indra/newview/llvosky.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 1aa00bc894..909588367b 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -100,8 +100,8 @@ LLSkyTex::LLSkyTex() : void LLSkyTex::init(bool isShiny) { mIsShiny = isShiny; - mSkyData = new LLColor4[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION]; - mSkyDirs = new LLVector3[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION]; + mSkyData = new LLColor4[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; + mSkyDirs = new LLVector3[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; for (S32 i = 0; i < 2; ++i) { -- cgit v1.2.3 From ebf7033f07d8a73559d8f3638643a9b27a1112c0 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 29 Jul 2022 22:55:44 +0300 Subject: SL-17858 Sit on ground was enabled but not working if already sitting --- indra/newview/llviewermenu.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8522c2ed55..060c1611c1 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4253,6 +4253,10 @@ class LLLandSit : public view_listener_t { bool handleEvent(const LLSD& userdata) { + if (gAgent.isSitting()) + { + gAgent.standUp(); + } LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal; LLQuaternion target_rot; -- cgit v1.2.3 From fe26a9d32c422fa26cfd82e92f93ad33654c2c51 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 30 Jul 2022 01:36:56 +0300 Subject: SL-17868 Crash at ThreadRecorder::bringUpToDate According to bugsplat get_thread_recorder was null Replaced apr based LLThreadLocalPointer with thread_local --- indra/llcommon/CMakeLists.txt | 1 - indra/llcommon/llapr.cpp | 4 -- indra/llcommon/llapr.h | 2 - indra/llcommon/llthreadlocalstorage.cpp | 115 ------------------------------- indra/llcommon/llthreadlocalstorage.h | 98 +------------------------- indra/llcommon/lltrace.cpp | 2 +- indra/llcommon/lltraceaccumulators.cpp | 2 +- indra/llcommon/lltracerecording.cpp | 14 ++-- indra/llcommon/lltracethreadrecorder.cpp | 6 +- indra/llcommon/lltracethreadrecorder.h | 3 +- 10 files changed, 15 insertions(+), 232 deletions(-) delete mode 100644 indra/llcommon/llthreadlocalstorage.cpp diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 59aa731af2..dcef3ec59f 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -108,7 +108,6 @@ set(llcommon_SOURCE_FILES llsys.cpp lltempredirect.cpp llthread.cpp - llthreadlocalstorage.cpp llthreadsafequeue.cpp lltimer.cpp lltrace.cpp diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index db94765871..435531f86f 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -30,7 +30,6 @@ #include "llapr.h" #include "llmutex.h" #include "apr_dso.h" -#include "llthreadlocalstorage.h" apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool. @@ -54,7 +53,6 @@ void ll_init_apr() LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; } - LLThreadLocalPointerBase::initAllThreadLocalStorage(); gAPRInitialized = true; } @@ -70,8 +68,6 @@ void ll_cleanup_apr() LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL; - LLThreadLocalPointerBase::destroyAllThreadLocalStorage(); - if (gAPRPoolp) { apr_pool_destroy(gAPRPoolp); diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index 565d7cfb63..cbac3002d0 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -36,8 +36,6 @@ #include #include "llwin32headerslean.h" #include "apr_thread_proc.h" -#include "apr_getopt.h" -#include "apr_signal.h" #include "llstring.h" diff --git a/indra/llcommon/llthreadlocalstorage.cpp b/indra/llcommon/llthreadlocalstorage.cpp deleted file mode 100644 index d8a063e8d5..0000000000 --- a/indra/llcommon/llthreadlocalstorage.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file llthreadlocalstorage.cpp - * @author Richard - * @date 2013-1-11 - * @brief implementation of thread local storage utility classes - * - * $LicenseInfo:firstyear=2013&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, 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 "linden_common.h" -#include "llthreadlocalstorage.h" -#include "llapr.h" - -// -//LLThreadLocalPointerBase -// -bool LLThreadLocalPointerBase::sInitialized = false; - -void LLThreadLocalPointerBase::set( void* value ) -{ - llassert(sInitialized && mThreadKey); - - apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to set thread local data" << LL_ENDL; - } -} - -void* LLThreadLocalPointerBase::get() const -{ - // llassert(sInitialized); - void* ptr; - apr_status_t result = - apr_threadkey_private_get(&ptr, mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to get thread local data" << LL_ENDL; - } - return ptr; -} - - -void LLThreadLocalPointerBase::initStorage( ) -{ - apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL; - } -} - -void LLThreadLocalPointerBase::destroyStorage() -{ - if (sInitialized) - { - if (mThreadKey) - { - apr_status_t result = apr_threadkey_private_delete(mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to delete thread local data" << LL_ENDL; - } - } - } -} - -//static -void LLThreadLocalPointerBase::initAllThreadLocalStorage() -{ - if (!sInitialized) - { - for (auto& base : instance_snapshot()) - { - base.initStorage(); - } - sInitialized = true; - } -} - -//static -void LLThreadLocalPointerBase::destroyAllThreadLocalStorage() -{ - if (sInitialized) - { - //for (auto& base : instance_snapshot()) - //{ - // base.destroyStorage(); - //} - sInitialized = false; - } -} diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h index 3b5786023f..bdd28ec865 100644 --- a/indra/llcommon/llthreadlocalstorage.h +++ b/indra/llcommon/llthreadlocalstorage.h @@ -30,100 +30,6 @@ #include "llinstancetracker.h" -class LLThreadLocalPointerBase : public LLInstanceTracker -{ -public: - LLThreadLocalPointerBase() - : mThreadKey(NULL) - { - if (sInitialized) - { - initStorage(); - } - } - - LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other) - : mThreadKey(NULL) - { - if (sInitialized) - { - initStorage(); - } - } - - ~LLThreadLocalPointerBase() - { - destroyStorage(); - } - - static void initAllThreadLocalStorage(); - static void destroyAllThreadLocalStorage(); - -protected: - void set(void* value); - - void* get() const; - - void initStorage(); - void destroyStorage(); - -protected: - struct apr_threadkey_t* mThreadKey; - static bool sInitialized; -}; - -template -class LLThreadLocalPointer : public LLThreadLocalPointerBase -{ -public: - - LLThreadLocalPointer() - {} - - explicit LLThreadLocalPointer(T* value) - { - set(value); - } - - - LLThreadLocalPointer(const LLThreadLocalPointer& other) - : LLThreadLocalPointerBase(other) - { - set(other.get()); - } - - LL_FORCE_INLINE T* get() const - { - return (T*)LLThreadLocalPointerBase::get(); - } - - T* operator -> () const - { - return (T*)get(); - } - - T& operator*() const - { - return *(T*)get(); - } - - LLThreadLocalPointer& operator = (T* value) - { - set((void*)value); - return *this; - } - - bool operator ==(const T* other) const - { - if (!sInitialized) return false; - return get() == other; - } - - bool isNull() const { return !sInitialized || get() == NULL; } - - bool notNull() const { return sInitialized && get() != NULL; } -}; - template class LLThreadLocalSingletonPointer { @@ -139,10 +45,10 @@ public: } private: - static LL_THREAD_LOCAL DERIVED_TYPE* sInstance; + static thread_local DERIVED_TYPE* sInstance; }; template -LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer::sInstance = NULL; +thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer::sInstance = NULL; #endif // LL_LLTHREADLOCALSTORAGE_H diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index f59b207ded..acdda5fe1e 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -40,7 +40,7 @@ StatBase::StatBase( const char* name, const char* description ) mDescription(description ? description : "") { #ifndef LL_RELEASE_FOR_DOWNLOAD - if (LLTrace::get_thread_recorder().notNull()) + if (LLTrace::get_thread_recorder() != NULL) { LL_ERRS() << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << LL_ENDL; } diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp index 34299f5a29..fe447d5319 100644 --- a/indra/llcommon/lltraceaccumulators.cpp +++ b/indra/llcommon/lltraceaccumulators.cpp @@ -93,7 +93,7 @@ void AccumulatorBufferGroup::makeCurrent() mStackTimers.makeCurrent(); mMemStats.makeCurrent(); - ThreadRecorder* thread_recorder = get_thread_recorder().get(); + ThreadRecorder* thread_recorder = get_thread_recorder(); AccumulatorBuffer& timer_accumulator_buffer = mStackTimers; // update stacktimer parent pointers for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++) diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 1613af1dcf..8cbb0db135 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -95,7 +95,7 @@ Recording::~Recording() // allow recording destruction without thread recorder running, // otherwise thread shutdown could crash if a recording outlives the thread recorder // besides, recording construction and destruction is fine without a recorder...just don't attempt to start one - if (isStarted() && LLTrace::get_thread_recorder().notNull()) + if (isStarted() && LLTrace::get_thread_recorder() != NULL) { LLTrace::get_thread_recorder()->deactivate(mBuffers.write()); } @@ -112,9 +112,9 @@ void Recording::update() // must have llassert(mActiveBuffers != NULL - && LLTrace::get_thread_recorder().notNull()); + && LLTrace::get_thread_recorder() != NULL); - if(!mActiveBuffers->isCurrent()) + if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL) { AccumulatorBufferGroup* buffers = mBuffers.write(); LLTrace::get_thread_recorder()->deactivate(buffers); @@ -144,7 +144,7 @@ void Recording::handleStart() mSamplingTimer.reset(); mBuffers.setStayUnique(true); // must have thread recorder running on this thread - llassert(LLTrace::get_thread_recorder().notNull()); + llassert(LLTrace::get_thread_recorder() != NULL); mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write()); #endif } @@ -155,7 +155,7 @@ void Recording::handleStop() #if LL_TRACE_ENABLED mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); // must have thread recorder running on this thread - llassert(LLTrace::get_thread_recorder().notNull()); + llassert(LLTrace::get_thread_recorder() != NULL); LLTrace::get_thread_recorder()->deactivate(mBuffers.write()); mActiveBuffers = NULL; mBuffers.setStayUnique(false); @@ -1181,8 +1181,8 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth PeriodicRecording& get_frame_recording() { - static LLThreadLocalPointer sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED)); - return *sRecording; + static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED); + return sRecording; } } diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 090d3297a0..26db15eaa0 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder() return sMasterThreadRecorder; } -LLThreadLocalPointer& get_thread_recorder_ptr() +ThreadRecorder*& get_thread_recorder_ptr() { - static LLThreadLocalPointer s_thread_recorder; + static thread_local ThreadRecorder* s_thread_recorder; return s_thread_recorder; } -const LLThreadLocalPointer& get_thread_recorder() +ThreadRecorder* get_thread_recorder() { return get_thread_recorder_ptr(); } diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h index a797c6687e..8fd1e5ef58 100644 --- a/indra/llcommon/lltracethreadrecorder.h +++ b/indra/llcommon/lltracethreadrecorder.h @@ -32,7 +32,6 @@ #include "llmutex.h" #include "lltraceaccumulators.h" -#include "llthreadlocalstorage.h" namespace LLTrace { @@ -92,7 +91,7 @@ namespace LLTrace }; - const LLThreadLocalPointer& get_thread_recorder(); + ThreadRecorder* get_thread_recorder(); void set_thread_recorder(ThreadRecorder*); void set_master_thread_recorder(ThreadRecorder*); -- cgit v1.2.3 From 302bab87e64704b075fdbdce4b3844a7b8338c49 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 1 Aug 2022 18:27:13 +0300 Subject: SL-17868 Fixed macos build issue --- indra/llcommon/llapr.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index cbac3002d0..565d7cfb63 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -36,6 +36,8 @@ #include #include "llwin32headerslean.h" #include "apr_thread_proc.h" +#include "apr_getopt.h" +#include "apr_signal.h" #include "llstring.h" -- cgit v1.2.3 From 3f3735c1f810f6a6c5635a5895689f5a366571de Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 2 Aug 2022 14:59:04 +0300 Subject: SL-17851 Highlight matching notifications when using Search Box in Preference --- indra/llui/llscrolllistctrl.cpp | 39 ++++++++++++++++++++++ indra/llui/llscrolllistctrl.h | 2 ++ indra/newview/llfloaterpreference.cpp | 21 ++++++++++++ indra/newview/llfloaterpreference.h | 1 + .../newview/skins/default/xui/en/notifications.xml | 2 +- 5 files changed, 64 insertions(+), 1 deletion(-) diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 11b0eb9f80..f3211b23c9 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -3307,3 +3307,42 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien } return mIsFriendSignal->connect(cb); } + +bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str) +{ + if (filter_str == "" || filter_str == " ") + { + clearHighlightedItems(); + return false; + } + + bool res = false; + + setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red)); + + std::string filter_str_lc(filter_str); + LLStringUtil::toLower(filter_str_lc); + + std::vector data = getAllData(); + std::vector::iterator iter = data.begin(); + while (iter != data.end()) + { + LLScrollListCell* cell = (*iter)->getColumn(0); + if (cell) + { + std::string value = cell->getValue().asString(); + LLStringUtil::toLower(value); + if (value.find(filter_str_lc) == std::string::npos) + { + (*iter)->setHighlighted(false); + } + else + { + (*iter)->setHighlighted(true); + res = true; + } + } + iter++; + } + return res; +} diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 08134bbfc8..af553843bd 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -410,6 +410,8 @@ public: void setNeedsSort(bool val = true) { mSorted = !val; } void dirtyColumns(); // some operation has potentially affected column layout or ordering + bool highlightMatchingItems(const std::string& filter_str); + boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) { if (!mSortCallback) mSortCallback = new sort_signal_t(); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 2bbf3b751f..98ac79dd96 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1512,6 +1512,10 @@ void LLFloaterPreference::onClickEnablePopup() } buildPopupLists(); + if (!mFilterEdit->getText().empty()) + { + filterIgnorableNotifications(); + } } void LLFloaterPreference::onClickDisablePopup() @@ -1527,6 +1531,10 @@ void LLFloaterPreference::onClickDisablePopup() } buildPopupLists(); + if (!mFilterEdit->getText().empty()) + { + filterIgnorableNotifications(); + } } void LLFloaterPreference::resetAllIgnored() @@ -3547,11 +3555,24 @@ void LLFloaterPreference::onUpdateFilterTerm(bool force) return; mSearchData->mRootTab->hightlightAndHide( seachValue ); + filterIgnorableNotifications(); + LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" ); if( pRoot ) pRoot->selectFirstTab(); } +void LLFloaterPreference::filterIgnorableNotifications() +{ + bool visible = getChildRef("enabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + visible |= getChildRef("disabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + + if (visible) + { + getChildRef("pref core").setTabVisibility( getChild("msgs"), true ); + } +} + void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer ) { if( !aView ) diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 5797f7be8d..484f82aa7f 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -227,6 +227,7 @@ private: void onUpdateFilterTerm( bool force = false ); void collectSearchableItems(); + void filterIgnorableNotifications(); std::map mIgnorableNotifs; }; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index aa93601669..b8ccc8c3e0 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -9628,7 +9628,7 @@ Do you wish to continue? The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh. confirm -- cgit v1.2.3 From fad6c45d2042e536b2602bf285b8ec0426dc2efe Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 2 Aug 2022 22:48:36 +0300 Subject: SL-17862 Fixed typo in rigged mesh rendering --- indra/newview/pipeline.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 62d3ae7a39..0830d4a2ea 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -465,7 +465,7 @@ public: RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED, RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS, RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT, - RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT, + RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT_RIGGED, RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE, RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED, RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY, -- cgit v1.2.3 From 68d78dd183ec639703f4033ef9047e1988c3ef0e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 2 Aug 2022 23:19:15 +0300 Subject: SL-17048 Fixed not cleaning session --- indra/newview/llvoicevivox.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index 19036a3f77..cfe927ecc0 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -6188,7 +6188,7 @@ void LLVivoxVoiceClient::clearSessionHandle(const sessionStatePtr_t &session) { if (session) { - if (session->mHandle.empty()) + if (!session->mHandle.empty()) { sessionMap::iterator iter = mSessionsByHandle.find(session->mHandle); if (iter != mSessionsByHandle.end()) -- cgit v1.2.3 From 70009d21b2dd51c2c3cc6d9195e048051ca00699 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 3 Aug 2022 01:46:01 +0300 Subject: SL-17890 Face creation does not clean used arrays --- indra/llprimitive/lldaeloader.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index e89690438e..7a138578a5 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -330,7 +330,10 @@ LLModel::EModelStatus load_face_from_dom_triangles( // VFExtents change face.mExtents[0].set(v[0], v[1], v[2]); face.mExtents[1].set(v[0], v[1], v[2]); - point_map.clear(); + + verts.clear(); + indices.clear(); + point_map.clear(); } } -- cgit v1.2.3 From 062f19027ec724f1a98380a58c688aa15e7f2b11 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 3 Aug 2022 22:03:57 +0300 Subject: SL-17890 readable warning for MAV_BLOCK_MISSING --- indra/newview/skins/default/xui/en/strings.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 8382e3970c..44513404e7 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -4290,6 +4290,10 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image The physics shape contains bad confirmation data. Try to correct the physics model. + + + Missing data. Make sure high lod is present and valid. Set the physics model if not set. + The physics shape does not have correct version. Set the correct version for the physics model. -- cgit v1.2.3 From 1f53d3abbf612531dd10672127552e189255da01 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 14 Jul 2022 22:39:23 +0300 Subject: SL-17628 Added attachments can be moved past limit #2 --- indra/llui/llspinctrl.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index ef7c8ec012..c411aafb1a 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -101,7 +101,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) // Spin buttons LLButton::Params up_button_params(p.up_button); up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height); - up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); + // Click callback starts within the button and ends within the button, + // but LLSpinCtrl handles the action continuosly so subsribers needs to + // be informed about click ending even if outside view, use 'up' instead + up_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.commit_on_capture_lost = true; @@ -110,7 +113,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) LLButton::Params down_button_params(p.down_button); down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height); - down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); + down_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.commit_on_capture_lost = true; mDownBtn = LLUICtrlFactory::create(down_button_params); -- cgit v1.2.3 From e3ef38876b9951af3ea8052fb02db46212c76965 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 4 Aug 2022 17:45:06 +0300 Subject: SL-17785 FIXED World Map scrolls too slowly after pressing "Me" button --- indra/newview/llfloaterworldmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp index f363733261..16b8c7a4bc 100755 --- a/indra/newview/llfloaterworldmap.cpp +++ b/indra/newview/llfloaterworldmap.cpp @@ -1281,7 +1281,7 @@ void LLFloaterWorldMap::onShowTargetBtn() void LLFloaterWorldMap::onShowAgentBtn() { - mMapView->setPan(0, 0, false); // false == animate + mMapView->setPanWithInterpTime(0, 0, false, 0.1f); // false == animate // Set flag so user's location will be displayed if not tracking anything else mSetToUserPosition = true; } -- cgit v1.2.3 From 64fefa9880a85d333ef4a4479bcb3468cef12f65 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Thu, 11 Aug 2022 15:58:53 +0300 Subject: SL-17670 tweaking simplified outfit snapshot floater --- indra/newview/llfloatersimpleoutfitsnapshot.cpp | 9 +++++++-- indra/newview/skins/default/colors.xml | 6 ++++++ .../default/xui/en/floater_simple_outfit_snapshot.xml | 18 +++++++++--------- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.cpp b/indra/newview/llfloatersimpleoutfitsnapshot.cpp index 181e2ba10e..bab2efbbd5 100644 --- a/indra/newview/llfloatersimpleoutfitsnapshot.cpp +++ b/indra/newview/llfloatersimpleoutfitsnapshot.cpp @@ -182,8 +182,8 @@ BOOL LLFloaterSimpleOutfitSnapshot::postBuild() return TRUE; } -const S32 PREVIEW_OFFSET_X = 2; -const S32 PREVIEW_OFFSET_Y = 63; +const S32 PREVIEW_OFFSET_X = 12; +const S32 PREVIEW_OFFSET_Y = 70; void LLFloaterSimpleOutfitSnapshot::draw() { @@ -216,7 +216,12 @@ void LLFloaterSimpleOutfitSnapshot::draw() gl_draw_scaled_image(offset_x, offset_y, thumbnail_w, thumbnail_h, previewp->getThumbnailImage(), color % alpha); +#if LL_DARWIN + std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "OutfitSnapshotMacMask" : "OutfitSnapshotMacMask2"; +#else std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "FloaterFocusBackgroundColor" : "DkGray"; +#endif + previewp->drawPreviewRect(offset_x, offset_y, LLUIColorTable::instance().getColor(alpha_color)); gGL.pushUIMatrix(); diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index 7beb013fba..3dd772ca93 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -969,4 +969,10 @@ + + diff --git a/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml index 765bc54e46..5ece7b85d5 100644 --- a/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml @@ -5,7 +5,7 @@ can_minimize="true" can_resize="false" can_close="true" - height="315" + height="305" layout="topleft" name="simple_outfit_snapshot" single_instance="true" @@ -13,24 +13,24 @@ save_rect="true" save_visibility="false" title="OUTFIT SNAPSHOT" - width="405"> + width="351"> + + Back + + + Preferred frame rate + + + + Desired frame rate + + + + + + + Settings affect + + + + + + + + Reducing detail shown on avatars that are far away will improve graphics speed. + + + + + + meters + + + + Choose the distance range that automatic settings will affect. + + + Minimum distance + + + + + Maximum distance + + + + -- cgit v1.2.3 From 664ce046eedc65963c1cbcbadfe72df8970ee2c6 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 21 Sep 2022 21:54:37 +0300 Subject: SL-17628 Add viewer sided max attachment distance to position fields --- indra/newview/llpanelobject.cpp | 16 ++++++++++++++++ indra/newview/llviewerjointattachment.cpp | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 0bfc1297d3..bc7933d84b 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -93,6 +93,8 @@ enum { MI_HOLE_COUNT }; +const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters + //static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright"); BOOL LLPanelObject::postBuild() @@ -1685,6 +1687,16 @@ void LLPanelObject::sendPosition(BOOL btn_down) mCtrlPosZ->set(LLWorld::getInstance()->resolveLandHeightAgent(newpos) + 1.f); } } + else + { + if (newpos.length() > MAX_ATTACHMENT_DIST) + { + newpos.clampLength(MAX_ATTACHMENT_DIST); + mCtrlPosX->set(newpos.mV[VX]); + mCtrlPosY->set(newpos.mV[VY]); + mCtrlPosZ->set(newpos.mV[VZ]); + } + } // Make sure new position is in a valid region, so the object // won't get dumped by the simulator. @@ -2191,6 +2203,10 @@ void LLPanelObject::onPastePos() mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width); //height will get properly clamped by sendPosition } + else + { + mClipboardPos.clampLength(MAX_ATTACHMENT_DIST); + } mCtrlPosX->set( mClipboardPos.mV[VX] ); mCtrlPosY->set( mClipboardPos.mV[VY] ); diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index fd314ed3dc..b3bfb86b99 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -45,7 +45,7 @@ #include "llglheaders.h" extern LLPipeline gPipeline; -const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters? +const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters //----------------------------------------------------------------------------- // LLViewerJointAttachment() -- cgit v1.2.3 From 3994101549eddf84d6c73982109f68d016a819ba Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 21 Sep 2022 20:52:27 +0100 Subject: SL-18119 - more ViewerStats logs for NUX --- indra/newview/llagent.cpp | 4 ++++ indra/newview/llappearancemgr.cpp | 4 ++++ indra/newview/llavataractions.cpp | 2 +- indra/newview/llcallingcard.cpp | 2 +- indra/newview/lltoolpie.cpp | 3 +++ indra/newview/llviewermessage.cpp | 4 ++-- indra/newview/llvoiceclient.cpp | 4 ++++ 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 7f6f6e5997..3b3eadada7 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -96,6 +96,7 @@ #include "stringize.h" #include "boost/foreach.hpp" #include "llcorehttputil.h" +#include "lluiusage.h" using namespace LLAvatarAppearanceDefines; @@ -574,6 +575,8 @@ void LLAgent::ageChat() //----------------------------------------------------------------------------- void LLAgent::moveAt(S32 direction, bool reset) { + LLUIUsage::instance().logCommand("Agent.MoveAt"); + mMoveTimer.reset(); LLFirstUse::notMoving(false); @@ -4023,6 +4026,7 @@ void LLAgent::startTeleportRequest() } if (hasPendingTeleportRequest()) { + LLUIUsage::instance().logCommand("Agent.StartTeleportRequest"); mTeleportCanceled.reset(); if (!isMaturityPreferenceSyncedWithServer()) { diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 39348412e5..909f32cd21 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3973,6 +3973,8 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo { if (!isAgentAvatarValid()) return; + LLUIUsage::instance().logCommand("Avatar.CreateNewOutfit"); + LL_DEBUGS("Avatar") << "creating new outfit" << LL_ENDL; gAgentWearables.notifyLoadingStarted(); @@ -4493,6 +4495,8 @@ public: "Quick Appearance"); if ( gInventory.getCategory( folder_uuid ) != NULL ) { + // Assume this is coming from the predefined avatars web floater + LLUIUsage::instance().logCommand("Avatar.WearPredefinedAppearance"); LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false); // *TODOw: This may not be necessary if initial outfit is chosen already -- josh diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp index 93370ba9c3..3e450e6dec 100644 --- a/indra/newview/llavataractions.cpp +++ b/indra/newview/llavataractions.cpp @@ -1419,7 +1419,7 @@ bool LLAvatarActions::handleUnfreeze(const LLSD& notification, const LLSD& respo void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message) { const LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD); - LLUIUsage::instance().logCommand("Avatar.SendFriendRequest"); + LLUIUsage::instance().logCommand("Agent.SendFriendRequest"); send_improved_im(target_id, target_name, diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 7d7c8ba0cd..1ad2157df0 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -295,7 +295,7 @@ void LLAvatarTracker::copyBuddyList(buddy_map_t& buddies) const void LLAvatarTracker::terminateBuddy(const LLUUID& id) { LL_DEBUGS() << "LLAvatarTracker::terminateBuddy()" << LL_ENDL; - LLUIUsage::instance().logCommand("Avatar.TerminateFriendship"); + LLUIUsage::instance().logCommand("Agent.TerminateFriendship"); LLRelationship* buddy = get_ptr_in_map(mBuddyInfo, id); if(!buddy) return; diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 43deac60d9..5fb83bf08e 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -71,6 +71,7 @@ #include "llui.h" #include "llweb.h" #include "pipeline.h" // setHighlightObject +#include "lluiusage.h" extern BOOL gDebugClicks; @@ -568,6 +569,8 @@ bool LLToolPie::walkToClickedLocation() return false; } + LLUIUsage::instance().logCommand("Agent.WalkToClickedLocation"); + LLPickInfo saved_pick = mPick; if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) { diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 10710ae5f3..c8b517b4c1 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -262,7 +262,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) { case 0: { - LLUIUsage::instance().logCommand("Avatar.AcceptFriendship"); + LLUIUsage::instance().logCommand("Agent.AcceptFriendship"); // accept LLAvatarTracker::formFriendship(payload["from_id"]); @@ -305,7 +305,7 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response) // fall-through case 2: // Send IM - decline and start IM session { - LLUIUsage::instance().logCommand("Avatar.DeclineFriendship"); + LLUIUsage::instance().logCommand("Agent.DeclineFriendship"); // decline // We no longer notify other viewers, but we DO still send // the rejection to the simulator to delete the pending userop. diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index e2bd1a39c7..8261fc7fb4 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -602,6 +602,10 @@ void LLVoiceClient::setMuteMic(bool muted) void LLVoiceClient::setUserPTTState(bool ptt) { + if (ptt) + { + LLUIUsage::instance().logCommand("Agent.EnableMicrophone"); + } mUserPTTState = ptt; updateMicMuteLogic(); mMicroChangedSignal(); -- cgit v1.2.3 From 827420e2fe1322023ab016d067211689bbcfbd93 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 21 Sep 2022 20:58:34 +0100 Subject: SL-18119 - bug fix --- indra/newview/llvoiceclient.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 8261fc7fb4..d399d724f3 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -37,6 +37,7 @@ #include "llui.h" #include "llkeyboard.h" #include "llagent.h" +#include "lluiusage.h" const F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f; -- cgit v1.2.3 From ef311198f97ca363ceb26b10c7100832274135f7 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 22 Sep 2022 15:48:28 +0100 Subject: SL-18119 - log group join, object add or rez --- indra/newview/lltooldraganddrop.cpp | 3 +++ indra/newview/lltoolplacer.cpp | 2 ++ indra/newview/llviewermessage.cpp | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index f76a2f7f90..b16b26b96e 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -60,6 +60,7 @@ #include "llvoavatarself.h" #include "llworld.h" #include "llpanelface.h" +#include "lluiusage.h" // syntactic sugar #define callMemberFunction(object,ptrToMember) ((object).*(ptrToMember)) @@ -1305,10 +1306,12 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target, LLMessageSystem* msg = gMessageSystem; if (mSource == SOURCE_NOTECARD) { + LLUIUsage::instance().logCommand("Object.RezObjectFromNotecard"); msg->newMessageFast(_PREHASH_RezObjectFromNotecard); } else { + LLUIUsage::instance().logCommand("Object.RezObject"); msg->newMessageFast(_PREHASH_RezObject); } msg->nextBlockFast(_PREHASH_AgentData); diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp index 814bade56a..7cdd7cc5c8 100644 --- a/indra/newview/lltoolplacer.cpp +++ b/indra/newview/lltoolplacer.cpp @@ -62,6 +62,7 @@ #include "llprimitive.h" #include "llwindow.h" // incBusyCount() #include "material_codes.h" +#include "lluiusage.h" const LLVector3 DEFAULT_OBJECT_SCALE(0.5f, 0.5f, 0.5f); @@ -227,6 +228,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics ) gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI); } + LLUIUsage::instance().logCommand("Build.ObjectAdd"); gMessageSystem->newMessageFast(_PREHASH_ObjectAdd); gMessageSystem->nextBlockFast(_PREHASH_AgentData); gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index c8b517b4c1..aa31aede7c 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -836,6 +836,11 @@ void send_join_group_response(LLUUID group_id, LLUUID transaction_id, bool accep EInstantMessage type = accept_invite ? IM_GROUP_INVITATION_ACCEPT : IM_GROUP_INVITATION_DECLINE; + if (accept_invite) + { + LLUIUsage::instance().logCommand("Group.Join"); + } + send_improved_im(group_id, std::string("name"), std::string("message"), -- cgit v1.2.3 From 81c287f877a48381bfa212ad00fe23aef260ef5f Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine 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(-) 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 @@ Value 0 + ShowTunedART + + Comment + Show the current render time not the pre-tuning render time in the avatar display. + Persist + 1 + Type + Boolean + Value + 1 + RenderAvatarMaxART Comment 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("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)); + mMaxARTChangedSignal = gSavedSettings.getControl("RenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this)); + mNearbyPanel->getChild("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 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(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(obj->getColumn(1)); + if (value_text) + { + value_text->setAlignment(LLFontGL::HCENTER); + } } } } @@ -332,6 +340,7 @@ void LLFloaterPerformance::populateObjectList() void LLFloaterPerformance::populateNearbyList() { + static LLCachedControl 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::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(*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(av_item->getColumn(0)); @@ -462,18 +489,11 @@ void LLFloaterPerformance::onClickExceptions() LLFloaterReg::showInstance("avatar_render_settings"); } -void LLFloaterPerformance::updateMaxComplexity() -{ - LLAvatarComplexityControls::updateMax( - mNearbyPanel->getChild("IndirectMaxComplexity"), - mNearbyPanel->getChild("IndirectMaxComplexityText"), - true); -} - -void LLFloaterPerformance::updateComplexityText() +void LLFloaterPerformance::updateMaxRenderTime() { - LLAvatarComplexityControls::setText(gSavedSettings.getU32("RenderAvatarMaxComplexity"), - mNearbyPanel->getChild("IndirectMaxComplexityText", true), + LLAvatarComplexityControls::updateMaxRenderTime( + mNearbyPanel->getChild("RenderAvatarMaxART"), + mNearbyPanel->getChild("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. + width="490"> - 0 + no limit Date: Thu, 22 Sep 2022 23:33:48 +0300 Subject: SL-18221 Water texture does not load after clearing cache Water texture should load only after having caps. Prefetch textures should load only after having caps. Prefetch list is now per grid --- indra/newview/llstartup.cpp | 9 ++++++--- indra/newview/lltexturefetch.cpp | 12 ++++++++---- indra/newview/llviewertexturelist.cpp | 27 ++++++++++++++++++++------- indra/newview/llviewertexturelist.h | 2 ++ 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 6aca701fe2..ce940e1d4e 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1285,9 +1285,6 @@ bool idle_startup() // Initialize classes w/graphics stuff. // LLViewerStatsRecorder::instance(); // Since textures work in threads - gTextureList.doPrefetchImages(); - display_startup(); - LLSurface::initClasses(); display_startup(); @@ -1432,6 +1429,12 @@ bool idle_startup() if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState()) { display_startup(); + + // These textures are not warrantied to be cached, so needs + // to hapen with caps granted + gTextureList.doPrefetchImages(); + + display_startup(); update_texture_fetch(); display_startup(); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 3099092abb..a7dcb1a9bb 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -1342,10 +1342,14 @@ bool LLTextureFetchWorker::doWork(S32 param) if ( use_http && mCanUseHTTP && mUrl.empty())//get http url. { LLViewerRegion* region = NULL; - if (mHost.isInvalid()) - region = gAgent.getRegion(); - else - region = LLWorld::getInstance()->getRegion(mHost); + if (mHost.isInvalid()) + { + region = gAgent.getRegion(); + } + else if (LLWorld::instanceExists()) + { + region = LLWorld::getInstance()->getRegion(mHost); + } if (region) { diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 546a03def2..fccf768f4d 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -50,6 +50,7 @@ #include "llviewercontrol.h" #include "llviewertexture.h" #include "llviewermedia.h" +#include "llviewernetwork.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "pipeline.h" @@ -160,12 +161,6 @@ void LLViewerTextureList::doPreloadImages() image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } - image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); - if (image) - { - image->setAddressMode(LLTexUnit::TAM_WRAP); - mImagePreloads.insert(image); - } image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, 0, 0, IMG_TRANSPARENT); if (image) @@ -198,7 +193,18 @@ void LLViewerTextureList::doPreloadImages() static std::string get_texture_list_name() { - return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml"); + if (LLGridManager::getInstance()->isInProductionGrid()) + { + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, + "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml"); + } + else + { + const std::string& grid_id_str = LLGridManager::getInstance()->getGridId(); + const std::string& grid_id_lower = utf8str_tolower(grid_id_str); + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, + "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + "." + grid_id_lower + ".xml"); + } } void LLViewerTextureList::doPrefetchImages() @@ -207,6 +213,13 @@ void LLViewerTextureList::doPrefetchImages() gTextureTimer.start(); gTextureTimer.pause(); + LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); + if (imagep) + { + imagep->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(imagep); + } + if (LLAppViewer::instance()->getPurgeCache()) { // cache was purged, no point diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 41b3568570..0018e78d45 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -131,7 +131,9 @@ public: void updateMaxResidentTexMem(S32Megabytes mem); + // Local UI images void doPreloadImages(); + // Network images. Needs caps and cache to work void doPrefetchImages(); void clearFetchingRequests(); -- cgit v1.2.3 From 3098d315a34f6d9e1bdf0f0de4e695a89626282f Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine 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(-) 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 @@ Value 0 - AutoFPS - - Comment - - Allow dynamic adjustment of graphics preferences - - Persist - 1 - Type - Boolean - Value - 0 - - AutoAdjustmentTimeout - - Comment - Time before next iteration of automatic adjustments - Persist - 1 - Type - F32 - Value - 5 - - InitialAdjustmentTimeout - - Comment - Time before first iteration of automatic adjustments after login to the world, teleporting, maximizing Viewer etc. - Persist - 1 - Type - F32 - Value - 10 - - AutoFPSLowerBoundary - - Comment - FPS lower boundary when automatic adjustments are occured to reduce graphics quality to increase FPS - Persist - 1 - Type - S32 - Value - 30 - - AutoFPSUpperBoundary - - Comment - FPS upper boundary when automatic adjustments are occured to increase graphics quality - Persist - 1 - Type - S32 - Value - 50 - TargetFPS Comment 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("graphics_quality")->setCommitCallback(boost::bind(&LLFloaterPerformance::onChangeQuality, this, _2)); mSettingsPanel->getChild("advanced_lighting_model")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickAdvancedLighting, this)); mSettingsPanel->getChild("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPerformance::onClickShadows, this)); - mSettingsPanel->getChild("Reflections")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning)); mNearbyPanel->getChild("exceptions_btn")->setCommitCallback(boost::bind(&LLFloaterPerformance::onClickExceptions, this)); mNearbyPanel->getChild("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 use_auto_adjust(gSavedSettings,"AutoFPS"); - if (use_auto_adjust) - { - LLNotificationsUtil::add("AutoFPSConfirmDisable", LLSD(), LLSD(), - [](const LLSD¬if, 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("ShadowDetail")->setMouseDownCallback(boost::bind(&LLFloaterPreference::showAutoAdjustWarning)); - getChild("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 use_auto_adjustment(gSavedSettings,"AutoFPS"); - if (!use_auto_adjustment) - { - return; - } - - if (LLStartUp::getStartupState() < STATE_STARTED || LLApp::isExiting()) - { - return; - } - - static LLCachedControl adjustment_timeout(gSavedSettings, "AutoAdjustmentTimeout"); - static LLCachedControl initial_adjustment_timeout(gSavedSettings, "InitialAdjustmentTimeout"); - - static LLCachedControl fps_lower_boundary(gSavedSettings, "AutoFPSLowerBoundary"); - static LLCachedControl 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 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 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& 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 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"> - - - - Automatic settings - - - - - 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) - - - + Quality & speed: @@ -238,10 +217,7 @@ max_val="512" name="DrawDistance" top_delta="40" - width="330"> - - + width="330" /> - + 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(-) 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("PrefSaveButton"); LLButton* delete_btn = findChild("PrefDeleteButton"); LLButton* exceptions_btn = findChild("RenderExceptionsButton"); + LLButton* auto_adjustments_btn = findChild("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("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 @@ + + Date: Tue, 27 Sep 2022 14:42:53 -0400 Subject: Introduce a U8* based interface to unzip_llsd and unpackVolumeFaces --- indra/llcommon/llsdserialize.cpp | 121 +++++++++++++++++++++------------------ indra/llcommon/llsdserialize.h | 6 ++ indra/llmath/llvolume.cpp | 20 ++++++- indra/llmath/llvolume.h | 6 +- 4 files changed, 96 insertions(+), 57 deletions(-) diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 8b4a0ee6d8..a510b73096 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -34,6 +34,9 @@ #include #include "apr_base64.h" +#include +#include + #ifdef LL_USESYSTEMLIBS # include #else @@ -2128,7 +2131,9 @@ std::string zip_llsd(LLSD& data) { //copy result into output if (strm.avail_out >= CHUNK) { - free(output); + deflateEnd(&strm); + if(output) + free(output); LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL; return std::string(); } @@ -2151,7 +2156,9 @@ std::string zip_llsd(LLSD& data) } else { - free(output); + deflateEnd(&strm); + if(output) + free(output); LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL; return std::string(); } @@ -2162,7 +2169,8 @@ std::string zip_llsd(LLSD& data) std::string result((char*) output, size); deflateEnd(&strm); - free(output); + if(output) + free(output); return result; } @@ -2171,54 +2179,67 @@ std::string zip_llsd(LLSD& data) // not very efficient -- creats a copy of decompressed LLSD block in memory // and deserializes from that copy using LLSDSerialize LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size) +{ + std::unique_ptr in = std::unique_ptr(new(std::nothrow) U8[size]); + if (!in) + { + return ZR_MEM_ERROR; + } + is.read((char*) in.get(), size); + + return unzip_llsd(data, in.get(), size); +} + +LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32 size) { U8* result = NULL; U32 cur_size = 0; z_stream strm; - const U32 CHUNK = 65536; + constexpr U32 CHUNK = 1024 * 512; - U8 *in = new(std::nothrow) U8[size]; - if (!in) + static thread_local std::unique_ptr out; + if (!out) { - return ZR_MEM_ERROR; + out = std::unique_ptr(new(std::nothrow) U8[CHUNK]); } - is.read((char*) in, size); - - U8 out[CHUNK]; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = size; - strm.next_in = in; + strm.next_in = const_cast(in); S32 ret = inflateInit(&strm); do { strm.avail_out = CHUNK; - strm.next_out = out; + strm.next_out = out.get(); ret = inflate(&strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR) + switch (ret) + { + case Z_NEED_DICT: + case Z_DATA_ERROR: { inflateEnd(&strm); free(result); - delete [] in; return ZR_DATA_ERROR; } - - switch (ret) + case Z_STREAM_ERROR: + case Z_BUF_ERROR: { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; - case Z_DATA_ERROR: + inflateEnd(&strm); + free(result); + return ZR_BUFFER_ERROR; + } + case Z_MEM_ERROR: + { inflateEnd(&strm); free(result); - delete [] in; return ZR_MEM_ERROR; - break; + } } U32 have = CHUNK-strm.avail_out; @@ -2231,17 +2252,15 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, { free(result); } - delete[] in; return ZR_MEM_ERROR; } result = new_result; - memcpy(result+cur_size, out, have); + memcpy(result+cur_size, out.get(), have); cur_size += have; - } while (ret == Z_OK); + } while (ret == Z_OK && ret != Z_STREAM_END); inflateEnd(&strm); - delete [] in; if (ret != Z_STREAM_END) { @@ -2251,37 +2270,11 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, //result now points to the decompressed LLSD block { - std::istringstream istr; - // Since we are using this for meshes, data we are dealing with tend to be large. - // So string can potentially fail to allocate, make sure this won't cause problems - try - { - std::string res_str((char*)result, cur_size); - - std::string deprecated_header(""); - - if (res_str.substr(0, deprecated_header.size()) == deprecated_header) - { - res_str = res_str.substr(deprecated_header.size() + 1, cur_size); - } - cur_size = res_str.size(); - - istr.str(res_str); - } -#ifdef LL_WINDOWS - catch (std::length_error) - { - free(result); - return ZR_SIZE_ERROR; - } -#endif - catch (std::bad_alloc&) - { - free(result); - return ZR_MEM_ERROR; - } + char* result_ptr = strip_deprecated_header((char*)result, cur_size); - if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH)) + boost::iostreams::stream istrm(result_ptr, cur_size); + + if (!LLSDSerialize::fromBinary(data, istrm, cur_size, UNZIP_LLSD_MAX_DEPTH)) { free(result); return ZR_PARSE_ERROR; @@ -2395,4 +2388,22 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 return result; } +char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size) +{ + const char* deprecated_header = ""; + constexpr size_t deprecated_header_size = 17; + + if (cur_size > deprecated_header_size + && memcmp(in, deprecated_header, deprecated_header_size) == 0) + { + in = in + deprecated_header_size; + cur_size = cur_size - deprecated_header_size; + if (header_size) + { + *header_size = deprecated_header_size + 1; + } + } + + return in; +} diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index d6079fd9fa..d33d2b6f34 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -858,9 +858,12 @@ public: ZR_SIZE_ERROR, ZR_DATA_ERROR, ZR_PARSE_ERROR, + ZR_BUFFER_ERROR, + ZR_VERSION_ERROR } EZipRresult; // return OK or reason for failure static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size); + static EZipRresult unzip_llsd(LLSD& data, const U8* in, S32 size); }; //dirty little zip functions -- yell at davep @@ -868,4 +871,7 @@ LL_COMMON_API std::string zip_llsd(LLSD& data); LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size); + +// returns a pointer to the array or past the array if the deprecated header exists +LL_COMMON_API char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size = nullptr); #endif // LL_LLSDSERIALIZE_H diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 93f1d508f3..91457fbebe 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2391,7 +2391,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; return false; } - + return unpackVolumeFacesInternal(mdl); +} + +bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size) +{ + //input data is now pointing at a zlib compressed block of LLSD + //decompress block + LLSD mdl; + U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size); + if (uzip_result != LLUZipHelper::ZR_OK) + { + LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; + return false; + } + return unpackVolumeFacesInternal(mdl); +} + +bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) +{ { U32 face_count = mdl.size(); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 9697952f5b..b53b0fd1cc 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1096,8 +1096,12 @@ protected: BOOL generate(); void createVolumeFaces(); public: - virtual bool unpackVolumeFaces(std::istream& is, S32 size); + bool unpackVolumeFaces(std::istream& is, S32 size); + bool unpackVolumeFaces(U8* in_data, S32 size); +private: + bool unpackVolumeFacesInternal(const LLSD& mdl); +public: virtual void setMeshAssetLoaded(BOOL loaded); virtual BOOL isMeshAssetLoaded(); -- cgit v1.2.3 From 4be11d87b5941b0a2159f62ab40500945cc873d5 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 14:44:19 -0400 Subject: Utilize pointer based unzip_llsd and unpackVolumeFaces in meshrepo and materialmgr --- indra/newview/llmaterialmgr.cpp | 18 +++++-------- indra/newview/llmeshrepository.cpp | 52 ++++---------------------------------- 2 files changed, 11 insertions(+), 59 deletions(-) diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 11aa607393..6e1e6506d9 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -429,12 +429,10 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUI llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); - LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); - std::string content_string(reinterpret_cast(content_binary.data()), content_binary.size()); - std::istringstream content_stream(content_string); + const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); LLSD response_data; - U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size()); + U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size()); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL; @@ -472,12 +470,10 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); - LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); - std::string content_string(reinterpret_cast(content_binary.data()), content_binary.size()); - std::istringstream content_stream(content_string); + const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); LLSD response_data; - U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size()); + U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size()); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL; @@ -541,12 +537,10 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); - LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); - std::string content_string(reinterpret_cast(content_binary.data()), content_binary.size()); - std::istringstream content_stream(content_string); + const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); LLSD response_data; - U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size()); + U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size()); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 4dd0543693..e1ff233354 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1911,19 +1911,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p } LLPointer volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); - std::istringstream stream; - try - { - std::string mesh_string((char*)data, data_size); - stream.str(mesh_string); - } - catch (std::bad_alloc&) - { - // out of memory, we won't be able to process this mesh - return MESH_OUT_OF_MEMORY; - } - - if (volume->unpackVolumeFaces(stream, data_size)) + if (volume->unpackVolumeFaces(data, data_size)) { if (volume->getNumFaces() > 0) { @@ -1953,10 +1941,7 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat { try { - std::string res_str((char*)data, data_size); - std::istringstream stream(res_str); - - U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size); + U32 uzip_result = LLUZipHelper::unzip_llsd(skin, data, data_size); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id @@ -1994,10 +1979,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 { try { - std::string res_str((char*)data, data_size); - std::istringstream stream(res_str); - - U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size); + U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, data, data_size); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id @@ -2006,7 +1988,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 return false; } } - catch (std::bad_alloc&) + catch (const std::bad_alloc&) { LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL; return false; @@ -2043,32 +2025,8 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_ volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH); LLPointer volume = new LLVolume(volume_params,0); - std::istringstream stream; - try - { - std::string mesh_string((char*)data, data_size); - stream.str(mesh_string); - } - catch (std::bad_alloc&) - { - // out of memory, we won't be able to process this mesh - delete d; - return MESH_OUT_OF_MEMORY; - } - - if (volume->unpackVolumeFaces(stream, data_size)) + if (volume->unpackVolumeFaces(data, data_size)) { - //load volume faces into decomposition buffer - S32 vertex_count = 0; - S32 index_count = 0; - - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = volume->getVolumeFace(i); - vertex_count += face.mNumVertices; - index_count += face.mNumIndices; - } - d->mPhysicsShapeMesh.clear(); std::vector& pos = d->mPhysicsShapeMesh.mPositions; -- cgit v1.2.3 From e097794919bff8456da498382b250891ab5235a0 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 14:48:19 -0400 Subject: Optimize mesh header size and data access throughout meshrepo --- indra/newview/llmeshrepository.cpp | 99 +++++++++++++++++++++----------------- indra/newview/llmeshrepository.h | 4 +- 2 files changed, 55 insertions(+), 48 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index e1ff233354..968d2ec8be 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -138,7 +138,7 @@ // data copied // headerReceived() invoked // LLSD parsed -// mMeshHeader, mMeshHeaderSize updated +// mMeshHeader updated // scan mPendingLOD for LOD request // push LODRequest to mLODReqQ // ... @@ -246,7 +246,6 @@ // sActiveLODRequests mMutex rw.any.mMutex, ro.repo.none [1] // sMaxConcurrentRequests mMutex wo.main.none, ro.repo.none, ro.main.mMutex // mMeshHeader mHeaderMutex rw.repo.mHeaderMutex, ro.main.mHeaderMutex, ro.main.none [0] -// mMeshHeaderSize mHeaderMutex rw.repo.mHeaderMutex // mSkinRequests mMutex rw.repo.mMutex, ro.repo.none [5] // mSkinInfoQ mMutex rw.repo.mMutex, rw.main.mMutex [5] (was: [0]) // mDecompositionRequests mMutex rw.repo.mMutex, ro.repo.none [5] @@ -1178,10 +1177,13 @@ void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) { //could be called from any thread + const LLUUID& mesh_id = mesh_params.getSculptID(); LLMutexLock lock(mMutex); - mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID()); + LLMutexLock header_lock(mHeaderMutex); + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); if (iter != mMeshHeader.end()) { //if we have the header, request LOD byte range + LODRequest req(mesh_params, lod); { mLODReqQ.push(req); @@ -1317,7 +1319,8 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) mHeaderMutex->lock(); - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; @@ -1325,13 +1328,14 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) ++LLMeshRepository::sMeshRequestCount; bool ret = true; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger(); + const LLSD& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header["skin"]["offset"].asInteger(); + S32 size = header["skin"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1413,21 +1417,23 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) mHeaderMutex->lock(); - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; bool ret = true; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger(); + const auto& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header["physics_convex"]["offset"].asInteger(); + S32 size = header["physics_convex"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1510,21 +1516,23 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) mHeaderMutex->lock(); - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; bool ret = true; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger(); + const auto& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header["physics_mesh"]["offset"].asInteger(); + S32 size = header["physics_mesh"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1704,20 +1712,25 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, return false; } - mHeaderMutex->lock(); + const LLUUID& mesh_id = mesh_params.getSculptID(); + mHeaderMutex->lock(); + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) + { //we have no header info for this mesh, do nothing + mHeaderMutex->unlock(); + return false; + } ++LLMeshRepository::sMeshRequestCount; bool retval = true; - - LLUUID mesh_id = mesh_params.getSculptID(); - U32 header_size = mMeshHeaderSize[mesh_id]; - + U32 header_size = header_it->second.first; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger(); + const auto& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger(); + S32 size = header[header_lod[lod]]["size"].asInteger(); mHeaderMutex->unlock(); if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) @@ -1878,8 +1891,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes { LLMutexLock lock(mHeaderMutex); - mMeshHeaderSize[mesh_id] = header_size; - mMeshHeader[mesh_id] = header; + mMeshHeader[mesh_id] = { header_size, header }; LLMeshRepository::sCacheBytesHeaders += header_size; } @@ -2928,7 +2940,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo if (iter != mMeshHeader.end()) { - LLSD& header = iter->second; + LLSD& header = iter->second.second; return LLMeshRepository::getActualMeshLOD(header, lod); } @@ -3173,8 +3185,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id); if (iter != gMeshRepo.mThread->mMeshHeader.end()) { - header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; - header = iter->second; + header_bytes = (S32)iter->second.first; + header = iter->second.second; } if (header_bytes > 0 @@ -4142,16 +4154,13 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) { LLMutexLock lock(mHeaderMutex); - if (mMeshHeaderSize[mesh_id] > 0) + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + if (iter != mMeshHeader.end() && iter->second.first > 0) { - mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); - if (iter != mMeshHeader.end()) + LLSD &mesh = iter->second.second; + if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) { - LLSD &mesh = iter->second; - if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) - { - return true; - } + return true; } } @@ -4176,9 +4185,9 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - LLSD& header = iter->second; + const LLSD& header = iter->second.second; if (header.has("404")) { @@ -4282,9 +4291,9 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - result = getStreamingCostLegacy(iter->second, radius, bytes, bytes_visible, lod, unscaled_value); + result = getStreamingCostLegacy(iter->second.second, radius, bytes, bytes_visible, lod, unscaled_value); } } if (result > 0.f) @@ -4597,9 +4606,9 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - LLSD& header = iter->second; + LLSD& header = iter->second.second; bool header_invalid = (header.has("404") || !header.has("lowest_lod") diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f61da3e571..6f43b0aa83 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -210,10 +210,8 @@ public: LLCondition* mSignal; //map of known mesh headers - typedef std::map mesh_header_map; + typedef boost::unordered_map> mesh_header_map; // pair is header_size and data mesh_header_map mMeshHeader; - - std::map mMeshHeaderSize; class HeaderRequest : public RequestStats { -- cgit v1.2.3 From 7dcdc4c37823c2db86454d3ba142f09b0475b4d8 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 14:54:42 -0400 Subject: Replaced usage of LLVolumeParams as map key in meshrepo with the mesh uuid --- indra/newview/llmeshrepository.cpp | 47 ++++++++++++++++++++++---------------- indra/newview/llmeshrepository.h | 4 ++-- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 968d2ec8be..d5b14dc6aa 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1193,8 +1193,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) else { HeaderRequest req(mesh_params); - - pending_lod_map::iterator pending = mPendingLOD.find(mesh_params); + pending_lod_map::iterator pending = mPendingLOD.find(mesh_id); if (pending != mPendingLOD.end()) { //append this lod request to existing header request @@ -1204,7 +1203,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) else { //if no header request is pending, fetch header mHeaderReqQ.push(req); - mPendingLOD[mesh_params].push_back(lod); + mPendingLOD[mesh_id].push_back(lod); } } } @@ -1805,16 +1804,19 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, } else { + LLMutexLock lock(mMutex); mUnavailableQ.push(LODRequest(mesh_params, lod)); } } else { + LLMutexLock lock(mMutex); mUnavailableQ.push(LODRequest(mesh_params, lod)); } } else { + LLMutexLock lock(mMutex); mUnavailableQ.push(LODRequest(mesh_params, lod)); } } @@ -1899,7 +1901,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. //check for pending requests - pending_lod_map::iterator iter = mPendingLOD.find(mesh_params); + pending_lod_map::iterator iter = mPendingLOD.find(mesh_id); if (iter != mPendingLOD.end()) { for (U32 i = 0; i < iter->second.size(); ++i) @@ -3605,15 +3607,19 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes - mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_params); + const auto& mesh_id = mesh_params.getSculptID(); + mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id); if (iter != mLoadingMeshes[detail].end()) { //request pending for this mesh, append volume id to list - iter->second.insert(vobj->getID()); + auto it = std::find(iter->second.begin(), iter->second.end(), vobj->getID()); + if (it == iter->second.end()) { + iter->second.push_back(vobj->getID()); + } } else { //first request for this mesh - mLoadingMeshes[detail][mesh_params].insert(vobj->getID()); + mLoadingMeshes[detail][mesh_id].push_back(vobj->getID()); mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail)); LLMeshRepository::sLODPending++; } @@ -3840,7 +3846,7 @@ void LLMeshRepository::notifyLoadedMeshes() for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) { F32 max_score = 0.f; - for (std::set::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) + for (std::vector::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) { LLViewerObject* object = gObjectList.findObject(*obj_iter); @@ -3855,7 +3861,7 @@ void LLMeshRepository::notifyLoadedMeshes() } } - score_map[iter->first.getSculptID()] = max_score; + score_map[iter->first] = max_score; } } @@ -3953,14 +3959,15 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail()); //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_params); + const auto& mesh_id = mesh_params.getSculptID(); + mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_id); if (volume && obj_iter != mLoadingMeshes[detail].end()) { //make sure target volume is still valid if (volume->getNumVolumeFaces() <= 0) { - LL_WARNS(LOG_MESH) << "Mesh loading returned empty volume. ID: " << mesh_params.getSculptID() + LL_WARNS(LOG_MESH) << "Mesh loading returned empty volume. ID: " << mesh_id << LL_ENDL; } @@ -3974,13 +3981,13 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } else { - LL_WARNS(LOG_MESH) << "Couldn't find system volume for mesh " << mesh_params.getSculptID() + LL_WARNS(LOG_MESH) << "Couldn't find system volume for mesh " << mesh_id << LL_ENDL; } } //notify waiting LLVOVolume instances that their requested mesh is available - for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + for (std::vector::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) { LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) @@ -3989,20 +3996,20 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } } - mLoadingMeshes[detail].erase(mesh_params); + mLoadingMeshes[detail].erase(obj_iter); } } void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod) { //called from main thread //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params); - - F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); - + const auto& mesh_id = mesh_params.getSculptID(); + mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_id); if (obj_iter != mLoadingMeshes[lod].end()) { - for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); + + for (std::vector::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) { LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) @@ -4018,7 +4025,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, } } - mLoadingMeshes[lod].erase(mesh_params); + mLoadingMeshes[lod].erase(obj_iter); } } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 6f43b0aa83..2cade8f01e 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -308,7 +308,7 @@ public: std::queue mLoadedQ; //map of pending header requests and currently desired LODs - typedef std::map > pending_lod_map; + typedef boost::unordered_map > pending_lod_map; pending_lod_map mPendingLOD; // llcorehttp library interface objects. @@ -611,7 +611,7 @@ public: static void metricsProgress(unsigned int count); static void metricsUpdate(); - typedef std::map > mesh_load_map; + typedef boost::unordered_map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; typedef std::unordered_map skin_map; -- cgit v1.2.3 From e83146ce0c4310c7a0c03a10b562e7317df034f6 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 16:26:18 -0400 Subject: Optimize away constant map finds in getSkinInfo by caching mesh skin into in vovolume --- indra/llprimitive/llmodel.cpp | 10 ++++++ indra/llprimitive/llmodel.h | 3 +- indra/newview/llmeshrepository.cpp | 71 +++++++++++++++++++++++++++++++------- indra/newview/llmeshrepository.h | 9 +++-- indra/newview/llvovolume.cpp | 36 ++++++++++++++++++- indra/newview/llvovolume.h | 4 +++ 6 files changed, 116 insertions(+), 17 deletions(-) diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 555164f3b0..444d9a5366 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1389,6 +1389,16 @@ LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin): fromLLSD(skin); } +LLMeshSkinInfo::LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& skin) : + mMeshID(mesh_id), + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false), + mJointNumsInitialized(false) +{ + fromLLSD(skin); +} + void LLMeshSkinInfo::fromLLSD(LLSD& skin) { if (skin.has("joint_names")) diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index a6ab96ab18..9c99bb75a0 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -41,12 +41,13 @@ class domMesh; #define MAX_MODEL_FACES 8 LL_ALIGN_PREFIX(16) -class LLMeshSkinInfo +class LLMeshSkinInfo : public LLRefCount { LL_ALIGN_NEW public: LLMeshSkinInfo(); LLMeshSkinInfo(LLSD& data); + LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data); void fromLLSD(LLSD& data); LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; void updateHash(); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index d5b14dc6aa..ced64b655e 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1972,8 +1972,16 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat } { - LLMeshSkinInfo info(skin); - info.mMeshID = mesh_id; + LLMeshSkinInfo* info = nullptr; + try + { + info = new LLMeshSkinInfo(mesh_id, skin); + } + catch (const std::bad_alloc& ex) + { + LL_WARNS() << "Failed to allocate skin info with exception: " << ex.what() << LL_ENDL; + return false; + } // LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL; { @@ -2898,7 +2906,7 @@ void LLMeshRepoThread::notifyLoadedMeshes() { if (mMutex->trylock()) { - std::list skin_info_q; + std::list skin_info_q; std::list decomp_q; if (! mSkinInfoQ.empty()) @@ -3491,7 +3499,7 @@ LLMeshRepository::LLMeshRepository() mMeshThreadCount(0), mThread(NULL) { - + mSkinInfoCullTimer.resetWithExpiry(10.f); } void LLMeshRepository::init() @@ -3776,6 +3784,28 @@ void LLMeshRepository::notifyLoadedMeshes() //call completed callbacks on finished decompositions mDecompThread->notifyCompleted(); + if (mSkinInfoCullTimer.checkExpirationAndReset(10.f)) + { + //// Clean up dead skin info + //U64Bytes skinbytes(0); + for (auto iter = mSkinMap.begin(), ender = mSkinMap.end(); iter != ender;) + { + auto copy_iter = iter++; + + //skinbytes += U64Bytes(sizeof(LLMeshSkinInfo)); + //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(std::string)); + //skinbytes += U64Bytes(copy_iter->second->mJointNums.size() * sizeof(S32)); + //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(LLMatrix4a)); + //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(LLMatrix4)); + + if (copy_iter->second->getNumRefs() == 1) + { + mSkinMap.erase(copy_iter); + } + } + //LL_INFOS() << "Skin info cache elements:" << mSkinMap.size() << " Memory: " << U64Kilobytes(skinbytes) << LL_ENDL; + } + // For major operations, attempt to get the required locks // without blocking and punt if they're not available. The // longest run of holdoffs is kept in sMaxLockHoldoffs just @@ -3913,13 +3943,13 @@ void LLMeshRepository::notifyLoadedMeshes() mThread->mSignal->signal(); } -void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info) +void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info) { - mSkinMap[info.mMeshID] = info; + mSkinMap[info->mMeshID] = info; // Cache into LLPointer // Alternative: We can get skin size from header - sCacheBytesSkins += info.sizeBytes(); + sCacheBytesSkins += info->sizeBytes(); - skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID); + skin_load_map::iterator iter = mLoadingSkins.find(info->mMeshID); if (iter != mLoadingSkins.end()) { for (std::set::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) @@ -3927,10 +3957,27 @@ void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info) LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); if (vobj) { - vobj->notifyMeshLoaded(); + vobj->notifySkinInfoLoaded(info); + } + } + mLoadingSkins.erase(iter); + } +} + +void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id) +{ + skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); + if (iter != mLoadingSkins.end()) + { + for (std::set::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) + { + LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); + if (vobj) + { + vobj->notifySkinInfoUnavailable(); } } - mLoadingSkins.erase(info.mMeshID); + mLoadingSkins.erase(iter); } } @@ -4042,7 +4089,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const skin_map::iterator iter = mSkinMap.find(mesh_id); if (iter != mSkinMap.end()) { - return &(iter->second); + return iter->second; } //no skin info known about given mesh, try to fetch it @@ -4058,7 +4105,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const mLoadingSkins[mesh_id].insert(requesting_obj->getID()); } } - return NULL; + return nullptr; } void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 2cade8f01e..a5b985ee76 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -284,7 +284,7 @@ public: std::set mSkinRequests; // list of completed skin info requests - std::list mSkinInfoQ; + std::list mSkinInfoQ; //set of requested decompositions std::set mDecompositionRequests; @@ -581,7 +581,8 @@ public: void notifyLoadedMeshes(); void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume); void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod); - void notifySkinInfoReceived(LLMeshSkinInfo& info); + void notifySkinInfoReceived(LLMeshSkinInfo* info); + void notifySkinInfoUnavailable(const LLUUID& info); void notifyDecompositionReceived(LLModel::Decomposition* info); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); @@ -614,7 +615,7 @@ public: typedef boost::unordered_map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; - typedef std::unordered_map skin_map; + typedef std::unordered_map> skin_map; skin_map mSkinMap; typedef std::map decomposition_map; @@ -650,6 +651,8 @@ public: std::vector mUploadWaitList; LLPhysicsDecomp* mDecompThread; + + LLFrameTimer mSkinInfoCullTimer; class inventory_data { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f4a938e57d..d5583f05f3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -228,6 +228,9 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mColorChanged = FALSE; mSpotLightPriority = 0.f; + mSkinInfoFailed = false; + mSkinInfo = NULL; + mMediaImplList.resize(getNumTEs()); mLastFetchedMediaVersion = -1; mServerDrawableUpdateCount = 0; @@ -1095,6 +1098,12 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo // if it's a mesh if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { + if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID()) + { + mSkinInfo = NULL; + mSkinInfoFailed = false; + } + if (!getVolume()->isMeshAssetLoaded()) { //load request not yet issued, request pipeline load this mesh @@ -1106,6 +1115,14 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } + if (!mSkinInfo && !mSkinInfoFailed) + { + const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this); + if (skin_info) + { + notifySkinInfoLoaded(skin_info); + } + } } else // otherwise is sculptie { @@ -1158,6 +1175,9 @@ void LLVOVolume::updateSculptTexture() { mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); } + + mSkinInfoFailed = false; + mSkinInfo = NULL; } else { @@ -1212,6 +1232,20 @@ void LLVOVolume::notifyMeshLoaded() updateVisualComplexity(); } +void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin) +{ + mSkinInfoFailed = false; + mSkinInfo = skin; + + notifyMeshLoaded(); +} + +void LLVOVolume::notifySkinInfoUnavailable() +{ + mSkinInfoFailed = true; + mSkinInfo = nullptr; +} + // sculpt replaces generate() for sculpted surfaces void LLVOVolume::sculpt() { @@ -3645,7 +3679,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const { if (getVolume()) { - return gMeshRepo.getSkinInfo(getMeshID(), this); + return mSkinInfo; } else { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 4136c13315..12681e2bd9 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -350,6 +350,8 @@ public: void updateVisualComplexity(); void notifyMeshLoaded(); + void notifySkinInfoLoaded(const LLMeshSkinInfo* skin); + void notifySkinInfoUnavailable(); // Returns 'true' iff the media data for this object is in flight bool isMediaDataBeingFetched() const; @@ -433,6 +435,8 @@ private: LLPointer mRiggedVolume; + bool mSkinInfoFailed; + LLConstPointer mSkinInfo; // statics public: static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop -- cgit v1.2.3 From bd20b61b8261623d75bbb22e7d368743d7bd971a Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 17:14:19 -0400 Subject: Optimize away gObjectList finds during mesh load --- indra/newview/llmeshrepository.cpp | 55 +++++++++++++++++++++++++------------- indra/newview/llmeshrepository.h | 7 ++--- indra/newview/llvovolume.cpp | 2 ++ 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index ced64b655e..ed942eca31 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3600,6 +3600,22 @@ S32 LLMeshRepository::update() return size ; } +void LLMeshRepository::unregisterMesh(LLVOVolume* vobj) +{ + for (auto& lod : mLoadingMeshes) + { + for (auto& param : lod) + { + vector_replace_with_last(param.second, vobj); + } + } + + for (auto& skin_pair : mLoadingSkins) + { + vector_replace_with_last(skin_pair.second, vobj); + } +} + S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); @@ -3619,15 +3635,15 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id); if (iter != mLoadingMeshes[detail].end()) { //request pending for this mesh, append volume id to list - auto it = std::find(iter->second.begin(), iter->second.end(), vobj->getID()); + auto it = std::find(iter->second.begin(), iter->second.end(), vobj); if (it == iter->second.end()) { - iter->second.push_back(vobj->getID()); + iter->second.push_back(vobj); } } else { //first request for this mesh - mLoadingMeshes[detail][mesh_id].push_back(vobj->getID()); + mLoadingMeshes[detail][mesh_id].push_back(vobj); mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail)); LLMeshRepository::sLODPending++; } @@ -3876,10 +3892,9 @@ void LLMeshRepository::notifyLoadedMeshes() for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) { F32 max_score = 0.f; - for (std::vector::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) + for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) { - LLViewerObject* object = gObjectList.findObject(*obj_iter); - + LLVOVolume* object = *obj_iter; if (object) { LLDrawable* drawable = object->mDrawable; @@ -3952,9 +3967,8 @@ void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info) skin_load_map::iterator iter = mLoadingSkins.find(info->mMeshID); if (iter != mLoadingSkins.end()) { - for (std::set::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) + for (LLVOVolume* vobj : iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); if (vobj) { vobj->notifySkinInfoLoaded(info); @@ -3969,9 +3983,8 @@ void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id) skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); if (iter != mLoadingSkins.end()) { - for (std::set::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) + for (LLVOVolume* vobj : iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); if (vobj) { vobj->notifySkinInfoUnavailable(); @@ -4034,9 +4047,8 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } //notify waiting LLVOVolume instances that their requested mesh is available - for (std::vector::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + for (LLVOVolume* vobj : obj_iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) { vobj->notifyMeshLoaded(); @@ -4056,9 +4068,8 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, { F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); - for (std::vector::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + for (LLVOVolume* vobj : obj_iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) { LLVolume* obj_volume = vobj->getVolume(); @@ -4081,7 +4092,7 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo return mThread->getActualMeshLOD(mesh_params, lod); } -const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj) +const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (mesh_id.notNull()) @@ -4098,11 +4109,19 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); - if (iter == mLoadingSkins.end()) - { //no request pending for this skin info + if (iter != mLoadingSkins.end()) + { //request pending for this mesh, append volume id to list + auto it = std::find(iter->second.begin(), iter->second.end(), requesting_obj); + if (it == iter->second.end()) { + iter->second.push_back(requesting_obj); + } + } + else + { + //first request for this mesh + mLoadingSkins[mesh_id].push_back(requesting_obj); mPendingSkinRequests.push(mesh_id); } - mLoadingSkins[mesh_id].insert(requesting_obj->getID()); } } return nullptr; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index a5b985ee76..01a8427757 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -575,6 +575,7 @@ public: void shutdown(); S32 update(); + void unregisterMesh(LLVOVolume* volume); //mesh management functions S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1); @@ -587,7 +588,7 @@ public: S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); static S32 getActualMeshLOD(LLSD& header, S32 lod); - const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj = nullptr); + const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr); LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); void fetchPhysicsShape(const LLUUID& mesh_id); bool hasPhysicsShape(const LLUUID& mesh_id); @@ -612,7 +613,7 @@ public: static void metricsProgress(unsigned int count); static void metricsUpdate(); - typedef boost::unordered_map > mesh_load_map; + typedef boost::unordered_map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; typedef std::unordered_map> skin_map; @@ -626,7 +627,7 @@ public: std::vector mPendingRequests; //list of mesh ids awaiting skin info - typedef std::map > skin_load_map; + typedef boost::unordered_map > skin_load_map; skin_load_map mLoadingSkins; //list of mesh ids that need to send skin info fetch requests diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d5583f05f3..8cfa83ba46 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -247,6 +247,8 @@ LLVOVolume::~LLVOVolume() delete mVolumeImpl; mVolumeImpl = NULL; + gMeshRepo.unregisterMesh(this); + if(!mMediaImplList.empty()) { for(U32 i = 0 ; i < mMediaImplList.size() ; i++) -- cgit v1.2.3 From 9ec86c84e3d75feb5505a98e96db542b054e162e Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 17:35:23 -0400 Subject: Add proper retry support to skin info fetch --- indra/newview/llmeshrepository.cpp | 115 +++++++++++++++++++++++++------------ indra/newview/llmeshrepository.h | 9 ++- 2 files changed, 83 insertions(+), 41 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index ed942eca31..53ce952739 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -857,6 +857,12 @@ LLMeshRepoThread::~LLMeshRepoThread() mHttpRequestSet.clear(); mHttpHeaders.reset(); + while (!mSkinInfoQ.empty()) + { + delete mSkinInfoQ.front(); + mSkinInfoQ.pop_front(); + } + while (!mDecompositionQ.empty()) { delete mDecompositionQ.front(); @@ -946,6 +952,7 @@ void LLMeshRepoThread::run() else { // too many fails + LLMutexLock lock(mMutex); mUnavailableQ.push(req); LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL; } @@ -1022,37 +1029,42 @@ void LLMeshRepoThread::run() if (!mSkinRequests.empty()) { - std::set incomplete; - while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - mMutex->lock(); - std::set::iterator iter = mSkinRequests.begin(); - UUIDBasedRequest req = *iter; - mSkinRequests.erase(iter); - mMutex->unlock(); - if (req.isDelayed()) - { - incomplete.insert(req); - } - else if (!fetchMeshSkinInfo(req.mId)) - { - if (req.canRetry()) - { - req.updateTime(); - incomplete.insert(req); - } - else - { - LL_DEBUGS() << "mSkinRequests failed: " << req.mId << LL_ENDL; - } - } - } + std::list incomplete; + while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { - if (!incomplete.empty()) - { - LLMutexLock locker(mMutex); - mSkinRequests.insert(incomplete.begin(), incomplete.end()); - } + mMutex->lock(); + auto req = mSkinRequests.front(); + mSkinRequests.pop_front(); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.emplace_back(req); + } + else if (!fetchMeshSkinInfo(req.mId, req.canRetry())) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.emplace_back(req); + } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.push_back(req); + LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL; + } + } + } + + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + for (const auto& req : incomplete) + { + mSkinRequests.push_back(req); + } + } } // holding lock, try next list @@ -1151,7 +1163,7 @@ void LLMeshRepoThread::run() // Mutex: LLMeshRepoThread::mMutex must be held on entry void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id) { - mSkinRequests.insert(UUIDBasedRequest(mesh_id)); + mSkinRequests.push_back(UUIDBasedRequest(mesh_id)); } // Mutex: LLMeshRepoThread::mMutex must be held on entry @@ -1308,7 +1320,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, } -bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) +bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) { if (!mHeaderMutex) @@ -1390,13 +1402,28 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) << LL_ENDL; ret = false; } - else + else if(can_retry) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.emplace_back(mesh_id); + } + } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.emplace_back(mesh_id); } } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.emplace_back(mesh_id); + } } else { @@ -2906,13 +2933,20 @@ void LLMeshRepoThread::notifyLoadedMeshes() { if (mMutex->trylock()) { - std::list skin_info_q; + std::deque skin_info_q; + std::deque skin_info_unavail_q; std::list decomp_q; if (! mSkinInfoQ.empty()) { skin_info_q.swap(mSkinInfoQ); } + + if (! mSkinUnavailableQ.empty()) + { + skin_info_unavail_q.swap(mSkinUnavailableQ); + } + if (! mDecompositionQ.empty()) { decomp_q.swap(mDecompositionQ); @@ -2926,6 +2960,11 @@ void LLMeshRepoThread::notifyLoadedMeshes() gMeshRepo.notifySkinInfoReceived(skin_info_q.front()); skin_info_q.pop_front(); } + while (! skin_info_unavail_q.empty()) + { + gMeshRepo.notifySkinInfoUnavailable(skin_info_unavail_q.front().mId); + skin_info_unavail_q.pop_front(); + } while (! decomp_q.empty()) { @@ -3357,9 +3396,8 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status) << ", Reason: " << status.toString() << " (" << status.toTerseString() << "). Not retrying." << LL_ENDL; - - // *TODO: Mark mesh unavailable on error. For now, simply leave - // request unfulfilled rather than retry forever. + LLMutexLock lock(gMeshRepo.mThread->mMutex); + gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID); } void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, @@ -3390,7 +3428,8 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* LL_WARNS(LOG_MESH) << "Error during mesh skin info processing. ID: " << mMeshID << ", Unknown reason. Not retrying." << LL_ENDL; - // *TODO: Mark mesh unavailable on error + LLMutexLock lock(gMeshRepo.mThread->mMutex); + gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID); } } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 01a8427757..f62216d8ba 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -281,10 +281,13 @@ public: }; //set of requested skin info - std::set mSkinRequests; + std::deque mSkinRequests; // list of completed skin info requests - std::list mSkinInfoQ; + std::deque mSkinInfoQ; + + // list of skin info requests that have failed or are unavailaibe + std::deque mSkinUnavailableQ; //set of requested decompositions std::set mDecompositionRequests; @@ -352,7 +355,7 @@ public: //send request for skin info, returns true if header info exists // (should hold onto mesh_id and try again later if header info does not exist) - bool fetchMeshSkinInfo(const LLUUID& mesh_id); + bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry = true); //send request for decomposition, returns true if header info exists // (should hold onto mesh_id and try again later if header info does not exist) -- cgit v1.2.3 From 07449892df0cfcfa22583d7d7c7b29098e3af499 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 17:54:30 -0400 Subject: Optimize mesh queue processing on main thread to reduce mutex contention --- indra/newview/llmeshrepository.cpp | 83 +++++++++++++++++++++----------------- indra/newview/llmeshrepository.h | 4 +- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 53ce952739..8c85b30e04 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -953,7 +953,7 @@ void LLMeshRepoThread::run() { // too many fails LLMutexLock lock(mMutex); - mUnavailableQ.push(req); + mUnavailableQ.push_back(req); LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL; } } @@ -1832,19 +1832,19 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, else { LLMutexLock lock(mMutex); - mUnavailableQ.push(LODRequest(mesh_params, lod)); + mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else { LLMutexLock lock(mMutex); - mUnavailableQ.push(LODRequest(mesh_params, lod)); + mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else { LLMutexLock lock(mMutex); - mUnavailableQ.push(LODRequest(mesh_params, lod)); + mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else @@ -1959,7 +1959,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p LoadedMesh mesh(volume, mesh_params, lod); { LLMutexLock lock(mMutex); - mLoadedQ.push(mesh); + mLoadedQ.push_back(mesh); // LLPointer is not thread safe, since we added this pointer into // threaded list, make sure counter gets decreased inside mutex lock // and won't affect mLoadedQ processing @@ -2888,45 +2888,52 @@ void LLMeshRepoThread::notifyLoadedMeshes() return; } - while (!mLoadedQ.empty()) + if (!mLoadedQ.empty()) { + std::deque loaded_queue; + mMutex->lock(); - if (mLoadedQ.empty()) + if (!mLoadedQ.empty()) { + loaded_queue.swap(mLoadedQ); mMutex->unlock(); - break; - } - LoadedMesh mesh = mLoadedQ.front(); // make sure nothing else owns volume pointer by this point - mLoadedQ.pop(); - mMutex->unlock(); - - update_metrics = true; - if (mesh.mVolume->getNumVolumeFaces() > 0) - { - gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume); - } - else - { - gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams, - LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail())); + + update_metrics = true; + + // Process the elements free of the lock + for (const auto& mesh : loaded_queue) + { + if (mesh.mVolume->getNumVolumeFaces() > 0) + { + gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume); + } + else + { + gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams, + LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail())); + } + } } } - while (!mUnavailableQ.empty()) + if (!mUnavailableQ.empty()) { + std::deque unavil_queue; + mMutex->lock(); - if (mUnavailableQ.empty()) + if (!mUnavailableQ.empty()) { + unavil_queue.swap(mUnavailableQ); mMutex->unlock(); - break; - } - - LODRequest req = mUnavailableQ.front(); - mUnavailableQ.pop(); - mMutex->unlock(); - update_metrics = true; - gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD); + update_metrics = true; + + // Process the elements free of the lock + for (const auto& req : unavil_queue) + { + gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD); + } + } } if (! mSkinInfoQ.empty() || ! mDecompositionQ.empty()) @@ -3192,7 +3199,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status) LLMutexLock lock(gMeshRepo.mThread->mMutex); for (int i(0); i < 4; ++i) { - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } } @@ -3221,7 +3228,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMutexLock lock(gMeshRepo.mThread->mMutex); for (int i(0); i < 4; ++i) { - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } } else if (data && data_size > 0) @@ -3303,7 +3310,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMutexLock lock(gMeshRepo.mThread->mMutex); for (int i(0); i < 4; ++i) { - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } } } @@ -3330,7 +3337,7 @@ void LLMeshLODHandler::processFailure(LLCore::HttpStatus status) << LL_ENDL; LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, @@ -3367,7 +3374,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body << " Not retrying." << LL_ENDL; LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } } else @@ -3378,7 +3385,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body << " Data size: " << data_size << LL_ENDL; LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f62216d8ba..e3688ff243 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -305,10 +305,10 @@ public: std::queue mLODReqQ; //queue of unavailable LODs (either asset doesn't exist or asset doesn't have desired LOD) - std::queue mUnavailableQ; + std::deque mUnavailableQ; //queue of successfully loaded meshes - std::queue mLoadedQ; + std::deque mLoadedQ; //map of pending header requests and currently desired LODs typedef boost::unordered_map > pending_lod_map; -- cgit v1.2.3 From 9f633e087fa0855ee8358e3e84924872ec5d965f Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 17:58:01 -0400 Subject: Optimize away many string copies in mesh header processing with boost iostream array adapters --- indra/newview/llmeshrepository.cpp | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 8c85b30e04..3ed7e9289d 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -77,6 +77,8 @@ #include "lluploaddialog.h" #include "llfloaterreg.h" +#include "boost/iostreams/device/array.hpp" +#include "boost/iostreams/stream.hpp" #include "boost/lexical_cast.hpp" #ifndef LL_WINDOWS @@ -1863,27 +1865,12 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes U32 header_size = 0; if (data_size > 0) { - std::istringstream stream; - try - { - std::string res_str((char*)data, data_size); - - std::string deprecated_header(""); + U32 dsize = data_size; + char* result_ptr = strip_deprecated_header((char*)data, dsize, &header_size); - if (res_str.substr(0, deprecated_header.size()) == deprecated_header) - { - res_str = res_str.substr(deprecated_header.size() + 1, data_size); - header_size = deprecated_header.size() + 1; - } - data_size = res_str.size(); + data_size = dsize; - stream.str(res_str); - } - catch (std::bad_alloc&) - { - // out of memory, we won't be able to process this mesh - return MESH_OUT_OF_MEMORY; - } + boost::iostreams::stream stream(result_ptr, data_size); if (!LLSDSerialize::fromBinary(header, stream, data_size)) { -- cgit v1.2.3 From 198420f9f61bc0f747102a2d5783327f13583be8 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 28 Sep 2022 14:16:16 +0300 Subject: SL-18248 Move frame breakdown stats to 'Scene loading statistics' floater --- doc/contributions.txt | 1 + indra/newview/llviewerstats.cpp | 91 ++++++++++++++++++++++ .../default/xui/en/floater_scene_load_stats.xml | 53 +++++++++++++ 3 files changed, 145 insertions(+) diff --git a/doc/contributions.txt b/doc/contributions.txt index 2c1e5487ce..e059f3bb38 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -281,6 +281,7 @@ Beq Janus SL-11300 SL-15709 SL-16021 + SL-18202 Beth Walcher Bezilon Kasei Biancaluce Robbiani 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 AVATAR_EDIT_TIME("avataredittime", "Second LLTrace::EventStatHandle > OBJECT_CACHE_HIT_RATE("object_cache_hits"); LLTrace::EventStatHandle TEXTURE_FETCH_TIME("texture_fetch_time"); + +LLTrace::SampleStatHandle > SCENERY_FRAME_PCT("scenery_frame_pct"); +LLTrace::SampleStatHandle > AVATAR_FRAME_PCT("avatar_frame_pct"); +LLTrace::SampleStatHandle > HUDS_FRAME_PCT("huds_frame_pct"); +LLTrace::SampleStatHandle > UI_FRAME_PCT("ui_frame_pct"); +LLTrace::SampleStatHandle > SWAP_FRAME_PCT("swap_frame_pct"); +LLTrace::SampleStatHandle > 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 @@ + + + + + + + + -- cgit v1.2.3 From d1701fb5b1a1cef281b04a8004f133ff7efa7db3 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Wed, 28 Sep 2022 09:55:57 -0400 Subject: Fix small bug in unavail skin info processing --- indra/newview/llmeshrepository.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 3ed7e9289d..f937754368 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2923,7 +2923,7 @@ void LLMeshRepoThread::notifyLoadedMeshes() } } - if (! mSkinInfoQ.empty() || ! mDecompositionQ.empty()) + if (!mSkinInfoQ.empty() || !mSkinUnavailableQ.empty() || ! mDecompositionQ.empty()) { if (mMutex->trylock()) { -- cgit v1.2.3 From c88767e27d7d4f2ca1781ff3aab74b1226e10207 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 28 Sep 2022 17:01:24 +0300 Subject: SL-18240 Don't disable HUD media when "Obscure MOAP" is active on land --- indra/newview/llviewermedia.cpp | 16 +++++++++++++++- indra/newview/llviewermedia.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 636909e6f2..a1cb152e1e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -3883,7 +3883,7 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const // bool LLViewerMediaImpl::isObscured() const { - if (getUsedInUI() || isParcelMedia()) return false; + if (getUsedInUI() || isParcelMedia() || isAttachedToHUD()) return false; LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!agent_parcel) @@ -3899,6 +3899,20 @@ bool LLViewerMediaImpl::isObscured() const return false; } +bool LLViewerMediaImpl::isAttachedToHUD() const +{ + std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin(); + std::list< LLVOVolume* >::const_iterator end = mObjectList.end(); + for ( ; iter != end; iter++) + { + if ((*iter)->isHUDAttachment()) + { + return true; + } + } + return false; +} + ////////////////////////////////////////////////////////////////////////////////////////// // bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index b95cfd4c68..f1f42afd81 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -411,6 +411,8 @@ public: void cancelMimeTypeProbe(); + bool isAttachedToHUD() const; + // Is this media attached to an avatar *not* self bool isAttachedToAnotherAvatar() const; -- cgit v1.2.3 From 6661e0fdc5becd17d438e0a1a5c47094598667fc Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 28 Sep 2022 17:37:33 +0300 Subject: SL-18240 Don't disable HUD media when "Obscure MOAP" is active on land --- indra/newview/llviewermedia.cpp | 16 +++++++++++++++- indra/newview/llviewermedia.h | 2 ++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 84013c488f..8570c0cd5d 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -3896,7 +3896,7 @@ bool LLViewerMediaImpl::shouldShowBasedOnClass() const // bool LLViewerMediaImpl::isObscured() const { - if (getUsedInUI() || isParcelMedia()) return false; + if (getUsedInUI() || isParcelMedia() || isAttachedToHUD()) return false; LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel(); if (!agent_parcel) @@ -3912,6 +3912,20 @@ bool LLViewerMediaImpl::isObscured() const return false; } +bool LLViewerMediaImpl::isAttachedToHUD() const +{ + std::list< LLVOVolume* >::const_iterator iter = mObjectList.begin(); + std::list< LLVOVolume* >::const_iterator end = mObjectList.end(); + for ( ; iter != end; iter++) + { + if ((*iter)->isHUDAttachment()) + { + return true; + } + } + return false; +} + ////////////////////////////////////////////////////////////////////////////////////////// // bool LLViewerMediaImpl::isAttachedToAnotherAvatar() const diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h index b95cfd4c68..f1f42afd81 100644 --- a/indra/newview/llviewermedia.h +++ b/indra/newview/llviewermedia.h @@ -411,6 +411,8 @@ public: void cancelMimeTypeProbe(); + bool isAttachedToHUD() const; + // Is this media attached to an avatar *not* self bool isAttachedToAnotherAvatar() const; -- cgit v1.2.3 From 6614a6ee9987ac2b199aaabe7d9cd520c613c13f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 28 Sep 2022 18:42:10 +0300 Subject: SL-18249 Optimizations to mesh and material loading --- doc/contributions.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/contributions.txt b/doc/contributions.txt index 2c1e5487ce..d74ec13637 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -1384,6 +1384,7 @@ Sovereign Engineer SL-14732 SL-15096 SL-16127 + SL-18249 SpacedOut Frye VWR-34 VWR-45 -- cgit v1.2.3 From 9104b899961a9ceb61de73528e85f1a240f30cb5 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 30 Sep 2022 00:26:44 +0300 Subject: SL-18235 Remove outfit buttons from unpacking dialog --- indra/newview/llfloateropenobject.cpp | 14 ------ indra/newview/llfloateropenobject.h | 2 - indra/newview/llpanelobjectinventory.cpp | 21 ++++++--- indra/newview/llpanelobjectinventory.h | 11 ++++- .../skins/default/xui/en/floater_openobject.xml | 52 ++-------------------- 5 files changed, 28 insertions(+), 72 deletions(-) diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 2a1749bd42..a682064dad 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -56,8 +56,6 @@ LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key) mDirty(TRUE) { mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this)); - mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this)); - mCommitCallbackRegistrar.add("OpenObject.ReplaceOutfit", boost::bind(&LLFloaterOpenObject::onClickReplace, this)); mCommitCallbackRegistrar.add("OpenObject.Cancel", boost::bind(&LLFloaterOpenObject::onClickCancel, this)); } @@ -243,18 +241,6 @@ void LLFloaterOpenObject::onClickMoveToInventory() closeFloater(); } -void LLFloaterOpenObject::onClickMoveAndWear() -{ - moveToInventory(true, false); - closeFloater(); -} - -void LLFloaterOpenObject::onClickReplace() -{ - moveToInventory(true, true); - closeFloater(); -} - void LLFloaterOpenObject::onClickCancel() { closeFloater(); diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h index 2e761f99bf..745753316b 100644 --- a/indra/newview/llfloateropenobject.h +++ b/indra/newview/llfloateropenobject.h @@ -63,8 +63,6 @@ protected: void moveToInventory(bool wear, bool replace = false); void onClickMoveToInventory(); - void onClickMoveAndWear(); - void onClickReplace(); void onClickCancel(); static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace = false); static void callbackMoveInventory(S32 result, void* data); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index cfaa9456be..5ac5f0d429 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1275,7 +1275,8 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par mHaveInventory(FALSE), mIsInventoryEmpty(TRUE), mInventoryNeedsUpdate(FALSE), - mInventoryViewModel(p.name) + mInventoryViewModel(p.name), + mShowRootFolder(p.show_root_folder) { // Setup context menu callbacks mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2)); @@ -1526,15 +1527,23 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root p.font_highlight_color = item_color; LLFolderViewFolder* new_folder = LLUICtrlFactory::create(p); - new_folder->addToFolder(mFolders); - new_folder->toggleOpen(); + + if (mShowRootFolder) + { + new_folder->addToFolder(mFolders); + new_folder->toggleOpen(); + } if (!contents.empty()) { - createViewsForCategory(&contents, inventory_root, new_folder); + createViewsForCategory(&contents, inventory_root, mShowRootFolder ? new_folder : mFolders); } - // Refresh for label to add item count - new_folder->refresh(); + + if (mShowRootFolder) + { + // Refresh for label to add item count + new_folder->refresh(); + } } } diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index 7b9ecfb8f3..0e450d8ce9 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -48,8 +48,14 @@ class LLViewerObject; class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener { public: - // dummy param block for template registration purposes - struct Params : public LLPanel::Params {}; + struct Params : public LLInitParam::Block + { + Optional show_root_folder; + + Params() + : show_root_folder("show_root_folder", true) + {} + }; LLPanelObjectInventory(const Params&); virtual ~LLPanelObjectInventory(); @@ -110,6 +116,7 @@ private: BOOL mIsInventoryEmpty; // 'Empty' label BOOL mInventoryNeedsUpdate; // for idle, set on changed callback LLFolderViewModelInventory mInventoryViewModel; + bool mShowRootFolder; }; #endif // LL_LLPANELOBJECTINVENTORY_H diff --git a/indra/newview/skins/default/xui/en/floater_openobject.xml b/indra/newview/skins/default/xui/en/floater_openobject.xml index 912db80bcc..ec03d7d32c 100644 --- a/indra/newview/skins/default/xui/en/floater_openobject.xml +++ b/indra/newview/skins/default/xui/en/floater_openobject.xml @@ -3,7 +3,7 @@ legacy_header_height="18" can_resize="true" default_tab_group="1" - height="370" + height="350" layout="topleft" min_height="190" min_width="285" @@ -31,62 +31,18 @@ background_visible="false" draw_border="false" follows="all" - height="240" + height="265" layout="topleft" + show_root_folder="false" left="10" name="object_contents" top_pad="0" width="284" /> - - - Copy to inventory and wear - - - + + -- cgit v1.2.3 From 439aa79414edfe48f3bfa5d154987d741308bdbb Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Mon, 24 Oct 2022 22:14:20 +0300 Subject: SL-18432 Fix for alpha sorting --- doc/contributions.txt | 1 + indra/newview/llspatialpartition.h | 2 +- indra/newview/llvovolume.cpp | 51 ++++++-------------------------------- 3 files changed, 9 insertions(+), 45 deletions(-) diff --git a/doc/contributions.txt b/doc/contributions.txt index a693c22abc..9368781c9a 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -236,6 +236,7 @@ Ansariel Hiller SL-15226 SL-15227 SL-15398 + SL-18432 Aralara Rajal Arare Chantilly CHUIBUG-191 diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index f7bc9fb644..6d3ef33801 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -264,7 +264,7 @@ public: return lhs->mAvatarp < rhs->mAvatarp; } - return lhs->mRenderOrder < rhs->mRenderOrder; + return lhs->mRenderOrder > rhs->mRenderOrder; } }; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e923115c43..a4e0d367c8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5515,7 +5515,7 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[1] < MAX_FACE_COUNT) { - //face->setDrawOrderIndex(count[1]); + face->setDrawOrderIndex(count[1]); list[1][count[1]++] = face; } } @@ -5523,36 +5523,12 @@ static inline void add_face(T*** list, U32* count, T* face) { if (count[0] < MAX_FACE_COUNT) { - //face->setDrawOrderIndex(count[0]); + face->setDrawOrderIndex(count[0]); list[0][count[0]++] = face; } } } -// return index into linkset for given object (0 for root prim) -U32 get_linkset_index(LLVOVolume* vobj) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; - if (vobj->isRootEdit()) - { - return 0; - } - - LLViewerObject* root = vobj->getRootEdit(); - U32 idx = 1; - for (const auto& child : root->getChildren()) - { - if (child == vobj) - { - return idx; - } - ++idx; - } - - llassert(false); - return idx; //should never get here -} - void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; @@ -5714,8 +5690,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { avatar->addAttachmentOverridesForObject(vobj, NULL, false); } - - U32 linkset_index = get_linkset_index(vobj); // Standard rigged mesh attachments: bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment(); @@ -5736,9 +5710,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } - // order by linkset index first and face index second - facep->setDrawOrderIndex(linkset_index * 100 + i); - //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group facep->setVertexBuffer(NULL); @@ -5763,6 +5734,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (facep->isState(LLFace::RIGGED)) { //face is not rigged but used to be, remove from rigged face pool + LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool(); + if (pool) + { + pool->removeFace(facep); + } facep->clearState(LLFace::RIGGED); facep->mAvatar = NULL; facep->mSkinInfo = NULL; @@ -6216,14 +6192,6 @@ struct CompareBatchBreakerRigged } }; -struct CompareDrawOrder -{ - bool operator()(const LLFace* const& lhs, const LLFace* const& rhs) - { - return lhs->getDrawOrderIndex() < rhs->getDrawOrderIndex(); - } -}; - U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL rigged) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; @@ -6267,11 +6235,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace //sort faces by things that break batches, including avatar and mesh id std::sort(faces, faces + face_count, CompareBatchBreakerRigged()); } - else - { - // preserve legacy draw order for rigged faces - std::sort(faces, faces + face_count, CompareDrawOrder()); - } } else if (!distance_sort) { -- cgit v1.2.3 From 228f5b2f120cf7e5691dcb174a2d4f34c5340ef4 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 25 Oct 2022 09:48:51 -0400 Subject: Restore LLUUID to a plain old data type in a post-c++11 world --- indra/llcommon/lluuid.cpp | 30 ------------------------------ indra/llcommon/lluuid.h | 8 ++++---- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index acce8366ea..6f9e09a587 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -1009,36 +1009,6 @@ LLUUID::LLUUID() return !(word[0] | word[1] | word[2] | word[3]); } -// Copy constructor - LLUUID::LLUUID(const LLUUID& rhs) -{ - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - tmp[0] = rhstmp[0]; - tmp[1] = rhstmp[1]; - tmp[2] = rhstmp[2]; - tmp[3] = rhstmp[3]; -} - - LLUUID::~LLUUID() -{ -} - -// Assignment - LLUUID& LLUUID::operator=(const LLUUID& rhs) -{ - // No need to check the case where this==&rhs. The branch is slower than the write. - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - tmp[0] = rhstmp[0]; - tmp[1] = rhstmp[1]; - tmp[2] = rhstmp[2]; - tmp[3] = rhstmp[3]; - - return *this; -} - - LLUUID::LLUUID(const char *in_string) { if (!in_string || in_string[0] == 0) diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index 86a396ab06..c139c4eb4e 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -55,10 +55,7 @@ public: LLUUID(); explicit LLUUID(const char *in_string); // Convert from string. explicit LLUUID(const std::string& in_string); // Convert from string. - LLUUID(const LLUUID &in); - LLUUID &operator=(const LLUUID &rhs); - - ~LLUUID(); + ~LLUUID() = default; // // MANIPULATORS @@ -131,6 +128,9 @@ public: U8 mData[UUID_BYTES]; }; +static_assert(std::is_trivially_copyable::value, "LLUUID must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLUUID must be trivial move"); +static_assert(std::is_standard_layout::value, "LLUUID must be a standard layout type"); typedef std::vector uuid_vec_t; typedef std::set uuid_set_t; -- cgit v1.2.3 From 7b3bb0f9c9fd2649365b17fdcd415e366cf57745 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 25 Oct 2022 17:16:57 +0300 Subject: SL-17991 update tooltip over Clear History button --- indra/newview/skins/default/xui/en/panel_preferences_privacy.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 2ec5cef640..ef08fdf7c4 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -19,7 +19,7 @@ follows="left|top" height="23" label="Clear History" - tool_tip="Clear login image, last location, teleport history, web and texture cache" + tool_tip="Clear search and teleport history, web and texture cache" layout="topleft" left="30" name="clear_cache" -- cgit v1.2.3 From 3ac77d73380ced1a9ff940053f448d2794fcc512 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 25 Oct 2022 19:49:37 +0300 Subject: SL-18438 Mac build fix --- indra/llmessage/tests/llcoproceduremanager_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 6424117ef3..a1a4ce0520 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -92,7 +92,7 @@ namespace tut Sync sync; int foo = 0; LLCoprocedureManager::instance().initializePool("PoolName"); - LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", + LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", [&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { sync.bump(); foo = 1; -- cgit v1.2.3 From 8e4e72ceb7a4c02e7196dc9cf69c60de93fb17f7 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Wed, 26 Oct 2022 02:02:02 +0300 Subject: SL-18440 fix for sorting by "Date" column --- indra/newview/llfloateravatarrendersettings.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp index b8f854feb3..8b28f6941e 100644 --- a/indra/newview/llfloateravatarrendersettings.cpp +++ b/indra/newview/llfloateravatarrendersettings.cpp @@ -89,6 +89,7 @@ BOOL LLFloaterAvatarRenderSettings::postBuild() LLFloater::postBuild(); mAvatarSettingsList = getChild("render_settings_list"); mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3)); + mAvatarSettingsList->setAlternateSort(); getChild("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2)); return TRUE; @@ -138,8 +139,8 @@ void LLFloaterAvatarRenderSettings::updateList() 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"); + S32 mute_date = LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first); + item_params.columns.add().value(createTimestamp(mute_date)).column("timestamp").alt_value(std::to_string(mute_date)); mAvatarSettingsList->addNameItemRow(item_params); } } -- cgit v1.2.3 From a022452ff56c31cb028d5a17d827c82f1a74e624 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Wed, 26 Oct 2022 14:35:44 -0400 Subject: Increment viewer version to 6.6.7 following promotion of DRTVWR-574 --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 10abd6ae5b..5db1411e12 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.6.6 +6.6.7 -- cgit v1.2.3 From 9e227a2c6d2c585f9b9ddefb25e6a2f65d9e0892 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 27 Oct 2022 01:16:06 +0300 Subject: SL-18157 Allow translation services to work in IM and group messaging --- indra/newview/llimview.cpp | 87 ++++++++++++++++------ indra/newview/llimview.h | 5 +- .../skins/default/xui/en/menu_participant_view.xml | 2 +- 3 files changed, 69 insertions(+), 25 deletions(-) diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 4d6ebf9cbb..9be00d1736 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -41,6 +41,7 @@ #include "llstring.h" #include "lltextutil.h" #include "lltrans.h" +#include "lltranslate.h" #include "lluictrlfactory.h" #include "llfloaterimsessiontab.h" #include "llagent.h" @@ -510,6 +511,31 @@ void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvit } +void translateSuccess(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, + bool log2file, std::string originalMsg, std::string expectLang, std::string translation, const std::string detected_language) +{ + std::string message_txt(utf8_text); + // filter out non-interesting responses + if (!translation.empty() + && ((detected_language.empty()) || (expectLang != detected_language)) + && (LLStringUtil::compareInsensitive(translation, originalMsg) != 0)) + { + message_txt += " (" + LLTranslate::removeNoTranslateTags(translation) + ")"; + } + + LLIMModel::getInstance()->processAddingMessage(session_id, from, from_id, message_txt, log2file); +} + +void translateFailure(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, + bool log2file, int status, const std::string err_msg) +{ + std::string message_txt(utf8_text); + std::string msg = LLTrans::getString("TranslationFailed", LLSD().with("[REASON]", err_msg)); + LLStringUtil::replaceString(msg, "\n", " "); // we want one-line error messages + message_txt += " (" + msg + ")"; + + LLIMModel::getInstance()->processAddingMessage(session_id, from, from_id, message_txt, log2file); +} LLIMModel::LLIMModel() { @@ -1188,39 +1214,56 @@ bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, } } -bool LLIMModel::proccessOnlineOfflineNotification( +void LLIMModel::proccessOnlineOfflineNotification( const LLUUID& session_id, const std::string& utf8_text) { // Add system message to history - return addMessage(session_id, SYSTEM_FROM, LLUUID::null, utf8_text); + addMessage(session_id, SYSTEM_FROM, LLUUID::null, utf8_text); } -bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, +void LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool log2file /* = true */) { - LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file); - if (!session) return false; + if (gSavedSettings.getBOOL("TranslateChat") && (from != SYSTEM_FROM)) + { + const std::string from_lang = ""; // leave empty to trigger autodetect + const std::string to_lang = LLTranslate::getTranslateLanguage(); + + LLTranslate::translateMessage(from_lang, to_lang, utf8_text, + boost::bind(&translateSuccess, session_id, from, from_id, utf8_text, log2file, utf8_text, from_lang, _1, _2), + boost::bind(&translateFailure, session_id, from, from_id, utf8_text, log2file, _1, _2)); + } + else + { + processAddingMessage(session_id, from, from_id, utf8_text, log2file); + } +} - //good place to add some1 to recent list - //other places may be called from message history. - if( !from_id.isNull() && - ( session->isP2PSessionType() || session->isAdHocSessionType() ) ) - LLRecentPeople::instance().add(from_id); +void LLIMModel::processAddingMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, + const std::string& utf8_text, bool log2file /* = true */) +{ + LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file); + if (!session) return; - // notify listeners - LLSD arg; - arg["session_id"] = session_id; - arg["num_unread"] = session->mNumUnread; - arg["participant_unread"] = session->mParticipantUnreadMessageCount; - arg["message"] = utf8_text; - arg["from"] = from; - arg["from_id"] = from_id; - arg["time"] = LLLogChat::timestamp(false); - arg["session_type"] = session->mSessionType; - mNewMsgSignal(arg); + //good place to add some1 to recent list + //other places may be called from message history. + if( !from_id.isNull() && + ( session->isP2PSessionType() || session->isAdHocSessionType() ) ) + LLRecentPeople::instance().add(from_id); - return true; + // notify listeners + LLSD arg; + arg["session_id"] = session_id; + arg["num_unread"] = session->mNumUnread; + arg["participant_unread"] = session->mParticipantUnreadMessageCount; + arg["message"] = utf8_text; + arg["from"] = from; + arg["from_id"] = from_id; + arg["time"] = LLLogChat::timestamp(false); + arg["session_type"] = session->mSessionType; + + mNewMsgSignal(arg); } LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index fdf9806e2e..5b9dedeac3 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -208,7 +208,8 @@ public: * and also saved into a file if log2file is specified. * It sends new message signal for each added message. */ - bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true); + void addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true); + void processAddingMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true); /** * Similar to addMessage(...) above but won't send a signal about a new message added @@ -219,7 +220,7 @@ public: /** * Add a system message to an IM Model */ - bool proccessOnlineOfflineNotification(const LLUUID& session_id, const std::string& utf8_text); + void proccessOnlineOfflineNotification(const LLUUID& session_id, const std::string& utf8_text); /** * Get a session's name. diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml index 7ea87ee05c..b9750284cd 100644 --- a/indra/newview/skins/default/xui/en/menu_participant_view.xml +++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml @@ -90,7 +90,7 @@ parameter="conversation_log" /> - + -- cgit v1.2.3 From b2c5973fbd504039e1ef9d8fe6d853857e00fcad Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 27 Oct 2022 02:35:52 +0300 Subject: DRTVWR-570 Mac build fix --- indra/newview/llaccountingcostmanager.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index e09527a34b..d3f988d715 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -96,11 +96,7 @@ void LLAccountingCostManager::accountingCostCoro(std::string url, LLSD dataToPost = LLSD::emptyMap(); dataToPost[keystr.c_str()] = objectList; - LLAccountingCostObserver* observer = observerHandle.get(); - LLUUID transactionId = observer->getTransactionID(); - observer = NULL; - - + LLAccountingCostObserver* observer = NULL; LLSD results = httpAdapter->postAndSuspend(httpRequest, url, dataToPost); -- cgit v1.2.3 From 449fa46b157c9cd30fd17f63a12a295da18c7b4f Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Thu, 27 Oct 2022 14:21:07 +0300 Subject: SL-18172 add the link to open object weights floater --- indra/newview/skins/default/xui/de/floater_tools.xml | 2 +- indra/newview/skins/default/xui/es/floater_tools.xml | 2 +- indra/newview/skins/default/xui/fr/floater_tools.xml | 2 +- indra/newview/skins/default/xui/it/floater_tools.xml | 2 +- indra/newview/skins/default/xui/ja/floater_tools.xml | 2 +- indra/newview/skins/default/xui/pl/floater_tools.xml | 2 +- indra/newview/skins/default/xui/pt/floater_tools.xml | 2 +- indra/newview/skins/default/xui/ru/floater_tools.xml | 2 +- indra/newview/skins/default/xui/tr/floater_tools.xml | 2 +- indra/newview/skins/default/xui/zh/floater_tools.xml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml index a4dfde66bc..f6208e11a5 100644 --- a/indra/newview/skins/default/xui/de/floater_tools.xml +++ b/indra/newview/skins/default/xui/de/floater_tools.xml @@ -40,7 +40,7 @@ Klicken und ziehen, um Land auszuwählen - [OBJ_COUNT] Objekte ausgewählt, Auswirkung auf Land [LAND_IMPACT] + [OBJ_COUNT] Objekte ausgewählt, Auswirkung auf Land [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] Verbleibende Kapazität [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml index 6fce98472d..ffa85a2f04 100644 --- a/indra/newview/skins/default/xui/es/floater_tools.xml +++ b/indra/newview/skins/default/xui/es/floater_tools.xml @@ -25,7 +25,7 @@ Pulsa y arrastra para seleccionar el terreno. - [OBJ_COUNT] objetos seleccionados, impacto en el terreno [LAND_IMPACT] + [OBJ_COUNT] objetos seleccionados, impacto en el terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] Capacidad restante [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml index 9597d38dca..c161f3f530 100644 --- a/indra/newview/skins/default/xui/fr/floater_tools.xml +++ b/indra/newview/skins/default/xui/fr/floater_tools.xml @@ -40,7 +40,7 @@ Cliquez et faites glisser pour sélectionner le terrain. - [OBJ_COUNT] objets sélectionnés, impact sur le terrain [LAND_IMPACT] + [OBJ_COUNT] objets sélectionnés, impact sur le terrain [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] Capacité restante [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml index a21ae9a485..f98a2da277 100644 --- a/indra/newview/skins/default/xui/it/floater_tools.xml +++ b/indra/newview/skins/default/xui/it/floater_tools.xml @@ -40,7 +40,7 @@ Clicca e trascina per selezionare il terreno - [OBJ_COUNT] oggetti selezionati, impatto terreno [LAND_IMPACT] + [OBJ_COUNT] oggetti selezionati, impatto terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] Capacità restante [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml index aec0dbdb55..13f766698e 100644 --- a/indra/newview/skins/default/xui/ja/floater_tools.xml +++ b/indra/newview/skins/default/xui/ja/floater_tools.xml @@ -40,7 +40,7 @@ 土地をクリックし、ドラッグして選択 - 選択されているオブジェクトは [OBJ_COUNT] 個、土地の負荷は [LAND_IMPACT] + 選択されているオブジェクトは [OBJ_COUNT] 個、土地の負荷は [LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳細] 残りの許容数 [LAND_CAPACITY]。 diff --git a/indra/newview/skins/default/xui/pl/floater_tools.xml b/indra/newview/skins/default/xui/pl/floater_tools.xml index 5e2ed4a351..8932a86fd1 100644 --- a/indra/newview/skins/default/xui/pl/floater_tools.xml +++ b/indra/newview/skins/default/xui/pl/floater_tools.xml @@ -40,7 +40,7 @@ Kliknij i przeciągnij, aby zaznaczyć teren - [OBJ_COUNT] zaznaczonych obiektów, wpływ na strefę: [LAND_IMPACT] + [OBJ_COUNT] zaznaczonych obiektów, wpływ na strefę: [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] Pojemność pozostała: [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml index 0882f485a6..c0eab171c8 100644 --- a/indra/newview/skins/default/xui/pt/floater_tools.xml +++ b/indra/newview/skins/default/xui/pt/floater_tools.xml @@ -40,7 +40,7 @@ Clicar e arrastar para selecionar a terra - [OBJ_COUNT] objetos selecionados, impacto no terreno [LAND_IMPACT] + [OBJ_COUNT] objetos selecionados, impacto no terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] Capacidade restante [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/ru/floater_tools.xml b/indra/newview/skins/default/xui/ru/floater_tools.xml index 82ee3c49ae..44f54aabb6 100644 --- a/indra/newview/skins/default/xui/ru/floater_tools.xml +++ b/indra/newview/skins/default/xui/ru/floater_tools.xml @@ -40,7 +40,7 @@ Щелкните и перетащите для выделения земли - Выбрано объектов: [OBJ_COUNT], влияние на землю [LAND_IMPACT] + Выбрано объектов: [OBJ_COUNT], влияние на землю [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?] Остаток емкости [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/tr/floater_tools.xml b/indra/newview/skins/default/xui/tr/floater_tools.xml index d6b9a4a533..d48a617e38 100644 --- a/indra/newview/skins/default/xui/tr/floater_tools.xml +++ b/indra/newview/skins/default/xui/tr/floater_tools.xml @@ -40,7 +40,7 @@ Araziyi seçmek için tıklayın ve sürükleyin - [OBJ_COUNT] nesne seçili, [LAND_IMPACT] arazi etkisi + [OBJ_COUNT] nesne seçili, [LAND_IMPACT] arazi etkisi [secondlife:///app/openfloater/object_weights Ek bilgi] Kalan kapasite [LAND_CAPACITY]. diff --git a/indra/newview/skins/default/xui/zh/floater_tools.xml b/indra/newview/skins/default/xui/zh/floater_tools.xml index 539c7454f1..f83b058ce1 100644 --- a/indra/newview/skins/default/xui/zh/floater_tools.xml +++ b/indra/newview/skins/default/xui/zh/floater_tools.xml @@ -40,7 +40,7 @@ 按住並拖曳,可以選取土地 - 選取了 [OBJ_COUNT] 個物件,土地衝擊量 [LAND_IMPACT] + 選取了 [OBJ_COUNT] 個物件,土地衝擊量 [LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳情] 剩餘容納量 [LAND_CAPACITY]。 -- cgit v1.2.3 From 91f9f2e9f789d0418107ed5d428e8f0be3a060e2 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 27 Oct 2022 23:08:09 +0300 Subject: DRTVWR-570 Mac build fix: unused variables cleanup --- indra/newview/llappearancemgr.cpp | 2 +- indra/newview/llenvironment.cpp | 1 - indra/newview/llfloatercreatelandmark.cpp | 1 - indra/newview/llfloateroutfitphotopreview.cpp | 1 - indra/newview/llfloaterscriptlimits.cpp | 1 - indra/newview/llimview.cpp | 6 ++---- indra/newview/llinventoryfilter.cpp | 1 - indra/newview/llinventoryfunctions.cpp | 3 --- indra/newview/llinventorymodel.cpp | 1 - indra/newview/lloutfitgallery.cpp | 2 +- indra/newview/lloutfitslist.cpp | 3 +-- indra/newview/llpanellandmedia.cpp | 1 - indra/newview/llpanelplaces.cpp | 1 - indra/newview/llpanelprofile.cpp | 1 - indra/newview/llspeakers.cpp | 1 - indra/newview/llviewermenu.cpp | 1 - indra/newview/llviewertexteditor.cpp | 1 - indra/newview/llviewerwindow.cpp | 1 - indra/newview/llvovolume.cpp | 6 +----- 19 files changed, 6 insertions(+), 29 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 909f32cd21..3c93a9df7e 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3987,7 +3987,7 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo // existence of AIS as an indicator the fix is present. Does // not actually use AIS to create the category. inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel); - LLUUID folder_id = gInventory.createNewCategory( + gInventory.createNewCategory( parent_id, LLFolderType::FT_OUTFIT, new_folder_name, diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 1300cf3658..9a23702c38 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -684,7 +684,6 @@ namespace if (!injection->mBlendIn) mix = 1.0 - mix; stringset_t dummy; - LLUUID cloud_noise_id = getCloudNoiseTextureId(); F64 value = this->mSettings[injection->mKeyName].asReal(); if (this->getCloudNoiseTextureId().isNull()) { diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index 7def855d83..b82d8a29ba 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -316,7 +316,6 @@ void LLFloaterCreateLandmark::onSaveClicked() LLStringUtil::trim(current_title_value); LLStringUtil::trim(current_notes_value); - LLUUID item_id = mItem->getUUID(); LLUUID folder_id = mFolderCombo->getValue().asUUID(); bool change_parent = folder_id != mItem->getParentUUID(); diff --git a/indra/newview/llfloateroutfitphotopreview.cpp b/indra/newview/llfloateroutfitphotopreview.cpp index 6c39db730c..ade258aef7 100644 --- a/indra/newview/llfloateroutfitphotopreview.cpp +++ b/indra/newview/llfloateroutfitphotopreview.cpp @@ -234,7 +234,6 @@ void LLFloaterOutfitPhotoPreview::updateImageID() if(item) { mImageID = item->getAssetUUID(); - LLPermissions perm(item->getPermissions()); } else { diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 3746b9b6c2..40fe11b309 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -421,7 +421,6 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) for(S32 i = 0; i < number_parcels; i++) { std::string parcel_name = content["parcels"][i]["name"].asString(); - LLUUID parcel_id = content["parcels"][i]["id"].asUUID(); S32 number_objects = content["parcels"][i]["objects"].size(); S32 local_id = 0; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 4d6ebf9cbb..afd68a6a38 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -2114,8 +2114,6 @@ void LLOutgoingCallDialog::show(const LLSD& key) std::string callee_name = mPayload["session_name"].asString(); - LLUUID session_id = mPayload["session_id"].asUUID(); - if (callee_name == "anonymous") // obsolete? Likely was part of avaline support { callee_name = getString("anonymous"); @@ -2499,7 +2497,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload } } - LLUUID new_session_id = gIMMgr->addSession(correct_session_name, type, session_id, true); + gIMMgr->addSession(correct_session_name, type, session_id, true); std::string url = gAgent.getRegion()->getCapability( "ChatSessionRequest"); @@ -2585,7 +2583,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) } else { - LLUUID new_session_id = gIMMgr->addSession( + gIMMgr->addSession( payload["session_name"].asString(), type, session_id, true); diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 707ff2b7b6..e3a6b2dc85 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -437,7 +437,6 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) const { LLInventoryType::EType object_type = item->getInventoryType(); - const LLUUID object_id = item->getUUID(); const U32 filterTypes = mFilterOps.mFilterTypes; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 27edc8148e..2c8d372eff 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1403,9 +1403,6 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol LLNotificationsUtil::add("MerchantPasteFailed", subs); return false; } - - // Get the parent folder of the moved item : we may have to update it - LLUUID src_folder = viewer_inv_item->getParentUUID(); if (copy) { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 06351dc540..87fd91b23a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2711,7 +2711,6 @@ void LLInventoryModel::buildParentChildMap() // some accounts has pbroken inventory root folders std::string name = "My Inventory"; - LLUUID prev_root_id = mRootFolderID; for (parent_cat_map_t::const_iterator it = mParentChildCategoryTree.begin(), it_end = mParentChildCategoryTree.end(); it != it_end; ++it) { diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index f419e2e06d..5d139ff75f 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1226,7 +1226,7 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector& filename checkRemovePhoto(outfit_id); std::string upload_pending_name = outfit_id.asString(); std::string upload_pending_desc = ""; - LLUUID photo_id = upload_new_resource(filename, // file + upload_new_resource(filename, // file upload_pending_name, upload_pending_desc, 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 7270580032..4171fd8822 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -823,8 +823,7 @@ void LLOutfitListBase::onOpen(const LLSD& info) mCategoriesObserver->addCategory(outfits, boost::bind(&LLOutfitListBase::refreshList, this, outfits)); - const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - + //const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); // Start observing changes in Current Outfit category. //mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this)); diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp index 26cd3ff1c1..e379d67e37 100644 --- a/indra/newview/llpanellandmedia.cpp +++ b/indra/newview/llpanellandmedia.cpp @@ -179,7 +179,6 @@ void LLPanelLandMedia::refresh() // enable/disable for text label for completeness mMediaSizeCtrlLabel->setEnabled( can_change_media && allow_resize ); - LLUUID tmp = parcel->getMediaID(); mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); mMediaTextureCtrl->setEnabled( can_change_media ); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 74ec576554..0f00231643 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -800,7 +800,6 @@ void LLPanelPlaces::onSaveButtonClicked() LLStringUtil::trim(current_title_value); LLStringUtil::trim(current_notes_value); - LLUUID item_id = mItem->getUUID(); LLUUID folder_id = mLandmarkInfo->getLandmarkFolder(); bool change_parent = folder_id != mItem->getParentUUID(); diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index deebf0cd1b..708ff26ced 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1055,7 +1055,6 @@ void LLPanelProfileSecondLife::resetData() void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) { - LLUUID avatar_id = getAvatarId(); const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile()) { diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index ea671a130e..60bada8f58 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -982,7 +982,6 @@ void LLActiveSpeakerMgr::updateSpeakerList() // clean up text only speakers for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it) { - LLUUID speaker_id = speaker_it->first; LLSpeaker* speakerp = speaker_it->second; if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 3bff01625b..01e4734b3c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7651,7 +7651,6 @@ void handle_selected_texture_info(void*) map_t::iterator it; for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it) { - LLUUID image_id = it->first; U8 te = it->second[0]; LLViewerTexture* img = node->getObject()->getTEImage(te); S32 height = img->getHeight(); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index e2de7ac825..7abb42dd8a 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1252,7 +1252,6 @@ bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD& S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if( 0 == option ) { - LLUUID item_id = notification["payload"]["item_id"].asUUID(); llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger()); LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc); if (itemp) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 588fb4eb1b..f4d8eb6035 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1307,7 +1307,6 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi TRUE /* pick_transparent */, FALSE /* pick_rigged */); - LLUUID object_id = pick_info.getObjectID(); S32 object_face = pick_info.mObjectFace; std::string url = data; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d98a40d188..2e7ccc8334 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -856,10 +856,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) if (isSculpted()) { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID id = sculpt_params->getSculptTexture(); - - updateSculptTexture(); + updateSculptTexture(); @@ -1109,7 +1106,6 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo if (!getVolume()->isMeshAssetLoaded()) { //load request not yet issued, request pipeline load this mesh - LLUUID asset_id = volume_params.getSculptID(); S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod); if (available_lod != lod) { -- cgit v1.2.3 From 27f7edeedbbf65086e4a6ba28724f8a80c48bcd0 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 28 Oct 2022 19:55:40 +0300 Subject: SL-16534 The link item is not updating after rezzing the linked object in-world --- indra/newview/llinventoryfunctions.cpp | 6 ++++- indra/newview/llinventorymodel.cpp | 41 +++++++++++++++++----------------- indra/newview/llinventorymodel.h | 2 +- 3 files changed, 27 insertions(+), 22 deletions(-) diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 27edc8148e..dab1e5c38d 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -529,7 +529,11 @@ BOOL get_is_item_worn(const LLUUID& id) const LLViewerInventoryItem* item = gInventory.getItem(id); if (!item) return FALSE; - + + if (item->getIsLinkType() && !gInventory.getItem(item->getLinkedUUID())) + { + return FALSE; + } // Consider the item as worn if it has links in COF. if (LLAppearanceMgr::instance().isLinkedInCOF(id)) { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index fab7ae8f1a..cf0219e76e 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1636,6 +1636,8 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo LL_WARNS(LOG_INV) << "Deleting non-existent object [ id: " << id << " ] " << LL_ENDL; return; } + + LLInventoryModel::item_array_t links = collectLinksTo(id); LL_DEBUGS(LOG_INV) << "Deleting inventory object " << id << LL_ENDL; mLastItem = NULL; @@ -1694,7 +1696,7 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo obj = NULL; // delete obj if (fix_broken_links && !is_link_type) { - updateLinkedObjectsFromPurge(id); + rebuildLinkItems(links); } if (do_notify_observers) { @@ -1702,26 +1704,25 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo } } -void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id) +void LLInventoryModel::rebuildLinkItems(LLInventoryModel::item_array_t& items) { - LLInventoryModel::item_array_t item_array = collectLinksTo(baseobj_id); - - // REBUILD is expensive, so clear the current change list first else - // everything else on the changelist will also get rebuilt. - if (item_array.size() > 0) - { - notifyObservers(); - for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin(); - iter != item_array.end(); - iter++) - { - const LLViewerInventoryItem *linked_item = (*iter); - const LLUUID &item_id = linked_item->getUUID(); - if (item_id == baseobj_id) continue; - addChangedMask(LLInventoryObserver::REBUILD, item_id); - } - notifyObservers(); - } + // REBUILD is expensive, so clear the current change list first else + // everything else on the changelist will also get rebuilt. + if (items.size() > 0) + { + notifyObservers(); + for (LLInventoryModel::item_array_t::const_iterator iter = items.begin(); + iter != items.end(); + iter++) + { + const LLViewerInventoryItem *linked_item = (*iter); + if (linked_item) + { + addChangedMask(LLInventoryObserver::REBUILD, linked_item->getUUID()); + } + } + notifyObservers(); + } } // Add/remove an observer. If the observer is destroyed, be sure to diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h index c4133ff9bb..685c2c0fe5 100644 --- a/indra/newview/llinventorymodel.h +++ b/indra/newview/llinventorymodel.h @@ -445,7 +445,7 @@ public: void checkTrashOverflow(); protected: - void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id); + void rebuildLinkItems(LLInventoryModel::item_array_t& items); //-------------------------------------------------------------------- // Reorder -- cgit v1.2.3 From fabfbb93e666326a9daad7c14e690a23e4567d23 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 15:45:25 -0400 Subject: Harden LLDataPackerBinaryBuffer from performing invalid memcpy in case buffer is too small --- indra/llmessage/lldatapacker.cpp | 258 +++++++++++++++++++++++---------------- 1 file changed, 156 insertions(+), 102 deletions(-) diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp index b6adc102d2..9f7768f78e 100644 --- a/indra/llmessage/lldatapacker.cpp +++ b/indra/llmessage/lldatapacker.cpp @@ -116,9 +116,8 @@ BOOL LLDataPacker::packFixed(const F32 value, const char *name, BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, const BOOL is_signed, const U32 int_bits, const U32 frac_bits) { - //BOOL success = TRUE; + BOOL success = TRUE; //LL_INFOS() << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << LL_ENDL; - BOOL ok = FALSE; S32 unsigned_bits = int_bits + frac_bits; S32 total_bits = unsigned_bits; @@ -134,19 +133,19 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, if (total_bits <= 8) { U8 fixed_8; - ok = unpackU8(fixed_8, name); + success = unpackU8(fixed_8, name); fixed_val = (F32)fixed_8; } else if (total_bits <= 16) { U16 fixed_16; - ok = unpackU16(fixed_16, name); + success = unpackU16(fixed_16, name); fixed_val = (F32)fixed_16; } else if (total_bits <= 31) { U32 fixed_32; - ok = unpackU32(fixed_32, name); + success = unpackU32(fixed_32, name); fixed_val = (F32)fixed_32; } else @@ -164,7 +163,7 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, } value = fixed_val; //LL_INFOS() << "Value: " << value << LL_ENDL; - return ok; + return success; } BOOL LLDataPacker::unpackU16s(U16 *values, S32 count, const char *name) @@ -238,37 +237,43 @@ BOOL LLDataPacker::unpackUUIDs(LLUUID *values, S32 count, const char *name) BOOL LLDataPackerBinaryBuffer::packString(const std::string& value, const char *name) { - BOOL success = TRUE; S32 length = value.length()+1; - success &= verifyLength(length, name); + if (!verifyLength(length, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length); } mCurBufferp += length; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackString(std::string& value, const char *name) { - BOOL success = TRUE; S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/ - success &= verifyLength(length, name); + if (!verifyLength(length, name)) + { + return FALSE; + } value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen() mCurBufferp += length; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(size + 4, name); + if (!verifyLength(size + 4, name)) + { + return FALSE; + } if (mWriteEnabled) { @@ -280,102 +285,117 @@ BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const c htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); } mCurBufferp += size; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(4, name); - htolememcpy(&size, mCurBufferp, MVT_S32, 4); - mCurBufferp += 4; - success &= verifyLength(size, name); - if (success) + if (!verifyLength(4, name)) { - htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); - mCurBufferp += size; + LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; + return FALSE; } - else + + htolememcpy(&size, mCurBufferp, MVT_S32, 4); + mCurBufferp += 4; + + if (!verifyLength(size, name)) { LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; - success = FALSE; + return FALSE; } - return success; + + htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); + mCurBufferp += size; + + return TRUE; } BOOL LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(size, name); + if (!verifyLength(size, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); } mCurBufferp += size; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(size, name); + if (!verifyLength(size, name)) + { + return FALSE; + } htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); mCurBufferp += size; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U8), name); + if (!verifyLength(sizeof(U8), name)) + { + return FALSE; + } if (mWriteEnabled) { *mCurBufferp = value; } mCurBufferp++; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U8), name); + if (!verifyLength(sizeof(U8), name)) + { + return FALSE; + } value = *mCurBufferp; mCurBufferp++; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U16), name); + if (!verifyLength(sizeof(U16), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_U16, 2); } mCurBufferp += 2; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U16), name); + if (!verifyLength(sizeof(U16), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_U16, 2); mCurBufferp += 2; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packS16(const S16 value, const char *name) @@ -404,134 +424,156 @@ BOOL LLDataPackerBinaryBuffer::unpackS16(S16 &value, const char *name) BOOL LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U32), name); + if (!verifyLength(sizeof(U32), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_U32, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U32), name); + if (!verifyLength(sizeof(U32), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_U32, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(S32), name); + if (!verifyLength(sizeof(S32), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_S32, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(S32), name); + if(!verifyLength(sizeof(S32), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_S32, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(F32), name); + if (!verifyLength(sizeof(F32), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_F32, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(F32), name); + if (!verifyLength(sizeof(F32), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_F32, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); } mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(4, name); + if (!verifyLength(4, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(4, name); + if (!verifyLength(4, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(8, name); + if (!verifyLength(8, name)) + { + return FALSE; + } if (mWriteEnabled) { @@ -539,92 +581,106 @@ BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *n htolememcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4); } mCurBufferp += 8; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(8, name); + if (!verifyLength(8, name)) + { + return FALSE; + } htolememcpy(&value.mV[0], mCurBufferp, MVT_F32, 4); htolememcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4); mCurBufferp += 8; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(12, name); + if (!verifyLength(12, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_LLVector3, 12); } mCurBufferp += 12; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(12, name); + if (!verifyLength(12, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_LLVector3, 12); mCurBufferp += 12; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); } mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mData, MVT_LLUUID, 16); } mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } htolememcpy(value.mData, mCurBufferp, MVT_LLUUID, 16); mCurBufferp += 16; - return success; + return TRUE; } const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a) @@ -698,15 +754,13 @@ BOOL LLDataPackerAsciiBuffer::packString(const std::string& value, const char *n BOOL LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name) { - BOOL success = TRUE; char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ - BOOL res = getValueStr(name, valuestr, DP_BUFSIZE); // NULL terminated - if (!res) // + if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated { return FALSE; } value = valuestr; - return success; + return TRUE; } -- cgit v1.2.3 From 129301c8e9d48e29466597f6baee6d3566fac9dc Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 15:46:42 -0400 Subject: Fix multiple leaks in the case of failure to deserialize animations --- indra/llcharacter/llkeyframemotion.cpp | 185 +++++++++++++++++---------------- 1 file changed, 97 insertions(+), 88 deletions(-) diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index ebf7454a61..403d5bcf49 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1229,7 +1229,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) { BOOL old_version = FALSE; - mJointMotionList = new LLKeyframeMotion::JointMotionList; + std::unique_ptr joint_motion_list(new LLKeyframeMotion::JointMotionList); //------------------------------------------------------------------------- // get base priority @@ -1272,16 +1272,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo << " for animation " << asset_id << LL_ENDL; return FALSE; } - mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority; + joint_motion_list->mBasePriority = (LLJoint::JointPriority) temp_priority; - if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) + if (joint_motion_list->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) { - mJointMotionList->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); - mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority; + joint_motion_list->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); + joint_motion_list->mMaxPriority = joint_motion_list->mBasePriority; } - else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY) + else if (joint_motion_list->mBasePriority < LLJoint::USE_MOTION_PRIORITY) { - LL_WARNS() << "bad animation base_priority " << mJointMotionList->mBasePriority + LL_WARNS() << "bad animation base_priority " << joint_motion_list->mBasePriority << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1289,15 +1289,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get duration //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mDuration, "duration")) + if (!dp.unpackF32(joint_motion_list->mDuration, "duration")) { LL_WARNS() << "can't read duration" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (mJointMotionList->mDuration > MAX_ANIM_DURATION || - !llfinite(mJointMotionList->mDuration)) + if (joint_motion_list->mDuration > MAX_ANIM_DURATION || + !llfinite(joint_motion_list->mDuration)) { LL_WARNS() << "invalid animation duration" << " for animation " << asset_id << LL_ENDL; @@ -1307,14 +1307,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get emote (optional) //------------------------------------------------------------------------- - if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name")) + if (!dp.unpackString(joint_motion_list->mEmoteName, "emote_name")) { LL_WARNS() << "can't read optional_emote_animation" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if(mJointMotionList->mEmoteName==mID.asString()) + if(joint_motion_list->mEmoteName==mID.asString()) { LL_WARNS() << "Malformed animation mEmoteName==mID" << " for animation " << asset_id << LL_ENDL; @@ -1324,23 +1324,23 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get loop //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") || - !llfinite(mJointMotionList->mLoopInPoint)) + if (!dp.unpackF32(joint_motion_list->mLoopInPoint, "loop_in_point") || + !llfinite(joint_motion_list->mLoopInPoint)) { LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") || - !llfinite(mJointMotionList->mLoopOutPoint)) + if (!dp.unpackF32(joint_motion_list->mLoopOutPoint, "loop_out_point") || + !llfinite(joint_motion_list->mLoopOutPoint)) { LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackS32(mJointMotionList->mLoop, "loop")) + if (!dp.unpackS32(joint_motion_list->mLoop, "loop")) { LL_WARNS() << "can't read loop" << " for animation " << asset_id << LL_ENDL; @@ -1353,22 +1353,22 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (female_land_anim == asset_id || formal_female_land_anim == asset_id) { LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; - mJointMotionList->mLoop = FALSE; + joint_motion_list->mLoop = FALSE; } //------------------------------------------------------------------------- // get easeIn and easeOut //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") || - !llfinite(mJointMotionList->mEaseInDuration)) + if (!dp.unpackF32(joint_motion_list->mEaseInDuration, "ease_in_duration") || + !llfinite(joint_motion_list->mEaseInDuration)) { LL_WARNS() << "can't read easeIn" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") || - !llfinite(mJointMotionList->mEaseOutDuration)) + if (!dp.unpackF32(joint_motion_list->mEaseOutDuration, "ease_out_duration") || + !llfinite(joint_motion_list->mEaseOutDuration)) { LL_WARNS() << "can't read easeOut" << " for animation " << asset_id << LL_ENDL; @@ -1393,7 +1393,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word; + joint_motion_list->mHandPose = (LLHandMotion::eHandPose)word; //------------------------------------------------------------------------- // get number of joint motions @@ -1419,8 +1419,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - mJointMotionList->mJointMotionArray.clear(); - mJointMotionList->mJointMotionArray.reserve(num_motions); + joint_motion_list->mJointMotionArray.clear(); + joint_motion_list->mJointMotionArray.reserve(num_motions); mJointStates.clear(); mJointStates.reserve(num_motions); @@ -1431,7 +1431,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo for(U32 i=0; imJointMotionArray.push_back(joint_motion); + joint_motion_list->mJointMotionArray.push_back(joint_motion); std::string joint_name; if (!dp.unpackString(joint_name, "joint_name")) @@ -1503,9 +1503,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo joint_motion->mPriority = (LLJoint::JointPriority)joint_priority; if (joint_priority != LLJoint::USE_MOTION_PRIORITY && - joint_priority > mJointMotionList->mMaxPriority) + joint_priority > joint_motion_list->mMaxPriority) { - mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority; + joint_motion_list->mMaxPriority = (LLJoint::JointPriority)joint_priority; } joint_state->setPriority((LLJoint::JointPriority)joint_priority); @@ -1556,9 +1556,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + time = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); - if (time < 0 || time > mJointMotionList->mDuration) + if (time < 0 || time > joint_motion_list->mDuration) { LL_WARNS() << "invalid frame time" << " for animation " << asset_id << LL_ENDL; @@ -1571,38 +1571,57 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo LLVector3 rot_angles; U16 x, y, z; - BOOL success = TRUE; - if (old_version) { - success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite(); + if (!dp.unpackVector3(rot_angles, "rot_angles")) + { + LL_WARNS() << "can't read rot_angles in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!rot_angles.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } LLQuaternion::Order ro = StringToOrder("ZYX"); rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); } else { - success &= dp.unpackU16(x, "rot_angle_x"); - success &= dp.unpackU16(y, "rot_angle_y"); - success &= dp.unpackU16(z, "rot_angle_z"); + if (!dp.unpackU16(x, "rot_angle_x")) + { + LL_WARNS() << "can't read rot_angle_x in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "rot_angle_y")) + { + LL_WARNS() << "can't read rot_angle_y in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "rot_angle_z")) + { + LL_WARNS() << "can't read rot_angle_z in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } LLVector3 rot_vec; rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f); rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f); rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f); + + if(!rot_vec.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" + << " for animation " << asset_id << LL_ENDL; + return FALSE; + } rot_key.mRotation.unpackFromVector3(rot_vec); } - if( !(rot_key.mRotation.isFinite()) ) - { - LL_WARNS() << "non-finite angle in rotation key" - << " for animation " << asset_id << LL_ENDL; - success = FALSE; - } - - if (!success) + if(!rot_key.mRotation.isFinite()) { - LL_WARNS() << "can't read rotation key (" << k << ")" + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1655,14 +1674,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - pos_key.mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + pos_key.mTime = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); } - BOOL success = TRUE; - if (old_version) { - success = dp.unpackVector3(pos_key.mPosition, "pos"); + if (!dp.unpackVector3(pos_key.mPosition, "pos")) + { + LL_WARNS() << "can't read pos in position key (" << k << ")" << LL_ENDL; + return FALSE; + } //MAINT-6162 pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); @@ -1674,25 +1695,30 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { U16 x, y, z; - success &= dp.unpackU16(x, "pos_x"); - success &= dp.unpackU16(y, "pos_y"); - success &= dp.unpackU16(z, "pos_z"); + if (!dp.unpackU16(x, "pos_x")) + { + LL_WARNS() << "can't read pos_x in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "pos_y")) + { + LL_WARNS() << "can't read pos_y in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "pos_z")) + { + LL_WARNS() << "can't read pos_z in position key (" << k << ")" << LL_ENDL; + return FALSE; + } pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); } - if( !(pos_key.mPosition.isFinite()) ) + if(!pos_key.mPosition.isFinite()) { LL_WARNS() << "non-finite position in key" - << " for animation " << asset_id << LL_ENDL; - success = FALSE; - } - - if (!success) - { - LL_WARNS() << "can't read position key (" << k << ")" << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1701,7 +1727,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (is_pelvis) { - mJointMotionList->mPelvisBBox.addPoint(pos_key.mPosition); + joint_motion_list->mPelvisBBox.addPoint(pos_key.mPosition); } } @@ -1733,23 +1759,21 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo for(S32 i = 0; i < num_constraints; ++i) { // read in constraint data - JointConstraintSharedData* constraintp = new JointConstraintSharedData; + std::unique_ptr constraintp(new JointConstraintSharedData); U8 byte = 0; if (!dp.unpackU8(byte, "chain_length")) { LL_WARNS() << "can't read constraint chain length" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } constraintp->mChainLength = (S32) byte; - if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions()) + if((U32)constraintp->mChainLength > joint_motion_list->getNumJointMotions()) { LL_WARNS() << "invalid constraint chain length" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1757,7 +1781,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint type" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1765,7 +1788,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "invalid constraint type" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } constraintp->mConstraintType = (EConstraintType)byte; @@ -1776,7 +1798,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read source volume name" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1787,7 +1808,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "not a valid source constraint volume " << str << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1795,7 +1815,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint source offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1803,7 +1822,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint source offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1811,7 +1829,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read target volume name" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1830,7 +1847,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "not a valid target constraint volume " << str << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } } @@ -1839,7 +1855,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint target offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1847,7 +1862,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint target offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1855,7 +1869,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint target direction" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1863,7 +1876,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint target direction" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1877,7 +1889,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease in start time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1885,7 +1896,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease in stop time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1893,7 +1903,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease out start time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1901,33 +1910,31 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease out stop time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } - mJointMotionList->mConstraints.push_front(constraintp); - - constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte - LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume); // get joint to which this collision volume is attached if (!joint) { return FALSE; } + + constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte + for (S32 i = 0; i < constraintp->mChainLength + 1; i++) { LLJoint* parent = joint->getParent(); if (!parent) { LL_WARNS() << "Joint with no parent: " << joint->getName() - << " Emote: " << mJointMotionList->mEmoteName + << " Emote: " << joint_motion_list->mEmoteName << " for animation " << asset_id << LL_ENDL; return FALSE; } joint = parent; constraintp->mJointStateIndices[i] = -1; - for (U32 j = 0; j < mJointMotionList->getNumJointMotions(); j++) + for (U32 j = 0; j < joint_motion_list->getNumJointMotions(); j++) { LLJoint* constraint_joint = getJoint(j); @@ -1948,14 +1955,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "No joint index for constraint " << i << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } } + + joint_motion_list->mConstraints.push_front(constraintp.release()); } } // *FIX: support cleanup of old keyframe data + mJointMotionList = joint_motion_list.release(); // release from unique_ptr to member; LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList); mAssetStatus = ASSET_LOADED; -- cgit v1.2.3 From 3dd874a99b81b6c392f1ab4c40015ba43f7801e6 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:47:32 -0400 Subject: Fix memory leaks in lldir objc/mac --- indra/llfilesystem/lldir_mac.cpp | 32 ++++++------- indra/llfilesystem/lldir_utils_objc.h | 10 ++--- indra/llfilesystem/lldir_utils_objc.mm | 82 +++++++++++++++++----------------- 3 files changed, 60 insertions(+), 64 deletions(-) diff --git a/indra/llfilesystem/lldir_mac.cpp b/indra/llfilesystem/lldir_mac.cpp index 3bc4ee844e..9ad8e274b6 100644 --- a/indra/llfilesystem/lldir_mac.cpp +++ b/indra/llfilesystem/lldir_mac.cpp @@ -66,16 +66,16 @@ LLDir_Mac::LLDir_Mac() const std::string secondLifeString = "SecondLife"; - std::string *executablepathstr = getSystemExecutableFolder(); + std::string executablepathstr = getSystemExecutableFolder(); //NOTE: LLINFOS/LLERRS will not output to log here. The streams are not initialized. - if (executablepathstr) + if (!executablepathstr.empty()) { // mExecutablePathAndName - mExecutablePathAndName = *executablepathstr; + mExecutablePathAndName = executablepathstr; - boost::filesystem::path executablepath(*executablepathstr); + boost::filesystem::path executablepath(executablepathstr); # ifndef BOOST_SYSTEM_NO_DEPRECATED #endif @@ -83,8 +83,8 @@ LLDir_Mac::LLDir_Mac() mExecutableDir = executablepath.parent_path().string(); // mAppRODataDir - std::string *resourcepath = getSystemResourceFolder(); - mAppRODataDir = *resourcepath; + std::string resourcepath = getSystemResourceFolder(); + mAppRODataDir = resourcepath; // *NOTE: When running in a dev tree, use the copy of // skins in indra/newview/ rather than in the application bundle. This @@ -110,11 +110,11 @@ LLDir_Mac::LLDir_Mac() } // mOSUserDir - std::string *appdir = getSystemApplicationSupportFolder(); + std::string appdir = getSystemApplicationSupportFolder(); std::string rootdir; //Create root directory - if (CreateDirectory(*appdir, secondLifeString, &rootdir)) + if (CreateDirectory(appdir, secondLifeString, &rootdir)) { // Save the full path to the folder @@ -128,12 +128,10 @@ LLDir_Mac::LLDir_Mac() } //mOSCacheDir - std::string *cachedir = getSystemCacheFolder(); - - if (cachedir) - + std::string cachedir = getSystemCacheFolder(); + if (!cachedir.empty()) { - mOSCacheDir = *cachedir; + mOSCacheDir = cachedir; //TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away. CreateDirectory(mOSCacheDir, secondLifeString, NULL); } @@ -143,12 +141,10 @@ LLDir_Mac::LLDir_Mac() // mTempDir //Aura 120920 boost::filesystem::temp_directory_path() not yet implemented on mac. :( - std::string *tmpdir = getSystemTempFolder(); - if (tmpdir) + std::string tmpdir = getSystemTempFolder(); + if (!tmpdir.empty()) { - - CreateDirectory(*tmpdir, secondLifeString, &mTempDir); - if (tmpdir) delete tmpdir; + CreateDirectory(tmpdir, secondLifeString, &mTempDir); } mWorkingDir = getCurPath(); diff --git a/indra/llfilesystem/lldir_utils_objc.h b/indra/llfilesystem/lldir_utils_objc.h index 12019c4284..59dbeb4aec 100644 --- a/indra/llfilesystem/lldir_utils_objc.h +++ b/indra/llfilesystem/lldir_utils_objc.h @@ -33,11 +33,11 @@ #include -std::string* getSystemTempFolder(); -std::string* getSystemCacheFolder(); -std::string* getSystemApplicationSupportFolder(); -std::string* getSystemResourceFolder(); -std::string* getSystemExecutableFolder(); +std::string getSystemTempFolder(); +std::string getSystemCacheFolder(); +std::string getSystemApplicationSupportFolder(); +std::string getSystemResourceFolder(); +std::string getSystemExecutableFolder(); #endif // LL_LLDIR_UTILS_OBJC_H diff --git a/indra/llfilesystem/lldir_utils_objc.mm b/indra/llfilesystem/lldir_utils_objc.mm index da55a2f897..20540fb93c 100644 --- a/indra/llfilesystem/lldir_utils_objc.mm +++ b/indra/llfilesystem/lldir_utils_objc.mm @@ -30,75 +30,75 @@ #include "lldir_utils_objc.h" #import -std::string* getSystemTempFolder() +std::string getSystemTempFolder() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString * tempDir = NSTemporaryDirectory(); - if (tempDir == nil) - tempDir = @"/tmp"; - std::string *result = ( new std::string([tempDir UTF8String]) ); - [pool release]; + std::string result; + @autoreleasepool { + NSString * tempDir = NSTemporaryDirectory(); + if (tempDir == nil) + tempDir = @"/tmp"; + result = std::string([tempDir UTF8String]); + } return result; } //findSystemDirectory scoped exclusively to this file. -std::string* findSystemDirectory(NSSearchPathDirectory searchPathDirectory, +std::string findSystemDirectory(NSSearchPathDirectory searchPathDirectory, NSSearchPathDomainMask domainMask) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - std::string *result = nil; - NSString *path = nil; - - // Search for the path - NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory, - domainMask, - YES); - if ([paths count]) - { - path = [paths objectAtIndex:0]; - //HACK: Always attempt to create directory, ignore errors. - NSError *error = nil; - - [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; - + std::string result; + @autoreleasepool { + NSString *path = nil; - result = new std::string([path UTF8String]); + // Search for the path + NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory, + domainMask, + YES); + if ([paths count]) + { + path = [paths objectAtIndex:0]; + //HACK: Always attempt to create directory, ignore errors. + NSError *error = nil; + + [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; + + + result = std::string([path UTF8String]); + } } - [pool release]; return result; } -std::string* getSystemExecutableFolder() +std::string getSystemExecutableFolder() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *bundlePath = [[NSBundle mainBundle] executablePath]; - std::string *result = (new std::string([bundlePath UTF8String])); - [pool release]; + std::string result; + @autoreleasepool { + NSString *bundlePath = [[NSBundle mainBundle] executablePath]; + result = std::string([bundlePath UTF8String]); + } return result; } -std::string* getSystemResourceFolder() +std::string getSystemResourceFolder() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; - std::string *result = (new std::string([bundlePath UTF8String])); - [pool release]; + std::string result; + @autoreleasepool { + NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; + result = std::string([bundlePath UTF8String]); + } return result; } -std::string* getSystemCacheFolder() +std::string getSystemCacheFolder() { return findSystemDirectory (NSCachesDirectory, NSUserDomainMask); } -std::string* getSystemApplicationSupportFolder() +std::string getSystemApplicationSupportFolder() { return findSystemDirectory (NSApplicationSupportDirectory, NSUserDomainMask); -- cgit v1.2.3 From 662dd44587796072b81b47f202597569f4e8c48d Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:49:32 -0400 Subject: Fix leaks in mac filepicker code --- indra/newview/llfilepicker.cpp | 10 +-- indra/newview/llfilepicker.h | 2 +- indra/newview/llfilepicker_mac.h | 4 +- indra/newview/llfilepicker_mac.mm | 157 +++++++++++++++++++------------------- 4 files changed, 88 insertions(+), 85 deletions(-) diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 3669fb1eeb..e3a695fc79 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -586,9 +586,9 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, #elif LL_DARWIN -std::vector* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) +std::unique_ptr> LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) { - std::vector *allowedv = new std::vector< std::string >; + std::unique_ptr> allowedv(new std::vector< std::string >); switch(filter) { case FFLOAD_ALL: @@ -661,9 +661,9 @@ bool LLFilePicker::doNavChooseDialog(ELoadFilter filter) gViewerWindow->getWindow()->beforeDialog(); - std::vector *allowed_types=navOpenFilterProc(filter); + std::unique_ptr> allowed_types = navOpenFilterProc(filter); - std::vector *filev = doLoadDialog(allowed_types, + std::unique_ptr> filev = doLoadDialog(allowed_types.get(), mPickOptions); gViewerWindow->getWindow()->afterDialog(); @@ -780,7 +780,7 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena gViewerWindow->getWindow()->beforeDialog(); // Run the dialog - std::string* filev = doSaveDialog(&namestring, + std::unique_ptr filev = doSaveDialog(&namestring, &type, &creator, &extension, diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 04ba4416d7..73baeca1c0 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -167,7 +167,7 @@ private: bool doNavChooseDialog(ELoadFilter filter); bool doNavSaveDialog(ESaveFilter filter, const std::string& filename); - std::vector* navOpenFilterProc(ELoadFilter filter); + std::unique_ptr> navOpenFilterProc(ELoadFilter filter); #endif #if LL_GTK diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h index e0b7e2e8ce..b2fb371afe 100644 --- a/indra/newview/llfilepicker_mac.h +++ b/indra/newview/llfilepicker_mac.h @@ -39,9 +39,9 @@ #include //void modelessPicker(); -std::vector* doLoadDialog(const std::vector* allowed_types, +std::unique_ptr> doLoadDialog(const std::vector* allowed_types, unsigned int flags); -std::string* doSaveDialog(const std::string* file, +std::unique_ptr doSaveDialog(const std::string* file, const std::string* type, const std::string* creator, const std::string* extension, diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm index 1438e4dc0a..0ae5fc3f77 100644 --- a/indra/newview/llfilepicker_mac.mm +++ b/indra/newview/llfilepicker_mac.mm @@ -29,104 +29,107 @@ #include #include "llfilepicker_mac.h" -std::vector* doLoadDialog(const std::vector* allowed_types, +std::unique_ptr> doLoadDialog(const std::vector* allowed_types, unsigned int flags) { - int i, result; - - //Aura TODO: We could init a small window and release it at the end of this routine - //for a modeless interface. - - NSOpenPanel *panel = [NSOpenPanel openPanel]; - //NSString *fileName = nil; - NSMutableArray *fileTypes = nil; - - - if ( allowed_types && !allowed_types->empty()) - { - fileTypes = [[NSMutableArray alloc] init]; + std::unique_ptr> outfiles; + + @autoreleasepool { + int i, result; + //Aura TODO: We could init a small window and release it at the end of this routine + //for a modeless interface. + + NSOpenPanel *panel = [NSOpenPanel openPanel]; + //NSString *fileName = nil; + NSMutableArray *fileTypes = nil; - for (i=0;isize();++i) + if ( allowed_types && !allowed_types->empty()) { - [fileTypes addObject: - [NSString stringWithCString:(*allowed_types)[i].c_str() - encoding:[NSString defaultCStringEncoding]]]; + fileTypes = [[[NSMutableArray alloc] init] autorelease]; + + for (i=0;isize();++i) + { + [fileTypes addObject: + [NSString stringWithCString:(*allowed_types)[i].c_str() + encoding:[NSString defaultCStringEncoding]]]; + } } - } - //[panel setMessage:@"Import one or more files or directories."]; - [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ]; - [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ]; - [panel setCanCreateDirectories: true]; - [panel setResolvesAliases: true]; - [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )]; - [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; - - std::vector* outfiles = NULL; - - if (fileTypes) - { - [panel setAllowedFileTypes:fileTypes]; - result = [panel runModal]; - } - else - { - // I suggest it's better to open the last path and let this default to home dir as necessary - // for consistency with other OS X apps - // - //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ]; - result = [panel runModal]; - } - - if (result == NSOKButton) - { - NSArray *filesToOpen = [panel URLs]; - int i, count = [filesToOpen count]; + //[panel setMessage:@"Import one or more files or directories."]; + [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ]; + [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ]; + [panel setCanCreateDirectories: true]; + [panel setResolvesAliases: true]; + [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )]; + [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; - if (count > 0) + if (fileTypes) + { + [panel setAllowedFileTypes:fileTypes]; + result = [panel runModal]; + } + else { - outfiles = new std::vector; + // I suggest it's better to open the last path and let this default to home dir as necessary + // for consistency with other OS X apps + // + //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ]; + result = [panel runModal]; } - for (i=0; ipush_back(*afilestr); + if (result == NSOKButton) + { + NSArray *filesToOpen = [panel URLs]; + int i, count = [filesToOpen count]; + + if (count > 0) + { + outfiles.reset(new std::vector); + } + + for (i=0; ipush_back(afilestr); + } } } + return outfiles; } -std::string* doSaveDialog(const std::string* file, +std::unique_ptr doSaveDialog(const std::string* file, const std::string* type, const std::string* creator, const std::string* extension, unsigned int flags) { - NSSavePanel *panel = [NSSavePanel savePanel]; - - NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; - NSArray *fileType = [extensionns componentsSeparatedByString:@","]; - - //[panel setMessage:@"Save Image File"]; - [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; - [panel setCanSelectHiddenExtension:true]; - [panel setAllowedFileTypes:fileType]; - NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; - - std::string *outfile = NULL; - NSURL* url = [NSURL fileURLWithPath:fileName]; - [panel setNameFieldStringValue: fileName]; - [panel setDirectoryURL: url]; - if([panel runModal] == - NSFileHandlingPanelOKButton) - { - NSURL* url = [panel URL]; - NSString* p = [url path]; - outfile = new std::string( [p UTF8String] ); - // write the file - } + std::unique_ptr outfile; + @autoreleasepool { + NSSavePanel *panel = [NSSavePanel savePanel]; + + NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; + NSArray *fileType = [extensionns componentsSeparatedByString:@","]; + + //[panel setMessage:@"Save Image File"]; + [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; + [panel setCanSelectHiddenExtension:true]; + [panel setAllowedFileTypes:fileType]; + NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; + + NSURL* url = [NSURL fileURLWithPath:fileName]; + [panel setNameFieldStringValue: fileName]; + [panel setDirectoryURL: url]; + if([panel runModal] == + NSFileHandlingPanelOKButton) + { + NSURL* url = [panel URL]; + NSString* p = [url path]; + outfile.reset(new std::string([p UTF8String])); + // write the file + } + } return outfile; } -- cgit v1.2.3 From 97ea17e6e9fec4538868e3dc86b802c1117e012b Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:50:38 -0400 Subject: Fix leak of copy and paste on mac --- indra/llwindow/llwindowmacosx-objc.h | 2 +- indra/llwindow/llwindowmacosx-objc.mm | 45 ++++++++++++++++++----------------- indra/llwindow/llwindowmacosx.cpp | 7 ++++-- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index 43edc0110d..77024d3a9c 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -83,7 +83,7 @@ int createNSApp(int argc, const char **argv); void setupCocoa(); bool pasteBoardAvailable(); bool copyToPBoard(const unsigned short *str, unsigned int len); -const unsigned short *copyFromPBoard(); +unsigned short *copyFromPBoard(); CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY); short releaseImageCursor(CursorRef ref); short setImageCursor(CursorRef ref); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 5ec9b017cf..acbcd1c281 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -64,13 +64,13 @@ void setupCocoa() bool copyToPBoard(const unsigned short *str, unsigned int len) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; - NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - [pboard clearContents]; - - NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil]; - [pool release]; - return [pboard writeObjects:contentsToPaste]; + @autoreleasepool { + NSPasteboard *pboard = [NSPasteboard generalPasteboard]; + [pboard clearContents]; + + NSArray *contentsToPaste = [[[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil] autorelease]; + return [pboard writeObjects:contentsToPaste]; + } } bool pasteBoardAvailable() @@ -79,22 +79,23 @@ bool pasteBoardAvailable() return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; } -const unsigned short *copyFromPBoard() +unsigned short *copyFromPBoard() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; - NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; - NSString *str = NULL; - BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; - if (ok) - { - NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]]; - str = [objToPaste objectAtIndex:0]; - } - unichar* temp = (unichar*)calloc([str length]+1, sizeof(unichar)); - [str getCharacters:temp]; - [pool release]; - return temp; + @autoreleasepool { + NSPasteboard *pboard = [NSPasteboard generalPasteboard]; + NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; + NSString *str = NULL; + BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; + if (ok) + { + NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]]; + str = [objToPaste objectAtIndex:0]; + } + NSUInteger str_len = [str length]; + unichar* temp = (unichar*)calloc(str_len+1, sizeof(unichar)); + [str getCharacters:temp range:NSMakeRange(0, str_len)]; + return temp; + } } CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index c29131d60b..cf940bf68c 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1246,8 +1246,11 @@ BOOL LLWindowMacOSX::isClipboardTextAvailable() } BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst) -{ - llutf16string str(copyFromPBoard()); +{ + unsigned short* pboard_data = copyFromPBoard(); // must free returned data + llutf16string str(pboard_data); + free(pboard_data); + dst = utf16str_to_wstring(str); if (dst != L"") { -- cgit v1.2.3 From d628a537f52b29dc1afd1dbea562f2abf48c7e4a Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:51:11 -0400 Subject: Fix leaks in mac IME --- indra/newview/llappdelegate-objc.mm | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 5214f4b838..1090888c1c 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -46,6 +46,7 @@ - (void)dealloc { + [currentInputLanguage release]; [super dealloc]; } @@ -199,12 +200,14 @@ - (bool) romanScript { - // How to add support for new languages with the input window: - // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.) - NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil]; - if ([nonRomanScript containsObject:currentInputLanguage]) - { - return false; + @autoreleasepool { + // How to add support for new languages with the input window: + // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.) + NSArray* nonRomanScript = @[@"ja", @"ko", @"zh-Hant", @"zh-Hans"]; + if ([nonRomanScript containsObject:currentInputLanguage]) + { + return false; + } } return true; -- cgit v1.2.3 From 83466b301a34183a0d146d13bdc7973e02172588 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:53:34 -0400 Subject: Clean up autorelease behavior in llwindowmac and additional leaks --- indra/llwindow/llwindowmacosx-objc.mm | 91 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index acbcd1c281..57c3d86295 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -49,14 +49,12 @@ void setupCocoa() if(!inited) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. - // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' - // when init'ing the Cocoa App window. - [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; - - [pool release]; + @autoreleasepool { + // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. + // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' + // when init'ing the Cocoa App window. + [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; + } inited = true; } @@ -100,19 +98,18 @@ unsigned short *copyFromPBoard() CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - // extra retain on the NSCursor since we want it to live for the lifetime of the app. - NSCursor *cursor = - [[[NSCursor alloc] - initWithImage: - [[[NSImage alloc] initWithContentsOfFile: - [NSString stringWithUTF8String:fullpath] - ]autorelease] - hotSpot:NSMakePoint(hotspotX, hotspotY) - ]retain]; - - [pool release]; + NSCursor *cursor = nil; + @autoreleasepool { + // extra retain on the NSCursor since we want it to live for the lifetime of the app. + cursor = + [[[NSCursor alloc] + initWithImage: + [[[NSImage alloc] initWithContentsOfFile: + [NSString stringWithUTF8String:fullpath] + ] autorelease] + hotSpot:NSMakePoint(hotspotX, hotspotY) + ] retain]; + } return (CursorRef)cursor; } @@ -179,10 +176,10 @@ OSErr releaseImageCursor(CursorRef ref) { if( ref != NULL ) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSCursor *cursor = (NSCursor*)ref; - [cursor release]; - [pool release]; + @autoreleasepool { + NSCursor *cursor = (NSCursor*)ref; + [cursor autorelease]; + } } else { @@ -196,10 +193,10 @@ OSErr setImageCursor(CursorRef ref) { if( ref != NULL ) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSCursor *cursor = (NSCursor*)ref; - [cursor set]; - [pool release]; + @autoreleasepool { + NSCursor *cursor = (NSCursor*)ref; + [cursor set]; + } } else { @@ -420,24 +417,26 @@ void requestUserAttention() long showAlert(std::string text, std::string title, int type) { - NSAlert *alert = [[NSAlert alloc] init]; - - [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]]; - [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]]; - if (type == 0) - { - [alert addButtonWithTitle:@"Okay"]; - } else if (type == 1) - { - [alert addButtonWithTitle:@"Okay"]; - [alert addButtonWithTitle:@"Cancel"]; - } else if (type == 2) - { - [alert addButtonWithTitle:@"Yes"]; - [alert addButtonWithTitle:@"No"]; + long ret = 0; + @autoreleasepool { + NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + + [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]]; + [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]]; + if (type == 0) + { + [alert addButtonWithTitle:@"Okay"]; + } else if (type == 1) + { + [alert addButtonWithTitle:@"Okay"]; + [alert addButtonWithTitle:@"Cancel"]; + } else if (type == 2) + { + [alert addButtonWithTitle:@"Yes"]; + [alert addButtonWithTitle:@"No"]; + } + ret = [alert runModal]; } - long ret = [alert runModal]; - [alert dealloc]; if (ret == NSAlertFirstButtonReturn) { -- cgit v1.2.3 From d89033420ef05b9b0a5751c3f254ce802e90df0b Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sat, 29 Oct 2022 23:18:03 -0400 Subject: Fix RenderAppleUseMultGL debug setting for enabling threaded GL engine --- indra/llwindow/llwindowmacosx.cpp | 4 ++-- indra/llwindow/llwindowmacosx.h | 1 + indra/newview/llappviewer.cpp | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index cf940bf68c..2fe0ed469e 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -668,11 +668,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits if (cgl_err != kCGLNoError ) { - LL_DEBUGS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; + LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; } else { - LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; + LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; } } makeFirstResponder(mWindow, mGLView); diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index b0f339e1db..851c860017 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -228,6 +228,7 @@ protected: BOOL mLanguageTextInputAllowed; LLPreeditor* mPreeditor; +public: static BOOL sUseMultGL; friend class LLWindowManager; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4f3e0b08e4..5d509fa4ff 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -135,6 +135,10 @@ #include "vlc/libvlc_version.h" #endif // LL_LINUX +#if LL_DARWIN +#include "llwindowmacosx.h" +#endif + // Third party library includes #include #include @@ -560,6 +564,7 @@ static void settings_to_globals() LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale")); #if LL_DARWIN + LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL"); gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); #endif } -- cgit v1.2.3 From 971fd6f8433b07bbd51ef83f2de518ef8b20d07f Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sat, 29 Oct 2022 23:18:35 -0400 Subject: Fix use of deprecated CGDisplayAvailableModes with CGDisplayCopyAllDisplayModes --- indra/llwindow/llwindowmacosx.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 2fe0ed469e..f924b17090 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1283,7 +1283,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r { if (!mSupportedResolutions) { - CFArrayRef modes = CGDisplayAvailableModes(mDisplay); + CFArrayRef modes = CGDisplayCopyAllDisplayModes(mDisplay, nullptr); if(modes != NULL) { @@ -1322,6 +1322,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r } } } + CFRelease(modes); } } -- cgit v1.2.3 From d0e07c770b978d57210a5403bc42cc48e700ef63 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 06:56:16 -0400 Subject: Fix checks for empty LLSD maps to use size and not emptyMap which is for creating an empty LLSDMap type. --- indra/llcommon/llerror.cpp | 2 +- indra/llui/llmultislider.cpp | 2 +- indra/llwindow/lldxhardware.cpp | 2 +- indra/newview/llenvironment.cpp | 2 +- indra/newview/llfloatermodelpreview.cpp | 2 +- indra/newview/llimprocessing.cpp | 2 +- indra/newview/llpanelexperiencelog.cpp | 2 +- indra/newview/llpanelobject.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 919d2dabc4..56fb7c21ca 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -943,7 +943,7 @@ namespace LLError for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a) { const LLSD& entry = *a; - if (entry.isMap() && !entry.emptyMap()) + if (entry.isMap() && entry.size() != 0) { ELevel level = decodeLevel(entry["level"]); diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index f89064d59a..604d246f12 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -92,7 +92,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) mMouseDownSignal(NULL), mMouseUpSignal(NULL) { - mValue.emptyMap(); + mValue = LLSD::emptyMap(); mCurSlider = LLStringUtil::null; if (mOrientation == HORIZONTAL) diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 81e938edbe..391a377280 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -1098,7 +1098,7 @@ LLSD LLDXHardware::getDisplayInfo() } LCleanup: - if (ret.emptyMap()) + if (!ret.isMap() || (ret.size() == 0)) { LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL; } diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 1300cf3658..a01410e521 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -3086,7 +3086,7 @@ bool LLEnvironment::loadFromSettings() LL_INFOS("ENVIRONMENT") << "Unable to open previous session environment file " << user_filepath << LL_ENDL; } - if (!env_data.isMap() || env_data.emptyMap()) + if (!env_data.isMap() || (env_data.size() == 0)) { LL_DEBUGS("ENVIRONMENT") << "Empty map loaded from: " << user_filepath << LL_ENDL; return false; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 66a245b779..6f8f73bca0 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1740,7 +1740,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible) childSetTextArg("download_weight", "[ST]", tbd); childSetTextArg("server_weight", "[SIM]", tbd); childSetTextArg("physics_weight", "[PH]", tbd); - if (!mModelPhysicsFee.isMap() || mModelPhysicsFee.emptyMap()) + if (!mModelPhysicsFee.isMap() || (mModelPhysicsFee.size() == 0)) { childSetTextArg("upload_fee", "[FEE]", tbd); } diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 0524313a5c..57c0c7388e 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1561,7 +1561,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url) return; } - if (messages.emptyArray()) + if (messages.size() == 0) { // Nothing to process return; diff --git a/indra/newview/llpanelexperiencelog.cpp b/indra/newview/llpanelexperiencelog.cpp index 44b4728df7..e5c637938f 100644 --- a/indra/newview/llpanelexperiencelog.cpp +++ b/indra/newview/llpanelexperiencelog.cpp @@ -112,7 +112,7 @@ void LLPanelExperienceLog::refresh() int items = 0; bool moreItems = false; LLSD events_to_save = events; - if (!events.emptyMap()) + if (events.isMap() && events.size() != 0) { LLSD::map_const_iterator day = events.endMap(); do diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 0bfc1297d3..c04b402610 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2119,7 +2119,7 @@ bool LLPanelObject::menuEnableItem(const LLSD& userdata) } else if (command == "params_paste") { - return mClipboardParams.isMap() && !mClipboardParams.emptyMap(); + return mClipboardParams.isMap() && (mClipboardParams.size() != 0); } // copy options else if (command == "psr_copy") -- cgit v1.2.3 From 8669f3f4c207e913bc2f6e39438d92d76b3aa1c4 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 06:59:54 -0400 Subject: Fix line editors deselecting when pressing capslock --- indra/llui/lllineeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 33037b5001..4c7dd034fc 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1567,7 +1567,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask ) KEY_SHIFT != key && KEY_CONTROL != key && KEY_ALT != key && - KEY_CAPSLOCK ) + KEY_CAPSLOCK != key) { deselect(); } -- cgit v1.2.3 From f3dd2bf95f942653123ec7a1011cf873fa7b4fb3 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 06:59:08 -0400 Subject: Fix menu checks for enabling object sit and touch to not traverse the entire menu holder to update labels --- indra/newview/llviewermenu.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 3573af40cb..fa2ec5fbec 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2803,14 +2803,15 @@ void handle_object_show_original() } -static void init_default_item_label(const std::string& item_name) +static void init_default_item_label(LLUICtrl* ctrl) { + const std::string& item_name = ctrl->getName(); boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); if (it == sDefaultItemLabels.end()) { // *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value // (doesn't seem to matter much ATM). - LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString(); + LLStringExplicit default_label = ctrl->getValue().asString(); if (!default_label.empty()) { sDefaultItemLabels.insert(std::pair(item_name, default_label)); @@ -2841,18 +2842,17 @@ bool enable_object_touch(LLUICtrl* ctrl) new_value = obj->flagHandleTouch() || (parent && parent->flagHandleTouch()); } - std::string item_name = ctrl->getName(); - init_default_item_label(item_name); + init_default_item_label(ctrl); // Update label based on the node touch name if available. LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid && !node->mTouchName.empty()) { - gMenuHolder->childSetValue(item_name, node->mTouchName); + ctrl->setValue(node->mTouchName); } else { - gMenuHolder->childSetValue(item_name, get_default_item_label(item_name)); + ctrl->setValue(get_default_item_label(ctrl->getName())); } return new_value; @@ -6591,20 +6591,18 @@ bool enable_object_sit(LLUICtrl* ctrl) bool sitting_on_sel = sitting_on_selection(); if (!sitting_on_sel) { - std::string item_name = ctrl->getName(); - // init default labels - init_default_item_label(item_name); + init_default_item_label(ctrl); // Update label LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid && !node->mSitName.empty()) { - gMenuHolder->childSetValue(item_name, node->mSitName); + ctrl->setValue(node->mSitName); } else { - gMenuHolder->childSetValue(item_name, get_default_item_label(item_name)); + ctrl->setValue(get_default_item_label(ctrl->getName())); } } return !sitting_on_sel && is_object_sittable(); -- cgit v1.2.3 From 0c36fed11056511872afae14a39a88f5e46be0fc Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 18:05:34 -0400 Subject: Correct macOS png loader to use a default gamma of 2.2 as apple has done since OS 10.6 --- indra/llimage/llpngwrapper.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index f7dc6272cf..cad7c00042 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -257,12 +257,7 @@ void LLPngWrapper::normalizeImage() png_set_strip_16(mReadPngPtr); } -#if LL_DARWIN - const F64 SCREEN_GAMMA = 1.8; -#else const F64 SCREEN_GAMMA = 2.2; -#endif - if (png_get_gAMA(mReadPngPtr, mReadInfoPtr, &mGamma)) { png_set_gamma(mReadPngPtr, SCREEN_GAMMA, mGamma); -- cgit v1.2.3 From f5b447bc4781d518fbe7841eea6cadd909b57a0a Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine 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(-) 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 @@ Type U32 Value - 25 + 30 AutoTuneFPS Comment Allow the viewer to adjust your settings to achieve target FPS Persist - 0 + 1 Type Boolean Value 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 52b64bcfd7292cb2013ec959d646ba0a01d58a79 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Mon, 31 Oct 2022 14:17:05 -0700 Subject: Fix SL-18511 TOS and MFA login failure handlers must cooperate to answer both reasons at the same time --- indra/newview/lllogininstance.cpp | 86 +++++++++++++++++++++++---------------- indra/newview/lllogininstance.h | 1 + 2 files changed, 53 insertions(+), 34 deletions(-) diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 82ecfbd4dc..dd8c9b2dde 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -451,26 +451,8 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event) LLSD args(llsd::map( "MESSAGE", LLTrans::getString(response["message_id"]) )); LLSD payload; - LLNotificationsUtil::add("PromptMFAToken", args, payload, [=](LLSD const & notif, LLSD const & response) { - bool continue_clicked = response["continue"].asBoolean(); - std::string token = response["token"].asString(); - LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL; - - // strip out whitespace - SL-17034/BUG-231938 - token = boost::regex_replace(token, boost::regex("\\s"), ""); - - if (continue_clicked && !token.empty()) - { - LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL; - - // Set the request data to true and retry login. - mRequestData["params"]["token"] = token; - reconnect(); - } else { - LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL; - attemptComplete(); - } - }); + LLNotificationsUtil::add("PromptMFAToken", args, payload, + boost::bind(&LLLoginInstance::handleMFAChallenge, this, _1, _2)); } else if( reason_response == "key" || reason_response == "presence" @@ -547,23 +529,59 @@ void LLLoginInstance::handleIndeterminate(const LLSD& event) bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key) { - if(accepted) - { - LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: accepted" << LL_ENDL; + if(accepted) + { + LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: accepted " << LL_ENDL; - // Set the request data to true and retry login. - mRequestData["params"][key] = true; - reconnect(); - } - else - { - LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: attemptComplete" << LL_ENDL; + // Set the request data to true and retry login. + mRequestData["params"][key] = true; - attemptComplete(); - } + if (!mRequestData["params"]["token"].asString().empty()) + { + // SL-18511 this TOS failure happened while we are in the middle of an MFA challenge/response. + // the previously entered token is very likely expired, so prompt again + LLSD args(llsd::map( "MESSAGE", LLTrans::getString("LoginFailedAuthenticationMFARequired") )); + LLSD payload; + LLNotificationsUtil::add("PromptMFAToken", args, payload, + boost::bind(&LLLoginInstance::handleMFAChallenge, this, _1, _2)); + } + else + { + reconnect(); + } + } + else + { + LL_INFOS("LLLogin") << "LLLoginInstance::handleTOSResponse: attemptComplete" << LL_ENDL; + + attemptComplete(); + } + + LLEventPumps::instance().obtain(TOS_REPLY_PUMP).stopListening(TOS_LISTENER_NAME); + return true; +} - LLEventPumps::instance().obtain(TOS_REPLY_PUMP).stopListening(TOS_LISTENER_NAME); - return true; +bool LLLoginInstance::handleMFAChallenge(LLSD const & notif, LLSD const & response) +{ + bool continue_clicked = response["continue"].asBoolean(); + std::string token = response["token"].asString(); + LL_DEBUGS("LLLogin") << "PromptMFAToken: response: " << response << " continue_clicked" << continue_clicked << LL_ENDL; + + // strip out whitespace - SL-17034/BUG-231938 + token = boost::regex_replace(token, boost::regex("\\s"), ""); + + if (continue_clicked && !token.empty()) + { + LL_INFOS("LLLogin") << "PromptMFAToken: token submitted" << LL_ENDL; + + // Set the request data to true and retry login. + mRequestData["params"]["token"] = token; + reconnect(); + } else { + LL_INFOS("LLLogin") << "PromptMFAToken: no token, attemptComplete" << LL_ENDL; + attemptComplete(); + } + return true; } std::string construct_start_string() diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h index b759b43474..ee3ef0e4b1 100644 --- a/indra/newview/lllogininstance.h +++ b/indra/newview/lllogininstance.h @@ -84,6 +84,7 @@ private: void syncWithUpdater(ResponsePtr resp, const LLSD& notification, const LLSD& response); bool handleTOSResponse(bool v, const std::string& key); + bool handleMFAChallenge(LLSD const & notif, LLSD const & response); void attemptComplete() { mAttemptComplete = true; } // In the future an event? -- cgit v1.2.3 From 15b5dedb2dc139c85461e7c867164b65cc6fc628 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 1 Nov 2022 17:16:13 -0400 Subject: Increment viewer version to 6.6.8 following promotion of DRTVWR-575 --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index 5db1411e12..4aa5a3a58e 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.6.7 +6.6.8 -- cgit v1.2.3 From 791fb0ee565ef8c485c5883ebfbad4146cfeb65b Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 2 Nov 2022 19:08:05 +0200 Subject: SL-18533 Updated ToS XUI with new language --- indra/newview/skins/default/xui/en/floater_tos.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml index a8db0aca4e..7e172e138a 100644 --- a/indra/newview/skins/default/xui/en/floater_tos.xml +++ b/indra/newview/skins/default/xui/en/floater_tos.xml @@ -76,7 +76,7 @@ word_wrap="true" text_readonly_color="LabelDisabledColor" width="552"> - I have read and agree to the Second Life Terms and Conditions, Privacy Policy, and Terms of Service, including the dispute resolution requirements. + I consent to the Linden Lab Terms of Service, Second Life Terms and Conditions, and acknowledge receipt of the Privacy Policy.