summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authorAndrey Kleshchev <117672381+akleshchev@users.noreply.github.com>2026-01-07 19:24:11 +0200
committerGitHub <noreply@github.com>2026-01-07 19:24:11 +0200
commit1cf375c89adfae557b18dadfb267659b6fb0a8ce (patch)
tree77c9f59277aad29cf00dd2de00d97c1909f9f59e /indra
parent516bd5e832a91e1f837b5b1b621cfac5fe71c08f (diff)
parentcab31f8bfed507425a09b266d47823f6acddfa94 (diff)
Merge pull request #5227 from RyeMutt/rye/devmerge
Sync develop-linux with develop
Diffstat (limited to 'indra')
-rw-r--r--indra/llappearance/lltexlayer.cpp18
-rw-r--r--indra/llcharacter/CMakeLists.txt4
-rw-r--r--indra/llcharacter/llkeyframemotionparam.cpp436
-rw-r--r--indra/llcharacter/llkeyframemotionparam.h169
-rw-r--r--indra/llcharacter/llmotioncontroller.h1
-rw-r--r--indra/llcharacter/llstatemachine.cpp384
-rw-r--r--indra/llcharacter/llstatemachine.h147
-rw-r--r--indra/llcommon/CMakeLists.txt1
-rwxr-xr-xindra/llcommon/llpointer.cpp43
-rw-r--r--indra/llcommon/llpointer.h291
-rw-r--r--indra/llcommon/workqueue.cpp22
-rw-r--r--indra/llimage/llimage.h5
-rw-r--r--indra/llmath/llvolumemgr.cpp1
-rw-r--r--indra/llmath/v3math.h9
-rw-r--r--indra/llprimitive/llprimitive.h9
-rw-r--r--indra/llrender/llrender.cpp63
-rw-r--r--indra/llrender/llrender.h13
-rw-r--r--indra/llui/lllineeditor.cpp1
-rw-r--r--indra/llui/lllineeditor.h2
-rw-r--r--indra/llui/llnotifications.h1
-rw-r--r--indra/llui/llscrolllistctrl.cpp1
-rw-r--r--indra/llui/lltexteditor.cpp2
-rw-r--r--indra/llwebrtc/llwebrtc.cpp3
-rw-r--r--indra/llxml/llcontrol.cpp29
-rw-r--r--indra/llxml/llcontrol.h2
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/settings.xml13
-rw-r--r--indra/newview/llagentcamera.cpp8
-rw-r--r--indra/newview/llappviewer.cpp19
-rw-r--r--indra/newview/llavataractions.cpp2
-rw-r--r--indra/newview/lldrawable.cpp8
-rw-r--r--indra/newview/lldrawpoolalpha.cpp2
-rw-r--r--indra/newview/llface.cpp6
-rw-r--r--indra/newview/llfloatereditenvironmentbase.cpp2
-rw-r--r--indra/newview/llfloatermarketplace.cpp35
-rw-r--r--indra/newview/llfloatermarketplace.h3
-rw-r--r--indra/newview/llfloatermarketplacelistings.cpp24
-rw-r--r--indra/newview/llfloaterobjectweights.cpp2
-rw-r--r--indra/newview/llfloaterpay.cpp2
-rw-r--r--indra/newview/llfloaterpreference.cpp15
-rw-r--r--indra/newview/llfloaterpreference.h1
-rw-r--r--indra/newview/llfloaterregioninfo.cpp15
-rw-r--r--indra/newview/llglsandbox.cpp66
-rw-r--r--indra/newview/llgrouplist.cpp2
-rw-r--r--indra/newview/llhudnametag.cpp2
-rw-r--r--indra/newview/llinventorybridge.cpp22
-rw-r--r--indra/newview/llinventoryfunctions.cpp14
-rw-r--r--indra/newview/llinventorygallery.cpp10
-rw-r--r--indra/newview/llinventorygallerymenu.cpp8
-rw-r--r--indra/newview/llinventorymodel.cpp11
-rw-r--r--indra/newview/llinventorymodel.h4
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp2
-rw-r--r--indra/newview/llinventorypanel.cpp16
-rw-r--r--indra/newview/lllocalbitmaps.cpp2
-rw-r--r--indra/newview/llmarketplacefunctions.cpp4
-rw-r--r--indra/newview/llmeshrepository.cpp59
-rw-r--r--indra/newview/llmeshrepository.h12
-rw-r--r--indra/newview/llpanelgroup.cpp34
-rw-r--r--indra/newview/llpanelgroup.h9
-rw-r--r--indra/newview/llpanellogin.cpp36
-rw-r--r--indra/newview/llpanellogin.h6
-rw-r--r--indra/newview/llpanelobject.cpp37
-rw-r--r--indra/newview/llpanelvolume.cpp10
-rw-r--r--indra/newview/llspatialpartition.cpp5
-rw-r--r--indra/newview/llspatialpartition.h2
-rw-r--r--indra/newview/lltooldraganddrop.cpp2
-rw-r--r--indra/newview/lltoolselect.cpp9
-rw-r--r--indra/newview/llvieweraudio.cpp59
-rw-r--r--indra/newview/llviewermedia.cpp14
-rw-r--r--indra/newview/llviewermenu.cpp2
-rw-r--r--indra/newview/llviewerobject.cpp168
-rw-r--r--indra/newview/llviewerobject.h64
-rw-r--r--indra/newview/llviewerobjectlist.cpp3
-rw-r--r--indra/newview/llvieweroctree.h1
-rw-r--r--indra/newview/llviewerparcelmgr.cpp3
-rwxr-xr-xindra/newview/llviewerparceloverlay.cpp235
-rw-r--r--indra/newview/llviewerparceloverlay.h5
-rw-r--r--indra/newview/llviewerwindow.cpp36
-rw-r--r--indra/newview/llvoicewebrtc.cpp14
-rw-r--r--indra/newview/llvovolume.cpp153
-rw-r--r--indra/newview/llvovolume.h5
-rw-r--r--indra/newview/llwatchdog.cpp1
-rw-r--r--indra/newview/llweb.cpp13
-rw-r--r--indra/newview/llworldmap.cpp1
-rwxr-xr-xindra/newview/llworldmapview.cpp40
-rw-r--r--indra/newview/pipeline.cpp2
-rw-r--r--indra/newview/skins/default/xui/en/floater_test_combobox.xml32
-rw-r--r--indra/newview/skins/default/xui/en/floater_world_map.xml30
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_group_general.xml9
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_general.xml2
-rw-r--r--indra/newview/skins/default/xui/en/panel_region_general.xml55
92 files changed, 1247 insertions, 1904 deletions
diff --git a/indra/llappearance/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
index 1bdaa814b7..5a02dfe716 100644
--- a/indra/llappearance/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -1449,6 +1449,12 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
size_t mem_size = pixels * bytes_per_pixel;
alpha_data = (U8*)ll_aligned_malloc_32(mem_size);
+ if (!alpha_data)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Failed to allocate memory for morph texture: " << (S32)(mem_size) << LL_ENDL;
+ return;
+ }
bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels
@@ -1458,6 +1464,12 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
{ // work-around for broken intel drivers which cannot do glReadPixels on an RGBA FBO
// returning only the alpha portion without locking up downstream
U8* temp = (U8*)ll_aligned_malloc_32(mem_size << 2); // allocate same size, but RGBA
+ if (!temp)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Failed to allocate temporary memory for morph texture readback: " << (S32)(mem_size << 2) << LL_ENDL;
+ return;
+ }
if (bound_target)
{
@@ -1494,6 +1506,12 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
// We just want GL_ALPHA, but that isn't supported in OGL core profile 4.
static const size_t TEMP_BYTES_PER_PIXEL = 4;
U8* temp_data = (U8*)ll_aligned_malloc_32(mem_size * TEMP_BYTES_PER_PIXEL);
+ if (!temp_data)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS() << "Failed to allocate temporary memory for morph texture: " << (S32)(mem_size * TEMP_BYTES_PER_PIXEL) << LL_ENDL;
+ return;
+ }
glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, temp_data);
for (size_t pixel = 0; pixel < pixels; pixel++) {
alpha_data[pixel] = temp_data[(pixel * TEMP_BYTES_PER_PIXEL) + 3];
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index 0d7802279a..9dbbddde8a 100644
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -17,14 +17,12 @@ set(llcharacter_SOURCE_FILES
lljointsolverrp3.cpp
llkeyframefallmotion.cpp
llkeyframemotion.cpp
- llkeyframemotionparam.cpp
llkeyframestandmotion.cpp
llkeyframewalkmotion.cpp
llmotioncontroller.cpp
llmotion.cpp
llmultigesture.cpp
llpose.cpp
- llstatemachine.cpp
lltargetingmotion.cpp
llvisualparam.cpp
)
@@ -45,14 +43,12 @@ set(llcharacter_HEADER_FILES
lljointstate.h
llkeyframefallmotion.h
llkeyframemotion.h
- llkeyframemotionparam.h
llkeyframestandmotion.h
llkeyframewalkmotion.h
llmotion.h
llmotioncontroller.h
llmultigesture.h
llpose.h
- llstatemachine.h
lltargetingmotion.h
llvisualparam.h
)
diff --git a/indra/llcharacter/llkeyframemotionparam.cpp b/indra/llcharacter/llkeyframemotionparam.cpp
deleted file mode 100644
index e4552b96c9..0000000000
--- a/indra/llcharacter/llkeyframemotionparam.cpp
+++ /dev/null
@@ -1,436 +0,0 @@
-/**
- * @file llkeyframemotionparam.cpp
- * @brief Implementation of LLKeyframeMotion class.
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-//-----------------------------------------------------------------------------
-// Header Files
-//-----------------------------------------------------------------------------
-#include "linden_common.h"
-
-#include "llkeyframemotionparam.h"
-#include "llcharacter.h"
-#include "llmath.h"
-#include "m3math.h"
-#include "lldir.h"
-#include "llanimationstates.h"
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam class
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam()
-// Class Constructor
-//-----------------------------------------------------------------------------
-LLKeyframeMotionParam::LLKeyframeMotionParam( const LLUUID &id) : LLMotion(id)
-{
- mDefaultKeyframeMotion = NULL;
- mCharacter = NULL;
-
- mEaseInDuration = 0.f;
- mEaseOutDuration = 0.f;
- mDuration = 0.f;
- mPriority = LLJoint::LOW_PRIORITY;
-}
-
-
-//-----------------------------------------------------------------------------
-// ~LLKeyframeMotionParam()
-// Class Destructor
-//-----------------------------------------------------------------------------
-LLKeyframeMotionParam::~LLKeyframeMotionParam()
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- delete paramMotion.mMotion;
- }
- motionList.clear();
- }
- mParameterizedMotions.clear();
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onInitialize(LLCharacter *character)
-//-----------------------------------------------------------------------------
-LLMotion::LLMotionInitStatus LLKeyframeMotionParam::onInitialize(LLCharacter *character)
-{
- mCharacter = character;
-
- if (!loadMotions())
- {
- return STATUS_FAILURE;
- }
-
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- LLMotion* motion = paramMotion.mMotion;
- motion->onInitialize(character);
-
- if (motion->getDuration() > mEaseInDuration)
- {
- mEaseInDuration = motion->getEaseInDuration();
- }
-
- if (motion->getEaseOutDuration() > mEaseOutDuration)
- {
- mEaseOutDuration = motion->getEaseOutDuration();
- }
-
- if (motion->getDuration() > mDuration)
- {
- mDuration = motion->getDuration();
- }
-
- if (motion->getPriority() > mPriority)
- {
- mPriority = motion->getPriority();
- }
-
- LLPose *pose = motion->getPose();
-
- mPoseBlender.addMotion(motion);
- for (LLJointState *jsp = pose->getFirstJointState(); jsp; jsp = pose->getNextJointState())
- {
- LLPose *blendedPose = mPoseBlender.getBlendedPose();
- blendedPose->addJointState(jsp);
- }
- }
- }
-
- return STATUS_SUCCESS;
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onActivate()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::onActivate()
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- paramMotion.mMotion->activate(mActivationTimestamp);
- }
- }
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onUpdate()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::onUpdate(F32 time, U8* joint_mask)
-{
- LL_PROFILE_ZONE_SCOPED;
- F32 weightFactor = 1.f / (F32)mParameterizedMotions.size();
-
- // zero out all pose weights
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
-// LL_INFOS() << "Weight for pose " << paramMotion.mMotion->getName() << " is " << paramMotion.mMotion->getPose()->getWeight() << LL_ENDL;
- paramMotion.mMotion->getPose()->setWeight(0.f);
- }
- }
-
-
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- const std::string& paramName = motion_pair.first;
- F32* paramValue = (F32 *)mCharacter->getAnimationData(paramName);
- if (NULL == paramValue) // unexpected, but...
- {
- LL_WARNS() << "paramValue == NULL" << LL_ENDL;
- continue;
- }
-
- // DANGER! Do not modify mParameterizedMotions while using these pointers!
- const ParameterizedMotion* firstMotion = NULL;
- const ParameterizedMotion* secondMotion = NULL;
-
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- paramMotion.mMotion->onUpdate(time, joint_mask);
-
- F32 distToParam = paramMotion.mParam - *paramValue;
-
- if ( distToParam <= 0.f)
- {
- // keep track of the motion closest to the parameter value
- firstMotion = &paramMotion;
- }
- else
- {
- // we've passed the parameter value
- // so store the first motion we find as the second one we want to blend...
- if (firstMotion && !secondMotion )
- {
- secondMotion = &paramMotion;
- }
- //...or, if we've seen no other motion so far, make sure we blend to this only
- else if (!firstMotion)
- {
- firstMotion = &paramMotion;
- secondMotion = &paramMotion;
- }
- }
- }
-
- LLPose *firstPose;
- LLPose *secondPose;
-
- if (firstMotion)
- firstPose = firstMotion->mMotion->getPose();
- else
- firstPose = NULL;
-
- if (secondMotion)
- secondPose = secondMotion->mMotion->getPose();
- else
- secondPose = NULL;
-
- // now modify weight of the subanim (only if we are blending between two motions)
- if (firstMotion && secondMotion)
- {
- if (firstMotion == secondMotion)
- {
- firstPose->setWeight(weightFactor);
- }
- else if (firstMotion->mParam == secondMotion->mParam)
- {
- firstPose->setWeight(0.5f * weightFactor);
- secondPose->setWeight(0.5f * weightFactor);
- }
- else
- {
- F32 first_weight = 1.f -
- ((llclamp(*paramValue - firstMotion->mParam, 0.f, (secondMotion->mParam - firstMotion->mParam))) /
- (secondMotion->mParam - firstMotion->mParam));
- first_weight = llclamp(first_weight, 0.f, 1.f);
-
- F32 second_weight = 1.f - first_weight;
-
- firstPose->setWeight(first_weight * weightFactor);
- secondPose->setWeight(second_weight * weightFactor);
-
-// LL_INFOS() << "Parameter " << *paramName << ": " << *paramValue << LL_ENDL;
-// LL_INFOS() << "Weights " << firstPose->getWeight() << " " << secondPose->getWeight() << LL_ENDL;
- }
- }
- else if (firstMotion && !secondMotion)
- {
- firstPose->setWeight(weightFactor);
- }
- }
-
- // blend poses
- mPoseBlender.blendAndApply();
-
- LL_INFOS() << "Param Motion weight " << mPoseBlender.getBlendedPose()->getWeight() << LL_ENDL;
-
- return true;
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::onDeactivate()
-//-----------------------------------------------------------------------------
-void LLKeyframeMotionParam::onDeactivate()
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- paramMotion.mMotion->onDeactivate();
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::addKeyframeMotion()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value)
-{
- LLMotion *newMotion = mCharacter->createMotion( id );
-
- if (!newMotion)
- {
- return false;
- }
-
- newMotion->setName(name);
-
- // now add motion to this list
- mParameterizedMotions[param].insert(ParameterizedMotion(newMotion, value));
-
- return true;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLKeyframeMotionParam::setDefaultKeyframeMotion()
-//-----------------------------------------------------------------------------
-void LLKeyframeMotionParam::setDefaultKeyframeMotion(char *name)
-{
- for (motion_map_t::value_type& motion_pair : mParameterizedMotions)
- {
- motion_list_t& motionList = motion_pair.second;
- for (const ParameterizedMotion& paramMotion : motionList)
- {
- if (paramMotion.mMotion->getName() == name)
- {
- mDefaultKeyframeMotion = paramMotion.mMotion;
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-// loadMotions()
-//-----------------------------------------------------------------------------
-bool LLKeyframeMotionParam::loadMotions()
-{
- //-------------------------------------------------------------------------
- // Load named file by concatenating the character prefix with the motion name.
- // Load data into a buffer to be parsed.
- //-------------------------------------------------------------------------
- //std::string path = gDirUtilp->getExpandedFilename(LL_PATH_MOTIONS,mCharacter->getAnimationPrefix())
- // + "_" + getName() + ".llp";
- //RN: deprecated unused reference to "motion" directory
- std::string path;
-
-
- //-------------------------------------------------------------------------
- // open the file
- //-------------------------------------------------------------------------
- S32 fileSize = 0;
- LLAPRFile infile ;
- infile.open(path, LL_APR_R, NULL, &fileSize);
- apr_file_t* fp = infile.getFileHandle() ;
- if (!fp || fileSize == 0)
- {
- LL_INFOS() << "ERROR: can't open: " << path << LL_ENDL;
- return false;
- }
-
- // allocate a text buffer
- std::vector<char> text(fileSize+1);
-
- //-------------------------------------------------------------------------
- // load data from file into buffer
- //-------------------------------------------------------------------------
- bool error = false;
- char *p = &text[0];
- while ( 1 )
- {
- if (apr_file_eof(fp) == APR_EOF)
- {
- break;
- }
- if (apr_file_gets(p, 1024, fp) != APR_SUCCESS)
- {
- error = true;
- break;
- }
- while ( *(++p) )
- ;
- }
-
- //-------------------------------------------------------------------------
- // close the file
- //-------------------------------------------------------------------------
- infile.close();
-
- //-------------------------------------------------------------------------
- // check for error
- //-------------------------------------------------------------------------
- llassert( p <= (&text[0] + fileSize) );
-
- if ( error )
- {
- LL_INFOS() << "ERROR: error while reading from " << path << LL_ENDL;
- return false;
- }
-
- LL_INFOS() << "Loading parametric keyframe data for: " << getName() << LL_ENDL;
-
- //-------------------------------------------------------------------------
- // parse the text and build keyframe data structures
- //-------------------------------------------------------------------------
- p = &text[0];
- S32 num;
- char strA[80]; /* Flawfinder: ignore */
- char strB[80]; /* Flawfinder: ignore */
- F32 floatA = 0.0f;
-
-
- //-------------------------------------------------------------------------
- // get priority
- //-------------------------------------------------------------------------
- bool isFirstMotion = true;
- num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
-
- while(1)
- {
- if (num == 0 || num == EOF) break;
- if ((num != 3))
- {
- LL_INFOS() << "WARNING: can't read parametric motion" << LL_ENDL;
- return false;
- }
-
- addKeyframeMotion(strA, gAnimLibrary.stringToAnimState(std::string(strA)), strB, floatA);
- if (isFirstMotion)
- {
- isFirstMotion = false;
- setDefaultKeyframeMotion(strA);
- }
-
- p = strstr(p, "\n");
- if (!p)
- {
- break;
- }
-
- p++;
- num = sscanf(p, "%79s %79s %f", strA, strB, &floatA); /* Flawfinder: ignore */
- }
-
- return true;
-}
-
-// End
diff --git a/indra/llcharacter/llkeyframemotionparam.h b/indra/llcharacter/llkeyframemotionparam.h
deleted file mode 100644
index 8c57766e9b..0000000000
--- a/indra/llcharacter/llkeyframemotionparam.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/**
- * @file llkeyframemotionparam.h
- * @brief Implementation of LLKeframeMotionParam class.
- *
- * $LicenseInfo:firstyear=2002&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$
- */
-
-#ifndef LL_LLKEYFRAMEMOTIONPARAM_H
-#define LL_LLKEYFRAMEMOTIONPARAM_H
-
-//-----------------------------------------------------------------------------
-// Header files
-//-----------------------------------------------------------------------------
-
-#include <string>
-
-#include "llmotion.h"
-#include "lljointstate.h"
-#include "v3math.h"
-#include "llquaternion.h"
-#include "llkeyframemotion.h"
-
-//-----------------------------------------------------------------------------
-// class LLKeyframeMotionParam
-//-----------------------------------------------------------------------------
-class LLKeyframeMotionParam :
- public LLMotion
-{
-public:
- // Constructor
- LLKeyframeMotionParam(const LLUUID &id);
-
- // Destructor
- virtual ~LLKeyframeMotionParam();
-
-public:
- //-------------------------------------------------------------------------
- // functions to support MotionController and MotionRegistry
- //-------------------------------------------------------------------------
-
- // static constructor
- // all subclasses must implement such a function and register it
- static LLMotion *create(const LLUUID &id) { return new LLKeyframeMotionParam(id); }
-
-public:
- //-------------------------------------------------------------------------
- // animation callbacks to be implemented by subclasses
- //-------------------------------------------------------------------------
-
- // motions must specify whether or not they loop
- virtual bool getLoop() {
- return true;
- }
-
- // motions must report their total duration
- virtual F32 getDuration() {
- return mDuration;
- }
-
- // motions must report their "ease in" duration
- virtual F32 getEaseInDuration() {
- return mEaseInDuration;
- }
-
- // motions must report their "ease out" duration.
- virtual F32 getEaseOutDuration() {
- return mEaseOutDuration;
- }
-
- // motions must report their priority
- virtual LLJoint::JointPriority getPriority() {
- return mPriority;
- }
-
- virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; }
-
- // called to determine when a motion should be activated/deactivated based on avatar pixel coverage
- virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_KEYFRAME; }
-
- // run-time (post constructor) initialization,
- // called after parameters have been set
- // must return true to indicate success and be available for activation
- virtual LLMotionInitStatus onInitialize(LLCharacter *character);
-
- // called when a motion is activated
- // must return true to indicate success, or else
- // it will be deactivated
- virtual bool onActivate();
-
- // called per time step
- // must return true while it is active, and
- // must return false when the motion is completed.
- virtual bool onUpdate(F32 time, U8* joint_mask);
-
- // called when a motion is deactivated
- virtual void onDeactivate();
-
- virtual LLPose* getPose() { return mPoseBlender.getBlendedPose();}
-
-protected:
- //-------------------------------------------------------------------------
- // new functions defined by this subclass
- //-------------------------------------------------------------------------
- struct ParameterizedMotion
- {
- ParameterizedMotion(LLMotion* motion, F32 param) : mMotion(motion), mParam(param) {}
- LLMotion* mMotion;
- F32 mParam;
- };
-
- // add a motion and associated parameter triplet
- bool addKeyframeMotion(char *name, const LLUUID &id, char *param, F32 value);
-
- // set default motion for LOD and retrieving blend constants
- void setDefaultKeyframeMotion(char *);
-
- bool loadMotions();
-
-protected:
- //-------------------------------------------------------------------------
- // Member Data
- //-------------------------------------------------------------------------
-
- struct compare_motions
- {
- bool operator() (const ParameterizedMotion& a, const ParameterizedMotion& b) const
- {
- if (a.mParam != b.mParam)
- return (a.mParam < b.mParam);
- else
- return a.mMotion < b.mMotion;
- }
- };
-
- typedef std::set < ParameterizedMotion, compare_motions > motion_list_t;
- typedef std::map <std::string, motion_list_t > motion_map_t;
- motion_map_t mParameterizedMotions;
- LLMotion* mDefaultKeyframeMotion;
- LLCharacter* mCharacter;
- LLPoseBlender mPoseBlender;
-
- F32 mEaseInDuration;
- F32 mEaseOutDuration;
- F32 mDuration;
- LLJoint::JointPriority mPriority;
-
- LLUUID mTransactionID;
-};
-
-#endif // LL_LLKEYFRAMEMOTIONPARAM_H
diff --git a/indra/llcharacter/llmotioncontroller.h b/indra/llcharacter/llmotioncontroller.h
index 0c262bf24a..c2cb174821 100644
--- a/indra/llcharacter/llmotioncontroller.h
+++ b/indra/llcharacter/llmotioncontroller.h
@@ -37,7 +37,6 @@
#include "llmotion.h"
#include "llpose.h"
#include "llframetimer.h"
-#include "llstatemachine.h"
#include "llstring.h"
//-----------------------------------------------------------------------------
diff --git a/indra/llcharacter/llstatemachine.cpp b/indra/llcharacter/llstatemachine.cpp
deleted file mode 100644
index 38e9ef444c..0000000000
--- a/indra/llcharacter/llstatemachine.cpp
+++ /dev/null
@@ -1,384 +0,0 @@
-/**
- * @file llstatemachine.cpp
- * @brief LLStateMachine implementation file.
- *
- * $LicenseInfo:firstyear=2001&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 "llstatemachine.h"
-#include "llapr.h"
-
-#define FSM_PRINT_STATE_TRANSITIONS (0)
-
-U32 LLUniqueID::sNextID = 0;
-
-bool operator==(const LLUniqueID &a, const LLUniqueID &b)
-{
- return (a.mId == b.mId);
-}
-
-bool operator!=(const LLUniqueID &a, const LLUniqueID &b)
-{
- return (a.mId != b.mId);
-}
-
-//-----------------------------------------------------------------------------
-// LLStateDiagram
-//-----------------------------------------------------------------------------
-LLStateDiagram::LLStateDiagram()
-{
- mDefaultState = NULL;
- mUseDefaultState = false;
-}
-
-LLStateDiagram::~LLStateDiagram()
-{
-
-}
-
-// add a state to the state graph
-bool LLStateDiagram::addState(LLFSMState *state)
-{
- mStates[state] = Transitions();
- return true;
-}
-
-// add a directed transition between 2 states
-bool LLStateDiagram::addTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition)
-{
- StateMap::iterator state_it;
- state_it = mStates.find(&start_state);
- Transitions* state_transitions = NULL;
- if (state_it == mStates.end() )
- {
- addState(&start_state);
- state_transitions = &mStates[&start_state];
- }
- else
- {
- state_transitions = &state_it->second;
- }
- state_it = mStates.find(&end_state);
- if (state_it == mStates.end() )
- {
- addState(&end_state);
- }
-
- Transitions::iterator transition_it = state_transitions->find(&transition);
- if (transition_it != state_transitions->end())
- {
- LL_ERRS() << "LLStateTable::addDirectedTransition() : transition already exists" << LL_ENDL;
- return false; // transition already exists
- }
-
- (*state_transitions)[&transition] = &end_state;
- return true;
-}
-
-// add an undirected transition between 2 states
-bool LLStateDiagram::addUndirectedTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition)
-{
- bool result;
- result = addTransition(start_state, end_state, transition);
- if (result)
- {
- result = addTransition(end_state, start_state, transition);
- }
- return result;
-}
-
-// add a transition that exists for every state
-void LLStateDiagram::addDefaultTransition(LLFSMState& end_state, LLFSMTransition& transition)
-{
- mDefaultTransitions[&transition] = &end_state;
-}
-
-// process a possible transition, and get the resulting state
-LLFSMState* LLStateDiagram::processTransition(LLFSMState& start_state, LLFSMTransition& transition)
-{
- // look up transition
- //LLFSMState** dest_state = (mStates.getValue(&start_state))->getValue(&transition);
- LLFSMState* dest_state = NULL;
- StateMap::iterator state_it = mStates.find(&start_state);
- if (state_it == mStates.end())
- {
- return NULL;
- }
- Transitions::iterator transition_it = state_it->second.find(&transition);
-
- // try default transitions if state-specific transition not found
- if (transition_it == state_it->second.end())
- {
- dest_state = mDefaultTransitions[&transition];
- }
- else
- {
- dest_state = transition_it->second;
- }
-
- // if we have a destination state...
- if (NULL != dest_state)
- {
- // ...return it...
- return dest_state;
- }
- // ... otherwise ...
- else
- {
- // ...look for default state...
- if (mUseDefaultState)
- {
- // ...return it if we have it...
- return mDefaultState;
- }
- else
- {
- // ...or else we're still in the same state.
- return &start_state;
- }
- }
-}
-
-void LLStateDiagram::setDefaultState(LLFSMState& default_state)
-{
- mUseDefaultState = true;
- mDefaultState = &default_state;
-}
-
-S32 LLStateDiagram::numDeadendStates()
-{
- S32 numDeadends = 0;
- for (StateMap::value_type& state_pair : mStates)
- {
- if (state_pair.second.size() == 0)
- {
- numDeadends++;
- }
- }
- return numDeadends;
-}
-
-bool LLStateDiagram::stateIsValid(LLFSMState& state)
-{
- if (mStates.find(&state) != mStates.end())
- {
- return true;
- }
- return false;
-}
-
-LLFSMState* LLStateDiagram::getState(U32 state_id)
-{
- for (StateMap::value_type& state_pair : mStates)
- {
- if (state_pair.first->getID() == state_id)
- {
- return state_pair.first;
- }
- }
- return NULL;
-}
-
-bool LLStateDiagram::saveDotFile(const std::string& filename)
-{
- LLAPRFile outfile ;
- outfile.open(filename, LL_APR_W);
- apr_file_t* dot_file = outfile.getFileHandle() ;
-
- if (!dot_file)
- {
- LL_WARNS() << "LLStateDiagram::saveDotFile() : Couldn't open " << filename << " to save state diagram." << LL_ENDL;
- return false;
- }
- apr_file_printf(dot_file, "digraph StateMachine {\n\tsize=\"100,100\";\n\tfontsize=40;\n\tlabel=\"Finite State Machine\";\n\torientation=landscape\n\tratio=.77\n");
-
- for (StateMap::value_type& state_pair : mStates)
- {
- apr_file_printf(dot_file, "\t\"%s\" [fontsize=28,shape=box]\n", state_pair.first->getName().c_str());
- }
- apr_file_printf(dot_file, "\t\"All States\" [fontsize=30,style=bold,shape=box]\n");
-
- for (Transitions::value_type& transition_pair : mDefaultTransitions)
- {
- apr_file_printf(dot_file, "\t\"All States\" -> \"%s\" [label = \"%s\",fontsize=24];\n", transition_pair.second->getName().c_str(),
- transition_pair.second->getName().c_str());
- }
-
- if (mDefaultState)
- {
- apr_file_printf(dot_file, "\t\"All States\" -> \"%s\";\n", mDefaultState->getName().c_str());
- }
-
-
- for (StateMap::value_type& state_pair : mStates)
- {
- LLFSMState *state = state_pair.first;
-
- for (Transitions::value_type& transition_pair : state_pair.second)
- {
- std::string state_name = state->getName();
- std::string target_name = transition_pair.second->getName();
- std::string transition_name = transition_pair.first->getName();
- apr_file_printf(dot_file, "\t\"%s\" -> \"%s\" [label = \"%s\",fontsize=24];\n", state->getName().c_str(),
- target_name.c_str(),
- transition_name.c_str());
- }
- }
-
- apr_file_printf(dot_file, "}\n");
-
- return true;
-}
-
-std::ostream& operator<<(std::ostream &s, LLStateDiagram &FSM)
-{
- if (FSM.mDefaultState)
- {
- s << "Default State: " << FSM.mDefaultState->getName() << "\n";
- }
-
- for (LLStateDiagram::Transitions::value_type& transition_pair : FSM.mDefaultTransitions)
- {
- s << "Any State -- " << transition_pair.first->getName()
- << " --> " << transition_pair.second->getName() << "\n";
- }
-
- for (LLStateDiagram::StateMap::value_type& state_pair : FSM.mStates)
- {
- for (LLStateDiagram::Transitions::value_type& transition_pair : state_pair.second)
- {
- s << state_pair.first->getName() << " -- " << transition_pair.first->getName()
- << " --> " << transition_pair.second->getName() << "\n";
- }
- s << "\n";
- }
-
- return s;
-}
-
-//-----------------------------------------------------------------------------
-// LLStateMachine
-//-----------------------------------------------------------------------------
-
-LLStateMachine::LLStateMachine()
-{
- // we haven't received a starting state yet
- mCurrentState = NULL;
- mLastState = NULL;
- mLastTransition = NULL;
- mStateDiagram = NULL;
-}
-
-LLStateMachine::~LLStateMachine()
-{
-
-}
-
-// returns current state
-LLFSMState* LLStateMachine::getCurrentState() const
-{
- return mCurrentState;
-}
-
-// executes current state
-void LLStateMachine::runCurrentState(void *data)
-{
- mCurrentState->execute(data);
-}
-
-// set current state
-bool LLStateMachine::setCurrentState(LLFSMState *initial_state, void* user_data, bool skip_entry)
-{
- llassert(mStateDiagram);
-
- if (mStateDiagram->stateIsValid(*initial_state))
- {
- mLastState = mCurrentState = initial_state;
- if (!skip_entry)
- {
- initial_state->onEntry(user_data);
- }
- return true;
- }
-
- return false;
-}
-
-bool LLStateMachine::setCurrentState(U32 state_id, void* user_data, bool skip_entry)
-{
- llassert(mStateDiagram);
-
- LLFSMState* state = mStateDiagram->getState(state_id);
-
- if (state)
- {
- mLastState = mCurrentState = state;
- if (!skip_entry)
- {
- state->onEntry(user_data);
- }
- return true;
- }
-
- return false;
-}
-
-void LLStateMachine::processTransition(LLFSMTransition& transition, void* user_data)
-{
- llassert(mStateDiagram);
-
- if (NULL == mCurrentState)
- {
- LL_WARNS() << "mCurrentState == NULL; aborting processTransition()" << LL_ENDL;
- return;
- }
-
- LLFSMState* new_state = mStateDiagram->processTransition(*mCurrentState, transition);
-
- if (NULL == new_state)
- {
- LL_WARNS() << "new_state == NULL; aborting processTransition()" << LL_ENDL;
- return;
- }
-
- mLastTransition = &transition;
- mLastState = mCurrentState;
-
- if (*mCurrentState != *new_state)
- {
- mCurrentState->onExit(user_data);
- mCurrentState = new_state;
- mCurrentState->onEntry(user_data);
-#if FSM_PRINT_STATE_TRANSITIONS
- LL_INFOS() << "Entering state " << mCurrentState->getName() <<
- " on transition " << transition.getName() << " from state " <<
- mLastState->getName() << LL_ENDL;
-#endif
- }
-}
-
-void LLStateMachine::setStateDiagram(LLStateDiagram* diagram)
-{
- mStateDiagram = diagram;
-}
diff --git a/indra/llcharacter/llstatemachine.h b/indra/llcharacter/llstatemachine.h
deleted file mode 100644
index 9a33798d96..0000000000
--- a/indra/llcharacter/llstatemachine.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/**
- * @file llstatemachine.h
- * @brief LLStateMachine class header file.
- *
- * $LicenseInfo:firstyear=2001&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$
- */
-
-#ifndef LL_LLSTATEMACHINE_H
-#define LL_LLSTATEMACHINE_H
-
-#include <string>
-
-#include "llerror.h"
-#include <map>
-
-class LLUniqueID
-{
- friend bool operator==(const LLUniqueID &a, const LLUniqueID &b);
- friend bool operator!=(const LLUniqueID &a, const LLUniqueID &b);
-protected:
- static U32 sNextID;
- U32 mId;
-public:
- LLUniqueID(){mId = sNextID++;}
- virtual ~LLUniqueID(){}
- U32 getID() {return mId;}
-};
-
-class LLFSMTransition : public LLUniqueID
-{
-public:
- LLFSMTransition() : LLUniqueID(){};
- virtual std::string getName()const { return "unnamed"; }
-};
-
-class LLFSMState : public LLUniqueID
-{
-public:
- LLFSMState() : LLUniqueID(){};
- virtual void onEntry(void *){};
- virtual void onExit(void *){};
- virtual void execute(void *){};
- virtual std::string getName() const { return "unnamed"; }
-};
-
-class LLStateDiagram
-{
-typedef std::map<LLFSMTransition*, LLFSMState*> Transitions;
-
-friend std::ostream& operator<<(std::ostream &s, LLStateDiagram &FSM);
-friend class LLStateMachine;
-
-protected:
- typedef std::map<LLFSMState*, Transitions> StateMap;
- StateMap mStates;
- Transitions mDefaultTransitions;
- LLFSMState* mDefaultState;
- bool mUseDefaultState;
-
-public:
- LLStateDiagram();
- virtual ~LLStateDiagram();
-
-protected:
- // add a state to the state graph, executed implicitly when adding transitions
- bool addState(LLFSMState *state);
-
- // add a directed transition between 2 states
- bool addTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition);
-
- // add an undirected transition between 2 states
- bool addUndirectedTransition(LLFSMState& start_state, LLFSMState& end_state, LLFSMTransition& transition);
-
- // add a transition that is taken if none other exist
- void addDefaultTransition(LLFSMState& end_state, LLFSMTransition& transition);
-
- // process a possible transition, and get the resulting state
- LLFSMState* processTransition(LLFSMState& start_state, LLFSMTransition& transition);
-
- // add a transition that exists for every state
- void setDefaultState(LLFSMState& default_state);
-
- // return total number of states with no outgoing transitions
- S32 numDeadendStates();
-
- // does this state exist in the state diagram?
- bool stateIsValid(LLFSMState& state);
-
- // get a state pointer by ID
- LLFSMState* getState(U32 state_id);
-
-public:
- // save the graph in a DOT file for rendering and visualization
- bool saveDotFile(const std::string& filename);
-};
-
-class LLStateMachine
-{
-protected:
- LLFSMState* mCurrentState;
- LLFSMState* mLastState;
- LLFSMTransition* mLastTransition;
- LLStateDiagram* mStateDiagram;
-
-public:
- LLStateMachine();
- virtual ~LLStateMachine();
-
- // set state diagram
- void setStateDiagram(LLStateDiagram* diagram);
-
- // process this transition
- void processTransition(LLFSMTransition &transition, void* user_data);
-
- // returns current state
- LLFSMState* getCurrentState() const;
-
- // execute current state
- void runCurrentState(void *data);
-
- // set state by state pointer
- bool setCurrentState(LLFSMState *initial_state, void* user_data, bool skip_entry = true);
-
- // set state by unique ID
- bool setCurrentState(U32 state_id, void* user_data, bool skip_entry = true);
-};
-
-#endif //_LL_LLSTATEMACHINE_H
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index cb3f0d7842..f2d19854b0 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -67,6 +67,7 @@ set(llcommon_SOURCE_FILES
llmetricperformancetester.cpp
llmortician.cpp
llmutex.cpp
+ llpointer.cpp
llptrto.cpp
llpredicate.cpp
llprocess.cpp
diff --git a/indra/llcommon/llpointer.cpp b/indra/llcommon/llpointer.cpp
new file mode 100755
index 0000000000..1bb7055b3a
--- /dev/null
+++ b/indra/llcommon/llpointer.cpp
@@ -0,0 +1,43 @@
+/**
+ * @file llpointer.cpp
+ * @author Nat Goodspeed
+ * @date 2024-09-26
+ * @brief Implementation for llpointer.
+ *
+ * $LicenseInfo:firstyear=2024&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2024, 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$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llpointer.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llerror.h"
+
+void LLPointerBase::wild_dtor(std::string_view msg)
+{
+// LL_WARNS() << msg << LL_ENDL;
+ llassert_msg(false, msg);
+}
diff --git a/indra/llcommon/llpointer.h b/indra/llcommon/llpointer.h
index 048547e4cc..d2dcf530e5 100644
--- a/indra/llcommon/llpointer.h
+++ b/indra/llcommon/llpointer.h
@@ -26,8 +26,9 @@
#ifndef LLPOINTER_H
#define LLPOINTER_H
-#include "llerror.h" // *TODO: consider eliminating this
-#include "llmutex.h"
+#include <functional>
+#include <string_view>
+#include <utility> // std::swap()
//----------------------------------------------------------------------------
// RefCount objects should generally only be accessed by way of LLPointer<>'s
@@ -42,8 +43,18 @@
//----------------------------------------------------------------------------
+class LLPointerBase
+{
+protected:
+ // alert the coder that a referenced type's destructor did something very
+ // strange -- this is in a non-template base class so we can hide the
+ // implementation in llpointer.cpp
+ static void wild_dtor(std::string_view msg);
+};
+
// Note: relies on Type having ref() and unref() methods
-template <class Type> class LLPointer
+template <class Type>
+class LLPointer: public LLPointerBase
{
public:
template<typename Subclass>
@@ -60,6 +71,13 @@ public:
ref();
}
+ // Even though the template constructors below accepting
+ // (const LLPointer<Subclass>&) and (LLPointer<Subclass>&&) appear to
+ // subsume these specific (const LLPointer<Type>&) and (LLPointer<Type>&&)
+ // constructors, the compiler recognizes these as The Copy Constructor and
+ // The Move Constructor, respectively. In other words, even in the
+ // presence of the LLPointer<Subclass> constructors, we still must specify
+ // the LLPointer<Type> constructors.
LLPointer(const LLPointer<Type>& ptr) :
mPointer(ptr.mPointer)
{
@@ -98,39 +116,52 @@ public:
const Type& operator*() const { return *mPointer; }
Type& operator*() { return *mPointer; }
- operator BOOL() const { return (mPointer != nullptr); }
operator bool() const { return (mPointer != nullptr); }
bool operator!() const { return (mPointer == nullptr); }
bool isNull() const { return (mPointer == nullptr); }
bool notNull() const { return (mPointer != nullptr); }
operator Type*() const { return mPointer; }
- bool operator !=(Type* ptr) const { return (mPointer != ptr); }
- bool operator ==(Type* ptr) const { return (mPointer == ptr); }
- bool operator ==(const LLPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
- bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
- bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
+ template <typename Type1>
+ bool operator !=(Type1* ptr) const { return (mPointer != ptr); }
+ template <typename Type1>
+ bool operator ==(Type1* ptr) const { return (mPointer == ptr); }
+ template <typename Type1>
+ bool operator !=(const LLPointer<Type1>& ptr) const { return (mPointer != ptr.mPointer); }
+ template <typename Type1>
+ bool operator ==(const LLPointer<Type1>& ptr) const { return (mPointer == ptr.mPointer); }
+ bool operator < (const LLPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
+ bool operator > (const LLPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
LLPointer<Type>& operator =(Type* ptr)
{
- assign(ptr);
+ // copy-and-swap idiom, see http://gotw.ca/gotw/059.htm
+ LLPointer temp(ptr);
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
+ // Even though the template assignment operators below accepting
+ // (const LLPointer<Subclass>&) and (LLPointer<Subclass>&&) appear to
+ // subsume these specific (const LLPointer<Type>&) and (LLPointer<Type>&&)
+ // assignment operators, the compiler recognizes these as Copy Assignment
+ // and Move Assignment, respectively. In other words, even in the presence
+ // of the LLPointer<Subclass> assignment operators, we still must specify
+ // the LLPointer<Type> operators.
LLPointer<Type>& operator =(const LLPointer<Type>& ptr)
{
- assign(ptr);
+ LLPointer temp(ptr);
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
LLPointer<Type>& operator =(LLPointer<Type>&& ptr)
{
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
+ LLPointer temp(std::move(ptr));
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
@@ -138,28 +169,32 @@ public:
template<typename Subclass>
LLPointer<Type>& operator =(const LLPointer<Subclass>& ptr)
{
- assign(ptr.get());
+ LLPointer temp(ptr);
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
template<typename Subclass>
LLPointer<Type>& operator =(LLPointer<Subclass>&& ptr)
{
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
+ LLPointer temp(std::move(ptr));
+ using std::swap; // per Swappable convention
+ swap(*this, temp);
return *this;
}
// Just exchange the pointers, which will not change the reference counts.
static void swap(LLPointer<Type>& a, LLPointer<Type>& b)
{
- Type* temp = a.mPointer;
- a.mPointer = b.mPointer;
- b.mPointer = temp;
+ using std::swap; // per Swappable convention
+ swap(a.mPointer, b.mPointer);
+ }
+
+ // Put swap() overload in the global namespace, per Swappable convention
+ friend void swap(LLPointer<Type>& a, LLPointer<Type>& b)
+ {
+ LLPointer<Type>::swap(a, b);
}
protected:
@@ -184,191 +219,19 @@ protected:
temp->unref();
if (mPointer != nullptr)
{
- LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
+ wild_dtor("Unreference did assignment to non-NULL because of destructor");
unref();
}
}
}
#endif // LL_LIBRARY_INCLUDE
- void assign(const LLPointer<Type>& ptr)
- {
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ref();
- }
- }
-
protected:
Type* mPointer;
};
-template <class Type> class LLConstPointer
-{
- template<typename Subclass>
- friend class LLConstPointer;
-public:
- LLConstPointer() :
- mPointer(nullptr)
- {
- }
-
- LLConstPointer(const Type* ptr) :
- mPointer(ptr)
- {
- ref();
- }
-
- LLConstPointer(const LLConstPointer<Type>& ptr) :
- mPointer(ptr.mPointer)
- {
- ref();
- }
-
- LLConstPointer(LLConstPointer<Type>&& ptr) noexcept
- {
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
-
- // support conversion up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
- template<typename Subclass>
- LLConstPointer(const LLConstPointer<Subclass>& ptr) :
- mPointer(ptr.get())
- {
- ref();
- }
-
- template<typename Subclass>
- LLConstPointer(LLConstPointer<Subclass>&& ptr) noexcept :
- mPointer(ptr.get())
- {
- ptr.mPointer = nullptr;
- }
-
- ~LLConstPointer()
- {
- unref();
- }
-
- const Type* get() const { return mPointer; }
- const Type* operator->() const { return mPointer; }
- const Type& operator*() const { return *mPointer; }
-
- operator BOOL() const { return (mPointer != nullptr); }
- operator bool() const { return (mPointer != nullptr); }
- bool operator!() const { return (mPointer == nullptr); }
- bool isNull() const { return (mPointer == nullptr); }
- bool notNull() const { return (mPointer != nullptr); }
-
- operator const Type*() const { return mPointer; }
- bool operator !=(const Type* ptr) const { return (mPointer != ptr); }
- bool operator ==(const Type* ptr) const { return (mPointer == ptr); }
- bool operator ==(const LLConstPointer<Type>& ptr) const { return (mPointer == ptr.mPointer); }
- bool operator < (const LLConstPointer<Type>& ptr) const { return (mPointer < ptr.mPointer); }
- bool operator > (const LLConstPointer<Type>& ptr) const { return (mPointer > ptr.mPointer); }
-
- LLConstPointer<Type>& operator =(const Type* ptr)
- {
- if( mPointer != ptr )
- {
- unref();
- mPointer = ptr;
- ref();
- }
-
- return *this;
- }
-
- LLConstPointer<Type>& operator =(const LLConstPointer<Type>& ptr)
- {
- if( mPointer != ptr.mPointer )
- {
- unref();
- mPointer = ptr.mPointer;
- ref();
- }
- return *this;
- }
-
- LLConstPointer<Type>& operator =(LLConstPointer<Type>&& ptr)
- {
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
- return *this;
- }
-
- // support assignment up the type hierarchy. See Item 45 in Effective C++, 3rd Ed.
- template<typename Subclass>
- LLConstPointer<Type>& operator =(const LLConstPointer<Subclass>& ptr)
- {
- if( mPointer != ptr.get() )
- {
- unref();
- mPointer = ptr.get();
- ref();
- }
- return *this;
- }
-
- template<typename Subclass>
- LLConstPointer<Type>& operator =(LLConstPointer<Subclass>&& ptr)
- {
- if (mPointer != ptr.mPointer)
- {
- unref();
- mPointer = ptr.mPointer;
- ptr.mPointer = nullptr;
- }
- return *this;
- }
-
- // Just exchange the pointers, which will not change the reference counts.
- static void swap(LLConstPointer<Type>& a, LLConstPointer<Type>& b)
- {
- const Type* temp = a.mPointer;
- a.mPointer = b.mPointer;
- b.mPointer = temp;
- }
-
-protected:
-#ifdef LL_LIBRARY_INCLUDE
- void ref();
- void unref();
-#else // LL_LIBRARY_INCLUDE
- void ref()
- {
- if (mPointer)
- {
- mPointer->ref();
- }
- }
-
- void unref()
- {
- if (mPointer)
- {
- const Type *temp = mPointer;
- mPointer = nullptr;
- temp->unref();
- if (mPointer != nullptr)
- {
- LL_WARNS() << "Unreference did assignment to non-NULL because of destructor" << LL_ENDL;
- unref();
- }
- }
- }
-#endif // LL_LIBRARY_INCLUDE
-
-protected:
- const Type* mPointer;
-};
+template <typename Type>
+using LLConstPointer = LLPointer<const Type>;
template<typename Type>
class LLCopyOnWritePointer : public LLPointer<Type>
@@ -418,38 +281,26 @@ private:
bool mStayUnique;
};
-template<typename Type>
-bool operator!=(Type* lhs, const LLPointer<Type>& rhs)
+template<typename Type0, typename Type1>
+bool operator!=(Type0* lhs, const LLPointer<Type1>& rhs)
{
return (lhs != rhs.get());
}
-template<typename Type>
-bool operator==(Type* lhs, const LLPointer<Type>& rhs)
+template<typename Type0, typename Type1>
+bool operator==(Type0* lhs, const LLPointer<Type1>& rhs)
{
return (lhs == rhs.get());
}
-// boost hash adapter
-template <class Type>
-struct boost::hash<LLPointer<Type>>
-{
- typedef LLPointer<Type> argument_type;
- typedef std::size_t result_type;
- result_type operator()(argument_type const& s) const
- {
- return (std::size_t) s.get();
- }
-};
-
-// Adapt boost hash to std hash
+// Specialize for std::hash
namespace std
{
template<class Type> struct hash<LLPointer<Type>>
{
std::size_t operator()(LLPointer<Type> const& s) const noexcept
{
- return boost::hash<LLPointer<Type>>()(s);
+ return std::hash<Type*>()(s.get());
}
};
}
diff --git a/indra/llcommon/workqueue.cpp b/indra/llcommon/workqueue.cpp
index 7efaebd569..4db44ff2a6 100644
--- a/indra/llcommon/workqueue.cpp
+++ b/indra/llcommon/workqueue.cpp
@@ -276,12 +276,30 @@ bool LL::WorkQueue::done()
bool LL::WorkQueue::post(const Work& callable)
{
- return mQueue.pushIfOpen(callable);
+ try
+ {
+ return mQueue.pushIfOpen(callable);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("LLCoros") << "Bad memory allocation in WorkQueue::post" << LL_ENDL;
+ return false;
+ }
}
bool LL::WorkQueue::tryPost(const Work& callable)
{
- return mQueue.tryPush(callable);
+ try
+ {
+ return mQueue.tryPush(callable);
+ }
+ catch (std::bad_alloc&)
+ {
+ LLError::LLUserWarningMsg::showOutOfMemory();
+ LL_ERRS("LLCoros") << "Bad memory allocation in WorkQueue::tryPost" << LL_ENDL;
+ return false;
+ }
}
LL::WorkQueue::Work LL::WorkQueue::pop_()
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 16042e573a..8569c28528 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -27,10 +27,11 @@
#ifndef LL_LLIMAGE_H
#define LL_LLIMAGE_H
-#include "lluuid.h"
-#include "llstring.h"
+#include "llmutex.h"
#include "llpointer.h"
+#include "llstring.h"
#include "lltrace.h"
+#include "lluuid.h"
constexpr S32 MIN_IMAGE_MIP = 2; // 4x4, only used for expand/contract power of 2
constexpr S32 MAX_IMAGE_MIP = 12; // 4096x4096
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp
index bb0c94d513..d8f649140f 100644
--- a/indra/llmath/llvolumemgr.cpp
+++ b/indra/llmath/llvolumemgr.cpp
@@ -25,6 +25,7 @@
#include "linden_common.h"
+#include "llmutex.h"
#include "llvolumemgr.h"
#include "llvolume.h"
diff --git a/indra/llmath/v3math.h b/indra/llmath/v3math.h
index 196ecdcf7d..0e11dca876 100644
--- a/indra/llmath/v3math.h
+++ b/indra/llmath/v3math.h
@@ -155,6 +155,7 @@ class LLVector3
friend const LLVector3& operator*=(LLVector3 &a, const LLVector3 &b); // Returns a * b;
friend const LLVector3& operator*=(LLVector3 &a, F32 k); // Return a times scaler k
friend const LLVector3& operator/=(LLVector3 &a, F32 k); // Return a divided by scaler k
+ friend const LLVector3& operator/=(LLVector3& a, const LLVector3& b);
friend const LLVector3& operator*=(LLVector3 &a, const LLQuaternion &b); // Returns a * b;
friend LLVector3 operator-(const LLVector3 &a); // Return vector -a
@@ -460,6 +461,14 @@ inline const LLVector3& operator/=(LLVector3& a, F32 k)
return a;
}
+inline const LLVector3& operator/=(LLVector3& a, const LLVector3& b)
+{
+ a.mV[VX] /= b.mV[VX];
+ a.mV[VY] /= b.mV[VY];
+ a.mV[VZ] /= b.mV[VZ];
+ return a;
+}
+
inline LLVector3 operator-(const LLVector3& a)
{
return LLVector3(-a.mV[VX], -a.mV[VY], -a.mV[VZ]);
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 31bc76344c..c3e3e19ee9 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -109,11 +109,12 @@ public:
PARAMS_EXTENDED_MESH = 0x70,
PARAMS_RENDER_MATERIAL = 0x80,
PARAMS_REFLECTION_PROBE = 0x90,
+ PARAMS_MAX = PARAMS_REFLECTION_PROBE,
};
public:
U16 mType;
- virtual ~LLNetworkData() {};
+ virtual ~LLNetworkData() = default;
virtual bool pack(LLDataPacker &dp) const = 0;
virtual bool unpack(LLDataPacker &dp) = 0;
virtual bool operator==(const LLNetworkData& data) const = 0;
@@ -319,7 +320,7 @@ public:
bool fromLLSD(LLSD& sd);
void setSculptTexture(const LLUUID& texture_id, U8 sculpt_type);
- LLUUID getSculptTexture() const { return mSculptTexture; }
+ const LLUUID& getSculptTexture() const { return mSculptTexture; }
U8 getSculptType() const { return mSculptType; }
};
@@ -340,10 +341,10 @@ public:
bool fromLLSD(LLSD& sd);
void setLightTexture(const LLUUID& id) { mLightTexture = id; }
- LLUUID getLightTexture() const { return mLightTexture; }
+ const LLUUID& getLightTexture() const { return mLightTexture; }
bool isLightSpotlight() const { return mLightTexture.notNull(); }
void setParams(const LLVector3& params) { mParams = params; }
- LLVector3 getParams() const { return mParams; }
+ const LLVector3& getParams() const { return mParams; }
};
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index ab88e4868e..e26c53bc2e 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -1698,25 +1698,64 @@ void LLRender::vertex3f(const GLfloat& x, const GLfloat& y, const GLfloat& z)
return;
}
- if (mUIOffset.empty())
+ LLVector4a vert(x, y, z);
+ transform(vert);
+ mVerticesp[mCount] = vert;
+
+ mCount++;
+ mVerticesp[mCount] = mVerticesp[mCount-1];
+ mColorsp[mCount] = mColorsp[mCount-1];
+ mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+}
+
+void LLRender::transform(LLVector3& vert)
+{
+ if (!mUIOffset.empty())
{
- mVerticesp[mCount].set(x,y,z);
+ vert += LLVector3(mUIOffset.back().getF32ptr());
+ vert *= LLVector3(mUIScale.back().getF32ptr());
}
- else
+}
+
+void LLRender::transform(LLVector4a& vert)
+{
+ if (!mUIOffset.empty())
{
- LLVector4a vert(x, y, z);
vert.add(mUIOffset.back());
vert.mul(mUIScale.back());
- mVerticesp[mCount] = vert;
}
+}
- mCount++;
- mVerticesp[mCount] = mVerticesp[mCount-1];
- mColorsp[mCount] = mColorsp[mCount-1];
- mTexcoordsp[mCount] = mTexcoordsp[mCount-1];
+void LLRender::untransform(LLVector3& vert)
+{
+ if (!mUIOffset.empty())
+ {
+ vert /= LLVector3(mUIScale.back().getF32ptr());
+ vert -= LLVector3(mUIOffset.back().getF32ptr());
+ }
+}
+
+void LLRender::batchTransform(LLVector4a* verts, U32 vert_count)
+{
+ if (!mUIOffset.empty())
+ {
+ const LLVector4a& offset = mUIOffset.back();
+ const LLVector4a& scale = mUIScale.back();
+
+ for (U32 i = 0; i < vert_count; ++i)
+ {
+ verts[i].add(offset);
+ verts[i].mul(scale);
+ }
+ }
+}
+
+void LLRender::vertexBatchPreTransformed(const std::vector<LLVector4a>& verts)
+{
+ vertexBatchPreTransformed(verts.data(), narrow(verts.size()));
}
-void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(const LLVector4a* verts, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
@@ -1737,7 +1776,7 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count)
mVerticesp[mCount] = mVerticesp[mCount-1];
}
-void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
@@ -1761,7 +1800,7 @@ void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32
}
}
-void LLRender::vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U* colors, S32 vert_count)
+void LLRender::vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, const LLColor4U* colors, S32 vert_count)
{
if (mCount + vert_count > 4094)
{
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index 9c17cf3470..51301c7cac 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -449,9 +449,16 @@ public:
void diffuseColor4ubv(const U8* c);
void diffuseColor4ub(U8 r, U8 g, U8 b, U8 a);
- void vertexBatchPreTransformed(LLVector4a* verts, S32 vert_count);
- void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, S32 vert_count);
- void vertexBatchPreTransformed(LLVector4a* verts, LLVector2* uvs, LLColor4U*, S32 vert_count);
+ void transform(LLVector3& vert);
+ void transform(LLVector4a& vert);
+ void untransform(LLVector3& vert);
+
+ void batchTransform(LLVector4a* verts, U32 vert_count);
+
+ void vertexBatchPreTransformed(const std::vector<LLVector4a>& verts);
+ void vertexBatchPreTransformed(const LLVector4a* verts, S32 vert_count);
+ void vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, S32 vert_count);
+ void vertexBatchPreTransformed(const LLVector4a* verts, const LLVector2* uvs, const LLColor4U*, S32 vert_count);
void setColorMask(bool writeColor, bool writeAlpha);
void setColorMask(bool writeColorR, bool writeColorG, bool writeColorB, bool writeAlpha);
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index b534c8d4e8..ef62666918 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -122,6 +122,7 @@ LLLineEditor::Params::Params()
LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
: LLUICtrl(p),
+ mDefaultText(p.default_text),
mMaxLengthBytes(p.max_length.bytes),
mMaxLengthChars(p.max_length.chars),
mCursorPos( 0 ),
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 3f762822ee..6384bfdc5f 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -202,6 +202,7 @@ public:
void setLabel(const LLStringExplicit &new_label) { mLabel = new_label; }
const std::string& getLabel() { return mLabel.getString(); }
+ void setDefaultText() { setText(mDefaultText); }
void setText(const LLStringExplicit &new_text);
const std::string& getText() const override { return mText.getString(); }
@@ -347,6 +348,7 @@ protected:
LLFontVertexBuffer mFontBufferSelection;
LLFontVertexBuffer mFontBufferPostSelection;
LLFontVertexBuffer mFontBufferLabel;
+ std::string mDefaultText;
S32 mMaxLengthBytes; // Max length of the UTF8 string in bytes
S32 mMaxLengthChars; // Maximum number of characters in the string
S32 mCursorPos; // I-beam is just after the mCursorPos-th character.
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index d56c459560..c7c7435be2 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -93,6 +93,7 @@
#include "llinitparam.h"
#include "llinstancetracker.h"
#include "llmortician.h"
+#include "llmutex.h"
#include "llnotificationptr.h"
#include "llpointer.h"
#include "llrefcount.h"
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index b459c67dad..558ce6a7fd 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -3185,6 +3185,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS
if (cell_p.width.isProvided())
{
new_column.width.pixel_width = cell_p.width;
+ new_column.width.pixel_width.choose();
}
addColumn(new_column);
columnp = mColumns[column];
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index fcdf3782ae..7689b93374 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -581,7 +581,7 @@ S32 LLTextEditor::indentLine( S32 pos, S32 spaces )
LLWString wtext = getWText();
if (wtext[pos] == ' ')
{
- delta_spaces += remove( pos, 1, false );
+ delta_spaces -= remove( pos, 1, false );
}
}
}
diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp
index d1bae49784..8e08239ee6 100644
--- a/indra/llwebrtc/llwebrtc.cpp
+++ b/indra/llwebrtc/llwebrtc.cpp
@@ -814,6 +814,7 @@ LLWebRTCPeerConnectionImpl::~LLWebRTCPeerConnectionImpl()
{
mSignalingObserverList.clear();
mDataObserverList.clear();
+ mPeerConnectionFactory.release();
if (mPendingJobs > 0)
{
RTC_LOG(LS_ERROR) << __FUNCTION__ << "Destroying a connection that has " << std::to_string(mPendingJobs) << " unfinished jobs that might cause workers to crash";
@@ -877,7 +878,6 @@ void LLWebRTCPeerConnectionImpl::terminate()
}
mPendingJobs--;
});
- mPeerConnectionFactory.release();
}
void LLWebRTCPeerConnectionImpl::setSignalingObserver(LLWebRTCSignalingObserver *observer) { mSignalingObserverList.emplace_back(observer); }
@@ -1004,6 +1004,7 @@ bool LLWebRTCPeerConnectionImpl::initializeConnection(const LLWebRTCPeerConnecti
}
webrtc::PeerConnectionInterface::RTCOfferAnswerOptions offerOptions;
+ this->AddRef(); // CreateOffer will deref this when it's done. Without this, the callbacks never get called.
mPeerConnection->CreateOffer(this, offerOptions);
mPendingJobs--;
});
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 24d2facc4c..8a95ab2cc2 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -157,9 +157,12 @@ LLControlVariable::LLControlVariable(const std::string& name, eControlType type,
{
if ((persist != PERSIST_NO) && mComment.empty())
{
- // File isn't actually missing, but something is wrong with it
- // so the main point is to warn user to reinstall
- LLError::LLUserWarningMsg::showMissingFiles();
+ std::string error_string =
+ "Second Life failed to initialize settings. Setting " + mName + " is invalid. "
+ "Either settings' files were supplied incorrectly or default files were corrupted."
+ "\n\nPlease reinstall viewer from https://secondlife.com/support/downloads/ and "
+ "contact https://support.secondlife.com if issue persists after reinstall.";
+ LLError::LLUserWarningMsg::show(error_string);
LL_ERRS() << "Must supply a comment for control " << mName << LL_ENDL;
}
//Push back versus setValue'ing here, since we don't want to call a signal yet
@@ -990,7 +993,7 @@ U32 LLControlGroup::saveToFile(const std::string& filename, bool nondefault_only
return num_saved;
}
-U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values)
+U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values, bool error_when_no_comment)
{
LLSD settings;
llifstream infile;
@@ -1105,10 +1108,26 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
}
}
+ std::string comment = control_map["Comment"].asString();
+ if (!error_when_no_comment
+ && !set_default_values
+ && comment.empty())
+ {
+ // Only error for default settings that should remind the developer to provide comments
+ // and otherwise indicate a problem with viewer's files.
+ // But permit this minor transgression in user's files.
+ // Otherwise user might have a hard time figuring out source of the error or how to fix it.
+ // Instead make setting to not persist so that unrecognized invalid settings won't be saved
+ // for the next run.
+ persist = LLControlVariable::PERSIST_NO;
+ comment = "Comment not provided, setting won't persist";
+ LL_WARNS() << "Control " << name << " is missing a comment value. Setting will be marked as PERSIST_NO" << LL_ENDL;
+ }
+
declareControl(name,
typeStringToEnum(control_map["Type"].asString()),
control_map["Value"],
- control_map["Comment"].asString(),
+ comment,
persist,
hidefromsettingseditor
);
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index da7268bf45..c9bd0a8a32 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -278,7 +278,7 @@ public:
// as the given type.
U32 loadFromFileLegacy(const std::string& filename, bool require_declaration = true, eControlType declare_as = TYPE_STRING);
U32 saveToFile(const std::string& filename, bool nondefault_only);
- U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true);
+ U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true, bool error_when_no_comment = true);
void resetToDefaults();
void incrCount(std::string_view name);
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 429dc57af3..4703009f54 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-7.2.3
+2026.01.0
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 674f459193..5d82b38c2a 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4591,6 +4591,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>MapShowGridCoords</key>
+ <map>
+ <key>Comment</key>
+ <string>Shows/hides the grid coordinates of each region on the world map.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>MiniMapAutoCenter</key>
<map>
<key>Comment</key>
@@ -7368,7 +7379,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>32.0</real>
+ <real>48.0</real>
</map>
<key>RenderCPUBasis</key>
<map>
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index b2c66b1bac..d884b32ac0 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -975,6 +975,10 @@ void LLAgentCamera::cameraZoomIn(const F32 fraction)
new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
}
}
+ else
+ {
+ new_distance = llmin(new_distance, getCameraMaxZoomDistance());
+ }
mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
}
@@ -1035,6 +1039,10 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters)
new_distance = llclamp(new_distance, APPEARANCE_MIN_ZOOM, APPEARANCE_MAX_ZOOM);
}
}
+ else
+ {
+ new_distance = llmin(new_distance, getCameraMaxZoomDistance());
+ }
// Compute new camera offset
mCameraFocusOffsetTarget = new_distance * camera_offset_unit;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6058973176..8bf418aa44 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2454,7 +2454,10 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, file.file_name());
}
- if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
+ // Be softer for files in the user's folders, user can't just reinstall those
+ bool error_when_no_comment = !set_defaults && location_key != "User";
+
+ if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent, error_when_no_comment))
{ // success!
LL_INFOS("Settings") << "Loaded settings file " << full_settings_path << LL_ENDL;
}
@@ -4499,7 +4502,19 @@ void LLAppViewer::purgeCacheImmediate()
{
LL_INFOS("AppCache") << "Purging Object Cache and Texture Cache immediately..." << LL_ENDL;
LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE, false);
- LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true);
+ if (LLVOCache::instanceExists())
+ {
+ LLVOCache::getInstance()->removeCache(LL_PATH_CACHE, true);
+ }
+ else if (!mSecondInstance)
+ {
+ // LLVOCache requires parameters to be initialized, if it's not there, try manually
+ std::string mask = "*";
+ std::string cache_dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "objectcache");
+ LL_INFOS() << "Removing cache at " << cache_dir << LL_ENDL;
+ gDirUtilp->deleteFilesInDir(cache_dir, mask); //delete all files
+ LLFile::remove(cache_dir);
+ }
}
std::string LLAppViewer::getSecondLifeTitle() const
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 6f6b89ea81..fb1426a235 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -29,8 +29,6 @@
#include "llavataractions.h"
-#include "boost/lambda/lambda.hpp" // for lambda::constant
-
#include "llavatarnamecache.h" // IDEVO
#include "llsd.h"
#include "llnotifications.h"
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 322ee90541..da9378ad12 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -723,9 +723,13 @@ F32 LLDrawable::updateXform(bool undamped)
mXform.setRotation(target_rot);
mXform.setScale(LLVector3(1,1,1)); //no scale in drawable transforms (IT'S A RULE!)
mXform.updateMatrix();
- if (isRoot() && mVObjp->isAnimatedObject() && mVObjp->getControlAvatar())
+ if (isRoot() && mVObjp->isAnimatedObject())
{
- mVObjp->getControlAvatar()->matchVolumeTransform();
+ LLControlAvatar* cav = mVObjp->getControlAvatar();
+ if (cav)
+ {
+ cav->matchVolumeTransform();
+ }
}
if (mSpatialBridge)
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index bc45734e66..9d1b11880b 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -267,7 +267,7 @@ void LLDrawPoolAlpha::forwardRender(bool rigged)
gGL.setColorMask(true, false);
- if (!rigged)
+ if (!rigged && getType() == LLDrawPoolAlpha::POOL_ALPHA_POST_WATER)
{ //render "highlight alpha" on final non-rigged pass
// NOTE -- hacky call here protected by !rigged instead of alongside "forwardRender"
// so renderDebugAlpha is executed while gls_pipeline_alpha and depth GL state
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 37802fa175..b9c84c10cf 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -2372,7 +2372,11 @@ F32 LLFace::adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius
//the above calculation is too expensive
//the below is a good estimation: bounding box of the bounding sphere:
- F32 alpha = 0.5f * (radius + screen_radius - d) / radius ;
+ F32 alpha = 1.f;
+ if (!is_approx_zero(radius)) // radius can be something like -1e-10
+ {
+ alpha = 0.5f * (radius + screen_radius - d) / radius;
+ }
alpha = llclamp(alpha, 0.f, 1.f) ;
return alpha * alpha ;
}
diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp
index a42c94f049..bc1f3045bb 100644
--- a/indra/newview/llfloatereditenvironmentbase.cpp
+++ b/indra/newview/llfloatereditenvironmentbase.cpp
@@ -262,7 +262,7 @@ void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, cons
}
else if (mInventoryItem)
{
- const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
LLUUID parent_id = mInventoryItem->getParentUUID();
if (marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(mInventoryItem->getUUID(), gInventory.getLibraryRootFolderID()))
{
diff --git a/indra/newview/llfloatermarketplace.cpp b/indra/newview/llfloatermarketplace.cpp
index 7316d7617d..2a67e75fec 100644
--- a/indra/newview/llfloatermarketplace.cpp
+++ b/indra/newview/llfloatermarketplace.cpp
@@ -39,6 +39,26 @@ LLFloaterMarketplace::~LLFloaterMarketplace()
{
}
+void LLFloaterMarketplace::onOpen(const LLSD& key)
+{
+ Params params(key);
+
+ if (!params.validateBlock())
+ {
+ closeFloater();
+ return;
+ }
+
+ if (params.url().empty())
+ {
+ openMarketplace();
+ }
+ else
+ {
+ openMarketplaceURL(params.url);
+ }
+}
+
// just to override LLFloaterWebContent
void LLFloaterMarketplace::onClose(bool app_quitting)
{
@@ -68,3 +88,18 @@ void LLFloaterMarketplace::openMarketplace()
mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
}
}
+
+void LLFloaterMarketplace::openMarketplaceURL(const std::string& url)
+{
+ if (mCurrentURL != url)
+ {
+ mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
+ }
+}
+
+// static
+bool LLFloaterMarketplace::isMarketplaceURL(const std::string& url)
+{
+ static LLCachedControl<std::string> marketplace_url(gSavedSettings, "MarketplaceURL", "https://marketplace.secondlife.com/");
+ return url.starts_with(marketplace_url());
+}
diff --git a/indra/newview/llfloatermarketplace.h b/indra/newview/llfloatermarketplace.h
index 9524c94eee..17979dae90 100644
--- a/indra/newview/llfloatermarketplace.h
+++ b/indra/newview/llfloatermarketplace.h
@@ -36,11 +36,14 @@ class LLFloaterMarketplace:
public:
void openMarketplace();
+ void openMarketplaceURL(const std::string& url);
+ bool static isMarketplaceURL(const std::string& url);
private:
LLFloaterMarketplace(const LLSD& key);
~LLFloaterMarketplace();
bool postBuild() override;
+ void onOpen(const LLSD& key) override;
void onClose(bool app_quitting) override;
};
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index f20fea01c5..dfd023e424 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -29,6 +29,7 @@
#include "llfloatermarketplacelistings.h"
+#include "llcallbacklist.h"
#include "llfloaterreg.h"
#include "llfiltereditor.h"
#include "llfolderview.h"
@@ -231,7 +232,7 @@ void LLPanelMarketplaceListings::onTabChange()
void LLPanelMarketplaceListings::onAddButtonClicked()
{
- LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ LLUUID marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
llassert(marketplacelistings_id.notNull());
LLFolderType::EType preferred_type = LLFolderType::lookup("category");
LLHandle<LLPanel> handle = getHandle();
@@ -351,7 +352,15 @@ public:
if (added_category_type == LLFolderType::FT_MARKETPLACE_LISTINGS)
{
- mMarketplaceListingsFloater->initializeMarketPlace();
+ LLHandle<LLFloater> handle = mMarketplaceListingsFloater->getHandle();
+ doOnIdleOneTime([handle]()
+ {
+ LLFloaterMarketplaceListings* floater = (LLFloaterMarketplaceListings*)handle.get();
+ if (floater)
+ {
+ floater->initializeMarketPlace();
+ }
+ });
}
}
}
@@ -415,7 +424,7 @@ bool LLFloaterMarketplaceListings::postBuild()
// Fetch aggressively so we can interact with listings as soon as possible
if (!fetchContents())
{
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
LLInventoryModelBackgroundFetch::instance().start(marketplacelistings_id, true);
}
@@ -513,8 +522,6 @@ void LLFloaterMarketplaceListings::setRootFolder()
return;
}
- mRootFolderCreating = false;
-
// No longer need to observe new category creation
if (mCategoryAddedObserver && gInventory.containsObserver(mCategoryAddedObserver))
{
@@ -524,6 +531,8 @@ void LLFloaterMarketplaceListings::setRootFolder()
}
llassert(!mCategoryAddedObserver);
+ mRootFolderCreating = false;
+
if (marketplacelistings_id == mRootFolderId)
{
LL_WARNS("SLM") << "Inventory warning: Marketplace listings folder already set" << LL_ENDL;
@@ -566,7 +575,8 @@ void LLFloaterMarketplaceListings::setPanels()
void LLFloaterMarketplaceListings::initializeMarketPlace()
{
- LLMarketplaceData::instance().initializeSLM(boost::bind(&LLFloaterMarketplaceListings::updateView, this));
+ if (!mRootFolderCreating)
+ LLMarketplaceData::instance().initializeSLM(boost::bind(&LLFloaterMarketplaceListings::updateView, this));
}
S32 LLFloaterMarketplaceListings::getFolderCount()
@@ -909,7 +919,7 @@ void LLFloaterMarketplaceValidation::onOpen(const LLSD& key)
LLUUID cat_id(key.asUUID());
if (cat_id.isNull())
{
- cat_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ cat_id = gInventory.getMarketplaceListingsUUID();
}
// Validates the folder
diff --git a/indra/newview/llfloaterobjectweights.cpp b/indra/newview/llfloaterobjectweights.cpp
index fa491a4b27..bd8530abd7 100644
--- a/indra/newview/llfloaterobjectweights.cpp
+++ b/indra/newview/llfloaterobjectweights.cpp
@@ -208,7 +208,7 @@ void LLFloaterObjectWeights::draw()
toggleRenderLoadingIndicators(false);
}
mTrianglesShown->setText(llformat("%d", total_tris));
- mPixelArea->setText(llformat("%d", pixel_area));
+ mPixelArea->setText(llformat("%ld", (S64)pixel_area)); // value capped at 10M
}
LLFloater::draw();
}
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index d5e45c09e3..e497fb0914 100644
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -502,7 +502,7 @@ void LLFloaterPay::onGive(give_money_ptr info)
amount = atoi(text_field->getValue().asString().c_str());
}
- if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount)
+ if (amount > PAY_AMOUNT_NOTIFICATION)
{
LLUUID payee_id = LLUUID::null;
bool is_group = false;
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 989dbc0c29..024017ad9b 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -474,7 +474,8 @@ bool LLFloaterPreference::postBuild()
getChild<LLUICtrl>("log_path_string")->setEnabled(false); // make it read-only but selectable
- getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
+ mLanguageCombobox = getChild<LLComboBox>("language_combobox");
+ mLanguageCombobox->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
mTimeFormatCombobox = getChild<LLComboBox>("time_format_combobox");
mTimeFormatCombobox->setCommitCallback(boost::bind(&LLFloaterPreference::onTimeFormatChange, this));
@@ -516,18 +517,18 @@ bool LLFloaterPreference::postBuild()
std::map<std::string, std::string>::iterator iter = labels.find(system_lang);
if (iter != labels.end())
{
- getChild<LLComboBox>("language_combobox")->add(iter->second, LLSD("default"), ADD_TOP, true);
+ mLanguageCombobox->add(iter->second, LLSD("default"), ADD_TOP, true);
}
else
{
LL_WARNS() << "Language \"" << system_lang << "\" is not in default_languages.xml" << LL_ENDL;
- getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
+ mLanguageCombobox->add("System default", LLSD("default"), ADD_TOP, true);
}
}
else
{
LL_WARNS() << "Failed to load labels from " << user_filename << ". Using default." << LL_ENDL;
- getChild<LLComboBox>("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true);
+ mLanguageCombobox->add("System default", LLSD("default"), ADD_TOP, true);
}
#ifndef LL_DISCORD
@@ -1340,6 +1341,12 @@ void LLFloaterPreference::refresh()
updateClickActionViews();
mTimeFormatCombobox->selectByValue(gSavedSettings.getBOOL("Use24HourClock") ? "1" : "0");
+
+ std::string current_language = gSavedSettings.getString("Language");
+ if (current_language != "default" && !current_language.empty())
+ {
+ mLanguageCombobox->selectByValue(LLSD(current_language));
+ }
}
void LLFloaterPreference::onCommitWindowedMode()
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index a2aa3ee8de..3028bec64a 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -237,6 +237,7 @@ private:
LLButton* mEnablePopupBtn = nullptr;
LLButton* mDisablePopupBtn = nullptr;
LLComboBox* mTimeFormatCombobox = nullptr;
+ LLComboBox* mLanguageCombobox = nullptr;
std::unique_ptr< ll::prefs::SearchData > mSearchData;
bool mSearchDataDirty;
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 4cb6e7be96..1b5566a32d 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -538,6 +538,18 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
panel->getChildView("access_combo")->setEnabled(gAgent.isGodlike() || (region && region->canManageEstate() && !teen_grid));
panel->setCtrlsEnabled(allow_modify);
+ panel->getChild<LLLineEditor>("estate_id")->setValue((S32)region_info.mEstateID);
+
+ if (region)
+ {
+ panel->getChild<LLLineEditor>("grid_position_x")->setValue((S32)(region->getOriginGlobal()[VX] / 256));
+ panel->getChild<LLLineEditor>("grid_position_y")->setValue((S32)(region->getOriginGlobal()[VY] / 256));
+ }
+ else
+ {
+ panel->getChild<LLLineEditor>("grid_position_x")->setDefaultText();
+ panel->getChild<LLLineEditor>("grid_position_y")->setDefaultText();
+ }
// DEBUG PANEL
panel = tab->getChild<LLPanel>("Debug");
@@ -902,6 +914,9 @@ bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region)
getChildView("apply_btn")->setEnabled(false);
getChildView("access_text")->setEnabled(allow_modify);
// getChildView("access_combo")->setEnabled(allow_modify);
+ getChildView("estate_id")->setEnabled(false);
+ getChildView("grid_position_x")->setEnabled(false);
+ getChildView("grid_position_y")->setEnabled(false);
// now set in processRegionInfo for teen grid detection
getChildView("kick_btn")->setEnabled(allow_modify);
getChildView("kick_all_btn")->setEnabled(allow_modify);
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index cb1068943e..41d7d93528 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -901,6 +901,39 @@ private:
};
+F32 shader_timer_benchmark(std::vector<LLRenderTarget> & dest, TextureHolder & texHolder, U32 textures_count, LLVertexBuffer * buff, F32 &seconds)
+{
+ // run GPU timer benchmark
+
+ //number of samples to take
+ const S32 samples = 64;
+
+ {
+ ShaderProfileHelper initProfile;
+ dest[0].bindTarget();
+ gBenchmarkProgram.bind();
+ for (S32 c = 0; c < samples; ++c)
+ {
+ for (U32 i = 0; i < textures_count; ++i)
+ {
+ texHolder.bind(i);
+ buff->setBuffer();
+ buff->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+ }
+ gBenchmarkProgram.unbind();
+ dest[0].flush();
+ }
+
+ F32 ms = gBenchmarkProgram.mTimeElapsed / 1000000.f;
+ seconds = ms / 1000.f;
+
+ F64 samples_drawn = (F64)gBenchmarkProgram.mSamplesDrawn;
+ F64 gpixels_drawn = samples_drawn / 1000000000.0;
+ F32 samples_sec = (F32)(gpixels_drawn / seconds);
+ return samples_sec * 4; // 4 bytes per sample
+}
+
//-----------------------------------------------------------------------------
// gpu_benchmark()
// returns measured memory bandwidth of GPU in gigabytes per second
@@ -942,9 +975,6 @@ F32 gpu_benchmark()
//number of textures
const U32 count = 32;
- //number of samples to take
- const S32 samples = 64;
-
//time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark.
const F32 time_limit = 30;
@@ -1034,33 +1064,15 @@ F32 gpu_benchmark()
LLGLSLShader::unbind();
- // run GPU timer benchmark
- {
- ShaderProfileHelper initProfile;
- dest[0].bindTarget();
- gBenchmarkProgram.bind();
- for (S32 c = 0; c < samples; ++c)
- {
- for (U32 i = 0; i < count; ++i)
- {
- texHolder.bind(i);
- buff->setBuffer();
- buff->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
- }
- gBenchmarkProgram.unbind();
- dest[0].flush();
- }
+ // run GPU timer benchmark twice
+ F32 seconds = 0;
+ F32 gbps = shader_timer_benchmark(dest, texHolder, count, buff.get(), seconds);
- F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
- F32 seconds = ms/1000.f;
+ LL_INFOS("Benchmark") << "Memory bandwidth, 1st run is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
- F64 samples_drawn = (F64)gBenchmarkProgram.mSamplesDrawn;
- F64 gpixels_drawn = samples_drawn / 1000000000.0;
- F32 samples_sec = (F32)(gpixels_drawn/seconds);
- F32 gbps = samples_sec*4; // 4 bytes per sample
+ gbps = shader_timer_benchmark(dest, texHolder, count, buff.get(), seconds);
- LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
+ LL_INFOS("Benchmark") << "Memory bandwidth, final run is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
return gbps;
}
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 7659e5f082..074cda1683 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -317,7 +317,7 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
// virtual
bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
{
- // Why is "new group" sufficient?
+ // "new group" is sufficient because update_group_floaters always calls that on group changes
if (event->desc() == "new group")
{
setDirty();
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 11f049564a..4327d281e5 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -301,7 +301,7 @@ void LLHUDNameTag::renderText()
const S32 label_height = ll_round((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
label_top_rect.mBottom = label_top_rect.mTop - label_height;
LLColor4 label_top_color = text_color;
- label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
+ label_top_color.mV[VALPHA] = bubble_opacity() * alpha_factor;
mRoundedRectTopImgp->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 848f28f933..542c0fdfdd 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -336,7 +336,7 @@ bool LLInvFVBridge::cutToClipboard()
const LLInventoryObject* obj = gInventory.getObject(mUUID);
if (obj && isItemMovable() && isItemRemovable())
{
- const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
const bool cut_from_marketplacelistings = gInventory.isObjectDescendentOf(mUUID, marketplacelistings_id);
if (cut_from_marketplacelistings && (LLMarketplaceData::instance().isInActiveFolder(mUUID) ||
@@ -1378,7 +1378,7 @@ bool LLInvFVBridge::isInboxFolder() const
bool LLInvFVBridge::isMarketplaceListingsFolder() const
{
- const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID folder_id = gInventory.getMarketplaceListingsUUID();
if (folder_id.isNull())
{
@@ -1686,7 +1686,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
{
std::string error_msg;
LLInventoryModel* model = getInventoryModel();
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &marketplacelistings_id = model->getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull())
{
LLViewerInventoryCategory * master_folder = model->getCategory(marketplacelistings_id);
@@ -1845,7 +1845,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
{
LLInventoryItem* itemp = model->getItem(mUUID);
if (!itemp) return;
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
// Note: For a single item, if it's not a copy, then it's a move
move_item_to_marketplacelistings(itemp, marketplacelistings_id, ("copy_to_marketplace_listings" == action));
}
@@ -2678,7 +2678,7 @@ bool LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
const LLUUID &cat_id = inv_cat->getUUID();
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID from_folder_uuid = inv_cat->getParentUUID();
const bool move_is_into_current_outfit = (mUUID == current_outfit_id);
@@ -3758,7 +3758,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
{
LLInventoryCategory * cat = gInventory.getCategory(mUUID);
if (!cat) return;
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
move_folder_to_marketplacelistings(cat, marketplacelistings_id, ("move_to_marketplace_listings" != action), (("copy_or_move_to_marketplace_listings" == action)));
}
else if ("copy_folder_uuid" == action)
@@ -4012,7 +4012,7 @@ void LLFolderBridge::pasteFromClipboard()
LLInventoryModel* model = getInventoryModel();
if (model && isClipboardPasteable())
{
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &marketplacelistings_id = model->getMarketplaceListingsUUID();
const bool paste_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
bool cut_from_marketplacelistings = false;
@@ -4074,7 +4074,7 @@ void LLFolderBridge::perform_pasteFromClipboard()
if (model && isClipboardPasteable())
{
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
@@ -4371,7 +4371,7 @@ void LLFolderBridge::pasteLinkFromClipboard()
if(model)
{
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const bool move_is_into_current_outfit = (mUUID == current_outfit_id);
@@ -4471,7 +4471,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
const LLUUID &trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
const LLUUID &lost_and_found_id = model->findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
const LLUUID &favorites = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
- const LLUUID &marketplace_listings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplace_listings_id = model->getMarketplaceListingsUUID();
const LLUUID &outfits_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
if (outfits_id == mUUID)
@@ -5708,7 +5708,7 @@ bool LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const LLUUID from_folder_uuid = inv_item->getParentUUID();
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 3cc57e851f..458ea24d33 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -405,7 +405,7 @@ void update_all_marketplace_count(const LLUUID& cat_id)
void update_all_marketplace_count()
{
// Get the marketplace root and launch the recursive exploration
- const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplace_listings_uuid = gInventory.getMarketplaceListingsUUID();
if (!marketplace_listings_uuid.isNull())
{
update_all_marketplace_count(marketplace_listings_uuid);
@@ -1050,11 +1050,7 @@ void open_marketplace_listings()
S32 depth_nesting_in_marketplace(LLUUID cur_uuid)
{
- // Get the marketplace listings root, exit with -1 (i.e. not under the marketplace listings root) if none
- // Todo: findCategoryUUIDForType is somewhat expensive with large
- // flat root folders yet we use depth_nesting_in_marketplace at
- // every turn, find a way to correctly cache this id.
- const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplace_listings_uuid = gInventory.getMarketplaceListingsUUID();
if (marketplace_listings_uuid.isNull())
{
return -1;
@@ -3420,7 +3416,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
if ("delete" == action)
{
- const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID &marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
bool marketplacelistings_item = false;
bool has_worn = false;
bool needs_replacement = false;
@@ -3601,7 +3597,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
if (action == "wear" || action == "wear_add")
{
const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
- const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID mp_id = gInventory.getMarketplaceListingsUUID();
std::copy_if(selected_uuid_set.begin(),
selected_uuid_set.end(),
std::back_inserter(ids),
@@ -4011,7 +4007,7 @@ void LLInventoryAction::buildMarketplaceFolders(LLFolderView* root)
// target listing *and* the original listing. So we need to keep track of both.
// Note: do not however put the marketplace listings root itself in this list or the whole marketplace data will be rebuilt.
sMarketplaceFolders.clear();
- const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.isNull())
{
return;
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index f77088e0b1..24b0866041 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -1726,7 +1726,7 @@ bool is_category_removable(const LLUUID& folder_id, bool check_worn)
}
}
- const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID mp_id = gInventory.getMarketplaceListingsUUID();
if (mp_id.notNull() && gInventory.isObjectDescendentOf(folder_id, mp_id))
{
return false;
@@ -1768,7 +1768,7 @@ void LLInventoryGallery::paste()
return;
}
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (mSelectedItemIDs.size() == 1 && gInventory.isObjectDescendentOf(*mSelectedItemIDs.begin(), marketplacelistings_id))
{
return;
@@ -2114,7 +2114,7 @@ void LLInventoryGallery::pasteAsLink()
}
const LLUUID& current_outfit_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
const LLUUID& my_outifts_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
std::vector<LLUUID> objects;
@@ -3333,7 +3333,7 @@ bool dragItemIntoFolder(LLUUID folder_id, LLInventoryItem* inv_item, bool drop,
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
const LLUUID &favorites_id = model->findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
const LLUUID &landmarks_id = model->findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
const LLUUID &my_outifts_id = model->findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
const bool move_is_into_current_outfit = (folder_id == current_outfit_id);
@@ -3727,7 +3727,7 @@ bool dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat,
const LLUUID &cat_id = inv_cat->getUUID();
const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
- const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = model->getMarketplaceListingsUUID();
//const LLUUID from_folder_uuid = inv_cat->getParentUUID();
const bool move_is_into_current_outfit = (dest_id == current_outfit_id);
const bool move_is_into_marketplacelistings = model->isObjectDescendentOf(dest_id, marketplacelistings_id);
diff --git a/indra/newview/llinventorygallerymenu.cpp b/indra/newview/llinventorygallerymenu.cpp
index 2c3909cc79..c0c93f56e0 100644
--- a/indra/newview/llinventorygallerymenu.cpp
+++ b/indra/newview/llinventorygallerymenu.cpp
@@ -400,7 +400,7 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata)
if (can_copy)
{
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (itemp)
{
move_item_to_marketplacelistings(itemp, marketplacelistings_id, copy_operation);
@@ -419,7 +419,7 @@ void LLInventoryGalleryContextMenu::doToSelected(const LLSD& userdata)
// option == 0 Move no copy item(s)
// option == 1 Don't move no copy item(s) (leave them behind)
bool copy_and_move = option == 0;
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
// main inventory only allows one item?
LLViewerInventoryItem* itemp = gInventory.getItem(lamdba_list.front());
@@ -535,7 +535,7 @@ bool can_list_on_marketplace(const LLUUID &id)
if (can_list)
{
std::string error_msg;
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull())
{
LLViewerInventoryCategory* master_folder = gInventory.getCategory(marketplacelistings_id);
@@ -1033,7 +1033,7 @@ void LLInventoryGalleryContextMenu::updateMenuItemsVisibility(LLContextMenu* men
// Marketplace
bool can_list = false;
- const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull() && !is_inbox && !obj->getIsLinkType())
{
if (is_folder)
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index c34df48f7d..01ff01e233 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -975,6 +975,15 @@ const LLUUID LLInventoryModel::findLibraryCategoryUUIDForType(LLFolderType::ETyp
return findCategoryUUIDForTypeInRoot(preferred_type, gInventory.getLibraryRootFolderID());
}
+const LLUUID LLInventoryModel::getMarketplaceListingsUUID()
+{
+ if (mMarketplaceListingsUUID.isNull())
+ {
+ mMarketplaceListingsUUID = findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ }
+ return mMarketplaceListingsUUID;
+}
+
// Convenience function to create a new category. You could call
// updateCategory() with a newly generated UUID category, but this
// version will take care of details like what the name should be
@@ -1692,7 +1701,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32
mask |= LLInventoryObserver::LABEL;
}
// Under marketplace, category labels are quite complex and need extra upate
- const LLUUID marketplace_id = findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplace_id = getMarketplaceListingsUUID();
if (marketplace_id.notNull() && isObjectDescendentOf(cat->getUUID(), marketplace_id))
{
mask |= LLInventoryObserver::LABEL;
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 2859923df9..9fbabec8f3 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -329,6 +329,8 @@ public:
// user specified one or it does not exist, creates default category if it is missing.
const LLUUID findUserDefinedCategoryUUIDForType(LLFolderType::EType preferred_type) const;
+ const LLUUID getMarketplaceListingsUUID();
+
// Get whatever special folder this object is a child of, if any.
const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
@@ -361,6 +363,8 @@ public:
private:
mutable LLPointer<LLViewerInventoryItem> mLastItem; // cache recent lookups
+ LLUUID mMarketplaceListingsUUID;
+
//--------------------------------------------------------------------
// Count
//--------------------------------------------------------------------
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 1e5f771ba7..82eefb50ac 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -828,7 +828,7 @@ void LLInventoryModelBackgroundFetch::bulkFetchViaAis()
// Intent is for marketplace request to happen after
// main inventory is done, unless requested by floater
mRecursiveMarketplaceFetchStarted = true;
- const LLUUID& marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID& marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull())
{
mFetchFolderQueue.emplace_front(marketplacelistings_id, FT_FOLDER_AND_CONTENT);
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index cde87ede9b..8d57a4e7bb 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1849,6 +1849,7 @@ void LLInventoryPanel::purgeSelectedItems()
{
if (!mFolderRoot.get()) return;
+ const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
const std::set<LLFolderViewItem*> inventory_selected = mFolderRoot.get()->getSelectionList();
if (inventory_selected.empty()) return;
LLSD args;
@@ -1858,12 +1859,17 @@ void LLInventoryPanel::purgeSelectedItems()
it != end_it;
++it)
{
+ // Selection allows items outside trash folder, only count the ones inside.
LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
- LLInventoryModel::cat_array_t cats;
- LLInventoryModel::item_array_t items;
- gInventory.collectDescendents(item_id, cats, items, LLInventoryModel::INCLUDE_TRASH);
- count += items.size() + cats.size();
- selected_items.push_back(item_id);
+ LLInventoryObject* obj = gInventory.getObject(item_id);
+ if (obj->getParentUUID() == trash_id)
+ {
+ LLInventoryModel::cat_array_t cats;
+ LLInventoryModel::item_array_t items;
+ gInventory.collectDescendents(item_id, cats, items, LLInventoryModel::INCLUDE_TRASH);
+ count += items.size() + cats.size();
+ selected_items.push_back(item_id);
+ }
}
args["COUNT"] = static_cast<S32>(count);
LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(callbackPurgeSelectedItems, _1, _2, selected_items));
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index d80d9058e2..3567ca8e4a 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -582,7 +582,7 @@ void LLLocalBitmap::updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel)
if (object->isSculpted() && object->getVolume() &&
object->getVolume()->getParams().getSculptID() == old_id)
{
- LLSculptParams* old_params = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams* old_params = object->getSculptParams();
LLSculptParams new_params(*old_params);
new_params.setSculptTexture(new_id, (*old_params).getSculptType());
object->setParameterEntry(LLNetworkData::PARAMS_SCULPT, new_params, true);
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index d1d4641df3..dad04f4eab 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -845,7 +845,7 @@ void LLMarketplaceData::setDataFetchedSignal(const status_updated_signal_t::slot
// Get/Post/Put requests to the SLM Server using the SLM API
void LLMarketplaceData::getSLMListings()
{
- const LLUUID marketplaceFolderId = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplaceFolderId = gInventory.getMarketplaceListingsUUID();
setUpdating(marketplaceFolderId, true);
LLCoros::instance().launch("getSLMListings",
@@ -1752,7 +1752,7 @@ bool LLMarketplaceData::isUpdating(const LLUUID& folder_id, S32 depth)
}
else
{
- const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplace_listings_uuid = gInventory.getMarketplaceListingsUUID();
std::set<LLUUID>::iterator it = mPendingUpdateSet.find(marketplace_listings_uuid);
if (it != mPendingUpdateSet.end())
{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 0ed1e01ff8..68739341e9 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4271,20 +4271,63 @@ S32 LLMeshRepository::update()
return static_cast<S32>(size);
}
-void LLMeshRepository::unregisterMesh(LLVOVolume* vobj)
+void LLMeshRepository::unregisterMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail)
{
- for (auto& lod : mLoadingMeshes)
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ llassert((mesh_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH);
+ llassert(mesh_params.getSculptID().notNull());
+ auto& lod = mLoadingMeshes[detail];
+ auto param_iter = lod.find(mesh_params.getSculptID());
+ if (param_iter != lod.end())
{
- for (auto& param : lod)
+ param_iter->second.mVolumes.erase(vobj);
+ llassert(!param_iter->second.mVolumes.contains(vobj));
+ if (param_iter->second.mVolumes.empty())
{
- vector_replace_with_last(param.second.mVolumes, vobj);
+ lod.erase(param_iter);
}
}
+}
- for (auto& skin_pair : mLoadingSkins)
+void LLMeshRepository::unregisterSkinInfo(const LLUUID& mesh_id, LLVOVolume* vobj)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ llassert(mesh_id.notNull());
+ auto skin_pair_iter = mLoadingSkins.find(mesh_id);
+ if (skin_pair_iter != mLoadingSkins.end())
+ {
+ skin_pair_iter->second.mVolumes.erase(vobj);
+ llassert(!skin_pair_iter->second.mVolumes.contains(vobj));
+ if (skin_pair_iter->second.mVolumes.empty())
+ {
+ mLoadingSkins.erase(skin_pair_iter);
+ }
+ }
+}
+
+// Lots of dead objects make expensive calls to
+// LLMeshRepository::unregisterMesh which may delay shutdown. Avoid this by
+// preemptively unregistering all meshes.
+// We can also do this safely if all objects are confirmed dead for some other
+// reason.
+void LLMeshRepository::unregisterAllMeshes()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ // The size of mLoadingMeshes and mLoadingSkins may be large and thus
+ // expensive to iterate over in LLVOVolume::~LLVOVolume.
+ // This is unnecessary during shutdown, so we ignore the referenced objects in the
+ // least expensive way which is still safe: by clearing these containers.
+ // Clear now and not in LLMeshRepository::shutdown because
+ // LLMeshRepository::notifyLoadedMeshes could (depending on invocation
+ // order) reference a pointer to an object after it has been deleted.
+ for (auto& lod : mLoadingMeshes)
{
- vector_replace_with_last(skin_pair.second.mVolumes, vobj);
+ lod.clear();
}
+ mLoadingSkins.clear();
}
S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 new_lod, S32 last_lod)
@@ -4306,7 +4349,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
mesh_load_map::iterator iter = mLoadingMeshes[new_lod].find(mesh_id);
if (iter != mLoadingMeshes[new_lod].end())
{ //request pending for this mesh, append volume id to list
- auto it = std::find(iter->second.mVolumes.begin(), iter->second.mVolumes.end(), vobj);
+ auto it = iter->second.mVolumes.find(vobj);
if (it == iter->second.mVolumes.end()) {
iter->second.addVolume(vobj);
}
@@ -4804,7 +4847,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOV
skin_load_map::iterator iter = mLoadingSkins.find(mesh_id);
if (iter != mLoadingSkins.end())
{ //request pending for this mesh, append volume id to list
- auto it = std::find(iter->second.mVolumes.begin(), iter->second.mVolumes.end(), requesting_obj);
+ auto it = iter->second.mVolumes.find(requesting_obj);
if (it == iter->second.mVolumes.end()) {
iter->second.addVolume(requesting_obj);
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 01b51e753e..56ad8297c7 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -290,7 +290,7 @@ private:
class MeshLoadData
{
public:
- MeshLoadData() {}
+ MeshLoadData() = default;
~MeshLoadData()
{
if (std::shared_ptr<PendingRequestBase> request = mRequest.lock())
@@ -300,19 +300,19 @@ public:
}
void initData(LLVOVolume* vol, std::shared_ptr<PendingRequestBase>& request)
{
- mVolumes.push_back(vol);
+ mVolumes.insert(vol);
request->trackData(this);
mRequest = request;
}
void addVolume(LLVOVolume* vol)
{
- mVolumes.push_back(vol);
+ mVolumes.insert(vol);
if (std::shared_ptr<PendingRequestBase> request = mRequest.lock())
{
request->setScoreDirty();
}
}
- std::vector<LLVOVolume*> mVolumes;
+ std::unordered_set<LLVOVolume*> mVolumes;
private:
std::weak_ptr<PendingRequestBase> mRequest;
};
@@ -862,10 +862,12 @@ public:
LLMeshRepository();
void init();
+ void unregisterAllMeshes();
void shutdown();
S32 update();
- void unregisterMesh(LLVOVolume* volume);
+ void unregisterMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail);
+ void unregisterSkinInfo(const LLUUID& mesh_id, LLVOVolume* vobj);
//mesh management functions
S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 new_lod = 0, S32 last_lod = -1);
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index ecb66f9cea..ad65293b98 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -191,6 +191,13 @@ bool LLPanelGroup::postBuild()
mButtonJoin->setCommitCallback(boost::bind(&LLPanelGroup::onBtnJoin,this));
mJoinText = panel_general->getChild<LLUICtrl>("join_cost_text");
+
+ mButtonActivate = panel_general->getChild<LLButton>("btn_activate");
+ mButtonActivate->setVisible(false);
+ mButtonActivate->setEnabled(gAgent.getGroupID() != mID);
+ mButtonActivate->setCommitCallback(boost::bind(&LLPanelGroup::onBtnActivate, this));
+
+ gAgent.addListener(this, "new group");
}
LLVoiceClient::addObserver(this);
@@ -267,6 +274,7 @@ void LLPanelGroup::onBtnJoin()
if (LLGroupActions::isInGroup(mID))
{
LLGroupActions::leave(mID);
+ mButtonActivate->setVisible(false);
}
else
{
@@ -275,6 +283,12 @@ void LLPanelGroup::onBtnJoin()
}
}
+void LLPanelGroup::onBtnActivate()
+{
+ LLGroupActions::activate(mID);
+ mButtonActivate->setEnabled(false);
+}
+
void LLPanelGroup::changed(LLGroupChange gc)
{
for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
@@ -312,6 +326,8 @@ void LLPanelGroup::update(LLGroupChange gc)
bool join_btn_visible = is_member || gdatap->mOpenEnrollment;
mButtonJoin->setVisible(join_btn_visible);
+ mButtonActivate->setEnabled(gAgent.getGroupID() != mID);
+ mButtonActivate->setVisible(is_member);
mJoinText->setVisible(join_btn_visible);
if (is_member)
@@ -384,6 +400,8 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
if(mButtonJoin)
mButtonJoin->setVisible(false);
+ if (mButtonActivate)
+ mButtonActivate->setVisible(false);
if(is_null_group_id)//creating new group
@@ -598,4 +616,20 @@ void LLPanelGroup::showNotice(const std::string& subject,
}
+bool LLPanelGroup::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+ if (event->desc() == "new group")
+ {
+ mButtonActivate->setEnabled(gAgent.getGroupID() != mID);
+ return true;
+ }
+
+ if (event->desc() == "value_changed")
+ {
+ mButtonActivate->setEnabled(gAgent.getGroupID() != mID);
+ return true;
+ }
+
+ return false;
+}
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index b43a93bc40..d3550264a0 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -26,6 +26,7 @@
#ifndef LL_LLPANELGROUP_H
#define LL_LLPANELGROUP_H
+#include "llevent.h"
#include "llgroupmgr.h"
#include "llpanel.h"
#include "lltimer.h"
@@ -44,7 +45,8 @@ class LLAgent;
class LLPanelGroup : public LLPanel,
public LLGroupMgrObserver,
- public LLVoiceClientStatusObserver
+ public LLVoiceClientStatusObserver,
+ public LLOldEvents::LLSimpleListener
{
public:
LLPanelGroup();
@@ -94,6 +96,7 @@ protected:
void onBackBtnClick();
void onBtnJoin();
+ void onBtnActivate();
static void onBtnApply(void*);
static void onBtnRefresh(void*);
@@ -120,11 +123,15 @@ protected:
LLUICtrl* mGroupNameCtrl = nullptr;
LLButton* mButtonJoin = nullptr;
+ LLButton* mButtonActivate = nullptr;
LLButton* mButtonApply = nullptr;
LLButton* mButtonCall = nullptr;
LLButton* mButtonChat = nullptr;
LLButton* mButtonRefresh = nullptr;
LLUICtrl* mJoinText;
+
+private:
+ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // for agent group list changes
};
class LLPanelGroupTab : public LLPanel
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index fe9145bf71..00b592d86e 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -188,7 +188,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
mUsernameLength(0),
mPasswordLength(0),
mLocationLength(0),
- mShowFavorites(false)
+ mShowFavorites(false),
+ mAlertNotif(false)
{
setBackgroundVisible(false);
setBackgroundOpaque(true);
@@ -297,8 +298,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
childSetAction("connect_btn", onClickConnect, this);
- LLButton* def_btn = getChild<LLButton>("connect_btn");
- setDefaultBtn(def_btn);
+ mLoginBtn = getChild<LLButton>("connect_btn");
+ setDefaultBtn(mLoginBtn);
std::string channel = LLVersionInfo::instance().getChannel();
std::string version = stringize(LLVersionInfo::instance().getShortVersion(), " (",
@@ -327,6 +328,8 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
LLCheckBoxCtrl* remember_name = getChild<LLCheckBoxCtrl>("remember_name");
remember_name->setCommitCallback(boost::bind(&LLPanelLogin::onRememberUserCheck, this));
getChild<LLCheckBoxCtrl>("remember_password")->setCommitCallback(boost::bind(&LLPanelLogin::onRememberPasswordCheck, this));
+
+ mAlertListener = LLNotifications::instance().getChannel("Alerts")->connectChanged([this](const LLSD& notify){ return onUpdateNotification(notify); });
}
void LLPanelLogin::addFavoritesToStartLocation()
@@ -409,7 +412,7 @@ void LLPanelLogin::addFavoritesToStartLocation()
gSavedSettings.setBOOL("RememberPassword", save_password);
if (!save_password)
{
- getChild<LLButton>("connect_btn")->setEnabled(false);
+ mLoginBtn->setEnabled(false);
}
update_password_setting = false;
}
@@ -936,7 +939,7 @@ void LLPanelLogin::handleMediaEvent(LLPluginClassMedia* /*self*/, EMediaEvent ev
// static
void LLPanelLogin::onClickConnect(bool commit_fields)
{
- if (sInstance && sInstance->mCallback)
+ if (sInstance && sInstance->mCallback && !sInstance->mAlertNotif)
{
if (commit_fields)
{
@@ -1193,9 +1196,7 @@ void LLPanelLogin::updateServer()
void LLPanelLogin::updateLoginButtons()
{
- LLButton* login_btn = getChild<LLButton>("connect_btn");
-
- login_btn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0);
+ mLoginBtn->setEnabled(mUsernameLength != 0 && mPasswordLength != 0 && !mAlertNotif);
if (!mFirstLoginThisInstall)
{
@@ -1367,3 +1368,22 @@ std::string LLPanelLogin::getUserName(LLPointer<LLCredential> &cred)
return "unknown";
}
+bool LLPanelLogin::onUpdateNotification(const LLSD& notify)
+{
+ // disable Login button while alert notification is displayed
+ LLNotificationPtr notifyp = LLNotifications::instance().find(notify["id"].asUUID());
+ if (notifyp && notifyp->getName() == "PromptOptionalUpdate")
+ {
+ std::string sigtype = notify["sigtype"].asString();
+ if (sigtype == "add")
+ {
+ mAlertNotif = true;
+ }
+ else if (sigtype == "delete")
+ {
+ mAlertNotif = false;
+ }
+ updateLoginButtons();
+ }
+ return false;
+}
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index a1bf25fb05..f527aa53ac 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -105,8 +105,11 @@ private:
static void onRememberPasswordCheck(void*);
static void onPassKey(LLLineEditor* caller, void* user_data);
+ bool onUpdateNotification(const LLSD& notify);
+
private:
std::unique_ptr<LLPanelLoginListener> mListener;
+ LLTempBoundListener mAlertListener;
void updateLoginButtons();
void populateUserList(LLPointer<LLCredential> credential);
@@ -126,6 +129,9 @@ private:
unsigned int mUsernameLength;
unsigned int mPasswordLength;
unsigned int mLocationLength;
+
+ bool mAlertNotif;
+ LLButton* mLoginBtn;
};
#endif
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 23e6a9fbcf..69be65d9c9 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -625,7 +625,7 @@ void LLPanelObject::getState( )
}
- if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ if (objectp->getSculptParams())
{
selected_item = MI_SCULPT;
//LLFirstUse::useSculptedPrim();
@@ -1078,7 +1078,7 @@ void LLPanelObject::getState( )
LLUUID id;
- LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = objectp->getSculptParams();
if (sculpt_params) // if we have a legal sculpt param block for this object:
@@ -1246,13 +1246,13 @@ void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata )
if (selected_type == MI_SCULPT)
{
self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, true, true);
- LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = self->mObject->getSculptParams();
if (sculpt_params)
volume_params.setSculptID(sculpt_params->getSculptTexture(), sculpt_params->getSculptType());
}
else
{
- LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = self->mObject->getSculptParams();
if (sculpt_params)
self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, false, true);
}
@@ -2264,24 +2264,21 @@ void LLPanelObject::onCopyParams()
mClipboardParams["volume_params"] = params.asLLSD();
// Sculpted Prim
- if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ LLSculptParams *sculpt_params = objectp->getSculptParams();
+ if (sculpt_params)
{
- LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- if (sculpt_params)
+ LLUUID texture_id = sculpt_params->getSculptTexture();
+ if (get_can_copy_texture(texture_id))
{
- LLUUID texture_id = sculpt_params->getSculptTexture();
- if (get_can_copy_texture(texture_id))
- {
- LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL;
- mClipboardParams["sculpt"]["id"] = texture_id;
- }
- else
- {
- mClipboardParams["sculpt"]["id"] = SCULPT_DEFAULT_TEXTURE;
- }
-
- mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType();
+ LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL;
+ mClipboardParams["sculpt"]["id"] = texture_id;
}
+ else
+ {
+ mClipboardParams["sculpt"]["id"] = SCULPT_DEFAULT_TEXTURE;
+ }
+
+ mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType();
}
}
@@ -2304,7 +2301,7 @@ void LLPanelObject::onPasteParams()
}
else
{
- LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = objectp->getSculptParams();
if (sculpt_params)
{
objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, false, true);
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 5916163f60..94864797d5 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -532,7 +532,7 @@ void LLPanelVolume::getState( )
getChildView("FlexForceY")->setEnabled(true);
getChildView("FlexForceZ")->setEnabled(true);
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData *attributes = objectp->getFlexibleObjectData();
getChild<LLUICtrl>("FlexNumSections")->setValue((F32)attributes->getSimulateLOD());
getChild<LLUICtrl>("FlexGravity")->setValue(attributes->getGravity());
@@ -643,7 +643,7 @@ void LLPanelVolume::getState( )
mComboPhysicsShapeType->add(getString("None"), LLSD(1));
bool isMesh = false;
- LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = objectp->getSculptParams();
if (sculpt_params)
{
U8 sculpt_type = sculpt_params->getSculptType();
@@ -1043,7 +1043,7 @@ void LLPanelVolume::onCopyFeatures()
// Flexi Prim
if (volobjp && volobjp->isFlexible())
{
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData *attributes = objectp->getFlexibleObjectData();
if (attributes)
{
clipboard["flex"]["lod"] = attributes->getSimulateLOD();
@@ -1141,7 +1141,7 @@ void LLPanelVolume::onPasteFeatures()
objectp->setClickAction(CLICK_ACTION_NONE);
}
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData *attributes = objectp->getFlexibleObjectData();
if (attributes)
{
LLFlexibleObjectData new_attributes;
@@ -1568,7 +1568,7 @@ void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
return;
}
- LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData *attributes = objectp->getFlexibleObjectData();
if (attributes)
{
LLFlexibleObjectData new_attributes;
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 2dc2810861..66872b104e 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -135,9 +135,10 @@ void LLSpatialGroup::clearDrawMap()
mDrawMap.clear();
}
-bool LLSpatialGroup::isHUDGroup()
+bool LLSpatialGroup::isHUDGroup() const
{
- return getSpatialPartition() && getSpatialPartition()->isHUDPartition() ;
+ LLSpatialPartition* part = (LLSpatialPartition*)mSpatialPartition;
+ return part && part->isHUDPartition();
}
void LLSpatialGroup::validate()
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index dd11099c69..2e918df910 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -265,7 +265,7 @@ public:
LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part);
- bool isHUDGroup() ;
+ bool isHUDGroup() const;
void clearDrawMap();
void validate();
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index f78ff2226c..5e2d91d31e 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -775,7 +775,7 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, bool drop,
if (!handled)
{
// Disallow drag and drop to 3D from the marketplace
- const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.notNull())
{
for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++)
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index 5ccda7d4eb..3bd459f5b0 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -55,17 +55,17 @@ LLToolSelect::LLToolSelect( LLToolComposite* composite )
: LLTool( std::string("Select"), composite ),
mIgnoreGroup( false )
{
- }
+}
// True if you selected an object.
bool LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
{
// do immediate pick query
bool pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
- bool pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects");
- bool pick_reflection_probe = gSavedSettings.getBOOL("SelectReflectionProbes");
+ static LLCachedControl<bool> select_invisible_objects(gSavedSettings, "SelectInvisibleObjects");
+ static LLCachedControl<bool> select_reflection_probes(gSavedSettings, "SelectReflectionProbes");
- mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged, false, true, pick_reflection_probe);
+ mPick = gViewerWindow->pickImmediate(x, y, select_invisible_objects, pick_rigged, false, true, select_reflection_probes);
// Pass mousedown to agent
LLTool::handleMouseDown(x, y, mask);
@@ -73,7 +73,6 @@ bool LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
return mPick.getObject().notNull();
}
-
// static
LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pick, bool ignore_group, bool temp_select, bool select_root)
{
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index aa0cbac91f..a7441febd9 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -398,18 +398,12 @@ void init_audio()
void audio_update_volume(bool force_update)
{
- F32 master_volume = gSavedSettings.getF32("AudioLevelMaster");
- bool mute_audio = gSavedSettings.getBOOL("MuteAudio");
-
- LLProgressView* progress = gViewerWindow->getProgressView();
- bool progress_view_visible = false;
-
- if (progress)
- {
- progress_view_visible = progress->getVisible();
- }
+ static LLCachedControl<F32> master_volume(gSavedSettings, "AudioLevelMaster");
+ static LLCachedControl<bool> mute_audio_setting(gSavedSettings, "MuteAudio");
+ static LLCachedControl<bool> mute_when_minimized(gSavedSettings, "MuteWhenMinimized");
+ bool mute_audio = mute_audio_setting();
- if (!gViewerWindow->getActive() && gSavedSettings.getBOOL("MuteWhenMinimized"))
+ if (!gViewerWindow->getActive() && mute_when_minimized())
{
mute_audio = true;
}
@@ -419,7 +413,7 @@ void audio_update_volume(bool force_update)
{
// Sound Effects
- gAudiop->setMasterGain ( master_volume );
+ gAudiop->setMasterGain (master_volume());
const F32 AUDIO_LEVEL_DOPPLER = 1.f;
gAudiop->setDopplerFactor(AUDIO_LEVEL_DOPPLER);
@@ -435,6 +429,7 @@ void audio_update_volume(bool force_update)
gAudiop->setRolloffFactor(AUDIO_LEVEL_UNDERWATER_ROLLOFF);
}
+ bool progress_view_visible = gViewerWindow->getShowProgress();
gAudiop->setMuted(mute_audio || progress_view_visible);
//Play any deferred sounds when unmuted
@@ -448,13 +443,21 @@ void audio_update_volume(bool force_update)
audio_update_wind(true);
}
+ static LLCachedControl<bool> mute_sounds(gSavedSettings, "MuteSounds");
+ static LLCachedControl<bool> mute_ui(gSavedSettings, "MuteUI");
+ static LLCachedControl<bool> mute_ambient(gSavedSettings, "MuteAmbient");
+ static LLCachedControl<bool> mute_music(gSavedSettings, "MuteMusic");
+ static LLCachedControl<F32> al_sfx(gSavedSettings, "AudioLevelSFX");
+ static LLCachedControl<F32> al_ui(gSavedSettings, "AudioLevelUI");
+ static LLCachedControl<F32> al_ambient(gSavedSettings, "AudioLevelAmbient");
+ static LLCachedControl<F32> al_music(gSavedSettings, "AudioLevelMusic");
// handle secondary gains
gAudiop->setSecondaryGain(LLAudioEngine::AUDIO_TYPE_SFX,
- gSavedSettings.getBOOL("MuteSounds") ? 0.f : gSavedSettings.getF32("AudioLevelSFX"));
+ mute_sounds() ? 0.f : al_sfx());
gAudiop->setSecondaryGain(LLAudioEngine::AUDIO_TYPE_UI,
- gSavedSettings.getBOOL("MuteUI") ? 0.f : gSavedSettings.getF32("AudioLevelUI"));
+ mute_ui() ? 0.f : al_ui());
gAudiop->setSecondaryGain(LLAudioEngine::AUDIO_TYPE_AMBIENT,
- gSavedSettings.getBOOL("MuteAmbient") ? 0.f : gSavedSettings.getF32("AudioLevelAmbient"));
+ mute_ambient() ? 0.f : al_ambient());
// Streaming Music
@@ -464,31 +467,29 @@ void audio_update_volume(bool force_update)
LLViewerAudio::getInstance()->setForcedTeleportFade(false);
}
- F32 music_volume = gSavedSettings.getF32("AudioLevelMusic");
- bool music_muted = gSavedSettings.getBOOL("MuteMusic");
F32 fade_volume = LLViewerAudio::getInstance()->getFadeVolume();
- music_volume = mute_volume * master_volume * music_volume * fade_volume;
- gAudiop->setInternetStreamGain (music_muted ? 0.f : music_volume);
+ F32 music_volume = mute_volume * master_volume * al_music() * fade_volume;
+ gAudiop->setInternetStreamGain (mute_music() ? 0.f : music_volume);
}
// Streaming Media
- F32 media_volume = gSavedSettings.getF32("AudioLevelMedia");
- bool media_muted = gSavedSettings.getBOOL("MuteMedia");
- media_volume = mute_volume * master_volume * media_volume;
- LLViewerMedia::getInstance()->setVolume( media_muted ? 0.0f : media_volume );
+ static LLCachedControl<bool> media_muted(gSavedSettings, "MuteMedia");
+ static LLCachedControl<F32> media_volume(gSavedSettings, "AudioLevelMedia");
+ LLViewerMedia::getInstance()->setVolume( media_muted() ? 0.0f : (mute_volume * master_volume() * media_volume()));
// Voice, this is parametric singleton, it gets initialized when ready
if (LLVoiceClient::instanceExists())
{
- F32 voice_volume = gSavedSettings.getF32("AudioLevelVoice");
- voice_volume = mute_volume * master_volume * voice_volume;
- bool voice_mute = gSavedSettings.getBOOL("MuteVoice");
+ static LLCachedControl<bool> voice_mute(gSavedSettings, "MuteVoice");
+ static LLCachedControl<F32> voice_volume_setting(gSavedSettings, "AudioLevelVoice");
+ static LLCachedControl<F32> voice_mic_setting(gSavedSettings, "AudioLevelMic");
+ F32 voice_volume = mute_volume * master_volume() * voice_volume_setting();
LLVoiceClient *voice_inst = LLVoiceClient::getInstance();
- voice_inst->setVoiceVolume(voice_mute ? 0.f : voice_volume);
- voice_inst->setMicGain(voice_mute ? 0.f : gSavedSettings.getF32("AudioLevelMic"));
+ voice_inst->setVoiceVolume(voice_mute() ? 0.f : voice_volume);
+ voice_inst->setMicGain(voice_mute() ? 0.f : voice_mic_setting());
- if (!gViewerWindow->getActive() && (gSavedSettings.getBOOL("MuteWhenMinimized")))
+ if (!gViewerWindow->getActive() && mute_when_minimized())
{
voice_inst->setMuteMic(true);
}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index a8eaadc426..30b2dafb8f 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -663,9 +663,10 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE);
llassert(!gCubeSnapshot);
+ static LLCachedControl<bool> use_read_thread(gSavedSettings, "PluginUseReadThread", true);
// Enable/disable the plugin read thread
- LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread"));
+ LLPluginProcessParent::setUseReadThread(use_read_thread());
// SL-16418 We can't call LLViewerMediaImpl->update() if we are in the state of shutting down.
if(LLApp::isExiting())
@@ -2196,16 +2197,19 @@ void LLViewerMediaImpl::updateVolume()
if (mProximityCamera > 0)
{
- if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMax"))
+ static LLCachedControl<F32> media_rolloff_min(gSavedSettings, "MediaRollOffMin");
+ static LLCachedControl<F32> media_rolloff_max(gSavedSettings, "MediaRollOffMax");
+ static LLCachedControl<F32> media_rolloff_rate(gSavedSettings, "MediaRollOffRate");
+ if (mProximityCamera > media_rolloff_max())
{
volume = 0;
}
- else if (mProximityCamera > gSavedSettings.getF32("MediaRollOffMin"))
+ else if (mProximityCamera > media_rolloff_min())
{
// attenuated_volume = 1 / (roll_off_rate * (d - min))^2
// the +1 is there so that for distance 0 the volume stays the same
- F64 adjusted_distance = mProximityCamera - gSavedSettings.getF32("MediaRollOffMin");
- F64 attenuation = 1.0 + (gSavedSettings.getF32("MediaRollOffRate") * adjusted_distance);
+ F64 adjusted_distance = mProximityCamera - media_rolloff_min();
+ F64 attenuation = 1.0 + (media_rolloff_rate() * adjusted_distance);
attenuation = 1.0 / (attenuation * attenuation);
// the attenuation multiplier should never be more than one since that would increase volume
volume = volume * (F32)llmin(1.0, attenuation);
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index abaf813530..f29760c824 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -425,7 +425,7 @@ void LLSLMMenuUpdater::setMerchantMenu()
LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
gToolBarView->enableCommand(command->id(), true);
- const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ const LLUUID marketplacelistings_id = gInventory.getMarketplaceListingsUUID();
if (marketplacelistings_id.isNull())
{
U32 mkt_status = LLMarketplaceData::instance().getSLMStatus();
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 1675c44c5c..0f4cbdd25c 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -310,6 +310,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mAttachmentItemID(LLUUID::null),
mLastUpdateType(OUT_UNKNOWN),
mLastUpdateCached(false),
+ mExtraParameterList(LLNetworkData::PARAMS_MAX >> 4),
mCachedMuteListUpdateTime(0),
mCachedOwnerInMuteList(false),
mRiggedAttachedWarned(false)
@@ -367,15 +368,6 @@ LLViewerObject::~LLViewerObject()
}
// Delete memory associated with extra parameters.
- std::unordered_map<U16, ExtraParameter*>::iterator iter;
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
- {
- if(iter->second != NULL)
- {
- delete iter->second->data;
- delete iter->second;
- }
- }
mExtraParameterList.clear();
for_each(mNameValuePairs.begin(), mNameValuePairs.end(), DeletePairedPointer()) ;
@@ -1508,10 +1500,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
unpackParticleSource(block_num, owner_id);
// Mark all extra parameters not used
- std::unordered_map<U16, ExtraParameter*>::iterator iter;
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ for (auto& entry : mExtraParameterList)
{
- iter->second->in_use = false;
+ if (entry.in_use) *entry.in_use = false;
}
// Unpack extra parameters
@@ -1543,12 +1534,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
delete[] buffer;
}
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ for (size_t i = 0; i < mExtraParameterList.size(); ++i)
{
- if (!iter->second->in_use)
+ auto& entry = mExtraParameterList[i];
+ if (entry.in_use && !*entry.in_use)
{
// Send an update message in case it was formerly in use
- parameterChanged(iter->first, iter->second->data, false, false);
+ parameterChanged(((U16)i + 1) << 4, entry.data, false, false);
}
}
@@ -1850,10 +1842,9 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
// Mark all extra parameters not used
- std::unordered_map<U16, ExtraParameter*>::iterator iter;
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ for (auto& entry : mExtraParameterList)
{
- iter->second->in_use = false;
+ if (entry.in_use) *entry.in_use = false;
}
// Unpack extra params
@@ -1871,12 +1862,13 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
unpackParameterEntry(param_type, &dp2);
}
- for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
+ for (size_t i = 0; i < mExtraParameterList.size(); ++i)
{
- if (!iter->second->in_use)
+ auto& entry = mExtraParameterList[i];
+ if (entry.in_use && !*entry.in_use)
{
// Send an update message in case it was formerly in use
- parameterChanged(iter->first, iter->second->data, false, false);
+ parameterChanged(((U16)i + 1) << 4, entry.data, false, false);
}
}
@@ -4183,7 +4175,7 @@ void LLViewerObject::boostTexturePriority(bool boost_children /* = true */)
if (isSculpted() && !isMesh())
{
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = getSculptParams();
if (sculpt_params)
{
LLUUID sculpt_id = sculpt_params->getSculptTexture();
@@ -6494,7 +6486,7 @@ bool LLViewerObject::unpackParameterEntry(U16 param_type, LLDataPacker *dp)
if (param)
{
param->data->unpack(*dp);
- param->in_use = true;
+ *param->in_use = true;
parameterChanged(param_type, param->data, true, false);
return true;
}
@@ -6506,108 +6498,79 @@ bool LLViewerObject::unpackParameterEntry(U16 param_type, LLDataPacker *dp)
LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 param_type)
{
- LLNetworkData* new_block = NULL;
+ LLNetworkData* new_block = nullptr;
+ bool* in_use = NULL;
switch (param_type)
{
case LLNetworkData::PARAMS_FLEXIBLE:
{
- new_block = new LLFlexibleObjectData();
+ mFlexibleObjectData = std::make_unique<LLFlexibleObjectData>();
+ new_block = mFlexibleObjectData.get();
+ in_use = &mFlexibleObjectDataInUse;
break;
}
case LLNetworkData::PARAMS_LIGHT:
{
- new_block = new LLLightParams();
+ mLightParams = std::make_unique<LLLightParams>();
+ new_block = mLightParams.get();
+ in_use = &mLightParamsInUse;
break;
}
case LLNetworkData::PARAMS_SCULPT:
{
- new_block = new LLSculptParams();
+ mSculptParams = std::make_unique<LLSculptParams>();
+ new_block = mSculptParams.get();
+ in_use = &mSculptParamsInUse;
break;
}
case LLNetworkData::PARAMS_LIGHT_IMAGE:
{
- new_block = new LLLightImageParams();
+ mLightImageParams = std::make_unique<LLLightImageParams>();
+ new_block = mLightImageParams.get();
+ in_use = &mLightImageParamsInUse;
break;
}
case LLNetworkData::PARAMS_EXTENDED_MESH:
{
- new_block = new LLExtendedMeshParams();
+ mExtendedMeshParams = std::make_unique<LLExtendedMeshParams>();
+ new_block = mExtendedMeshParams.get();
+ in_use = &mExtendedMeshParamsInUse;
break;
}
case LLNetworkData::PARAMS_RENDER_MATERIAL:
{
- new_block = new LLRenderMaterialParams();
+ mRenderMaterialParams = std::make_unique<LLRenderMaterialParams>();
+ new_block = mRenderMaterialParams.get();
+ in_use = &mRenderMaterialParamsInUse;
break;
}
case LLNetworkData::PARAMS_REFLECTION_PROBE:
{
- new_block = new LLReflectionProbeParams();
+ mReflectionProbeParams = std::make_unique<LLReflectionProbeParams>();
+ new_block = mReflectionProbeParams.get();
+ in_use = &mReflectionProbeParamsInUse;
break;
}
default:
{
- LL_INFOS_ONCE() << "Unknown param type: " << param_type << LL_ENDL;
+ LL_INFOS_ONCE() << "Unknown param type. (" << llformat("0x%2x", param_type) << ")" << LL_ENDL;
break;
}
};
+ ExtraParameter& entry = mExtraParameterList[U32(param_type >> 4) - 1];
if (new_block)
{
- ExtraParameter* new_entry = new ExtraParameter;
- new_entry->data = new_block;
- new_entry->in_use = false; // not in use yet
- llassert(mExtraParameterList[param_type] == nullptr); // leak -- redundantly allocated parameter entry
- mExtraParameterList[param_type] = new_entry;
- return new_entry;
- }
- return NULL;
-}
-
-LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER;
- std::unordered_map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
- if (itor != mExtraParameterList.end())
- {
- return itor->second;
- }
- return NULL;
-}
-
-LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntryCreate(U16 param_type)
-{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (!param)
- {
- param = createNewParameterEntry(param_type);
- }
- return param;
-}
-
-LLNetworkData* LLViewerObject::getParameterEntry(U16 param_type) const
-{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (param)
- {
- return param->data;
+ entry.in_use = in_use;
+ *entry.in_use = false; // not in use yet
+ entry.data = new_block;
+ return &entry;
}
else
{
- return NULL;
- }
-}
-
-bool LLViewerObject::getParameterEntryInUse(U16 param_type) const
-{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (param)
- {
- return param->in_use;
- }
- else
- {
- return false;
+ entry.is_invalid = true;
}
+ return nullptr;
}
bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin)
@@ -6615,11 +6578,11 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_
ExtraParameter* param = getExtraParameterEntryCreate(param_type);
if (param)
{
- if (param->in_use && new_value == *(param->data))
+ if (*(param->in_use) && new_value == *(param->data))
{
return false;
}
- param->in_use = true;
+ *param->in_use = true;
param->data->copy(new_value);
parameterChanged(param_type, param->data, true, local_origin);
return true;
@@ -6635,22 +6598,28 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_
// Should always return true.
bool LLViewerObject::setParameterEntryInUse(U16 param_type, bool in_use, bool local_origin)
{
- ExtraParameter* param = getExtraParameterEntryCreate(param_type);
- if (param && param->in_use != in_use)
+ if (param_type <= LLNetworkData::PARAMS_MAX)
{
- param->in_use = in_use;
- parameterChanged(param_type, param->data, in_use, local_origin);
- return true;
+ ExtraParameter* param = (in_use ? getExtraParameterEntryCreate(param_type) : &getExtraParameterEntry(param_type));
+ if (param && param->data && *param->in_use != in_use)
+ {
+ *param->in_use = in_use;
+ parameterChanged(param_type, param->data, in_use, local_origin);
+ return true;
+ }
}
return false;
}
void LLViewerObject::parameterChanged(U16 param_type, bool local_origin)
{
- ExtraParameter* param = getExtraParameterEntry(param_type);
- if (param)
+ if (param_type <= LLNetworkData::PARAMS_MAX)
{
- parameterChanged(param_type, param->data, param->in_use, local_origin);
+ const ExtraParameter& param = getExtraParameterEntry(param_type);
+ if (param.data)
+ {
+ parameterChanged(param_type, param.data, *param.in_use, local_origin);
+ }
}
}
@@ -6698,7 +6667,7 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, bool
{
if (param_type == LLNetworkData::PARAMS_RENDER_MATERIAL)
{
- const LLRenderMaterialParams* params = in_use ? (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL) : nullptr;
+ const LLRenderMaterialParams* params = in_use ? getRenderMaterialParams() : nullptr;
setRenderMaterialIDs(params, local_origin);
}
}
@@ -7469,9 +7438,10 @@ const std::string& LLViewerObject::getAttachmentItemName() const
LLVOAvatar* LLViewerObject::getAvatar() const
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
- if (getControlAvatar())
+ LLControlAvatar* ca = getControlAvatar();
+ if (ca)
{
- return getControlAvatar();
+ return ca;
}
if (isAttachment())
{
@@ -7490,7 +7460,7 @@ LLVOAvatar* LLViewerObject::getAvatar() const
bool LLViewerObject::hasRenderMaterialParams() const
{
- return getParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ return mRenderMaterialParamsInUse;
}
void LLViewerObject::setHasRenderMaterialParams(bool has_materials)
@@ -7512,7 +7482,7 @@ void LLViewerObject::setHasRenderMaterialParams(bool has_materials)
const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const
{
- LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ const LLRenderMaterialParams* param_block = getRenderMaterialParams();
if (param_block)
{
return param_block->getMaterial(te);
@@ -7553,7 +7523,7 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
start_idx = llmax(start_idx, 0);
end_idx = llmin(end_idx, (S32) getNumTEs());
- LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ LLRenderMaterialParams* param_block = getRenderMaterialParams();
if (!param_block && id.notNull())
{ // block doesn't exist, but it will need to
param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data;
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index a9c2db60e4..cccf59a319 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -126,13 +126,15 @@ class LLViewerObject
protected:
virtual ~LLViewerObject(); // use unref()
+private:
// TomY: Provide for a list of extra parameter structures, mapped by structure name
struct ExtraParameter
{
- bool in_use;
- LLNetworkData *data;
+ bool is_invalid = false;
+ bool* in_use = nullptr;
+ LLNetworkData* data = nullptr;
};
- std::unordered_map<U16, ExtraParameter*> mExtraParameterList;
+ std::vector<ExtraParameter> mExtraParameterList;
public:
typedef std::list<LLPointer<LLViewerObject> > child_list_t;
@@ -630,10 +632,16 @@ public:
void dirtySpatialGroup() const;
virtual void dirtyMesh();
- virtual LLNetworkData* getParameterEntry(U16 param_type) const;
- virtual bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin);
- virtual bool getParameterEntryInUse(U16 param_type) const;
- virtual bool setParameterEntryInUse(U16 param_type, bool in_use, bool local_origin);
+ LLFlexibleObjectData* getFlexibleObjectData() const { return mFlexibleObjectDataInUse ? mFlexibleObjectData.get() : nullptr; }
+ LLLightParams* getLightParams() const { return mLightParamsInUse ? mLightParams.get() : nullptr; }
+ LLSculptParams* getSculptParams() const { return mSculptParamsInUse ? mSculptParams.get() : nullptr; }
+ LLLightImageParams* getLightImageParams() const { return mLightImageParamsInUse ? mLightImageParams.get() : nullptr; }
+ LLExtendedMeshParams* getExtendedMeshParams() const { return mExtendedMeshParamsInUse ? mExtendedMeshParams.get() : nullptr; }
+ LLRenderMaterialParams* getRenderMaterialParams() const { return mRenderMaterialParamsInUse ? mRenderMaterialParams.get() : nullptr; }
+ LLReflectionProbeParams* getReflectionProbeParams() const { return mReflectionProbeParamsInUse ? mReflectionProbeParams.get() : nullptr; }
+
+ bool setParameterEntry(U16 param_type, const LLNetworkData& new_value, bool local_origin);
+ bool setParameterEntryInUse(U16 param_type, bool in_use, bool local_origin);
// Called when a parameter is changed
virtual void parameterChanged(U16 param_type, bool local_origin);
virtual void parameterChanged(U16 param_type, LLNetworkData* data, bool in_use, bool local_origin);
@@ -675,8 +683,31 @@ private:
bool isAssetInInventory(LLViewerInventoryItem* item, LLAssetType::EType type);
ExtraParameter* createNewParameterEntry(U16 param_type);
- ExtraParameter* getExtraParameterEntry(U16 param_type) const;
- ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
+ const ExtraParameter& getExtraParameterEntry(U16 param_type) const
+ {
+ return mExtraParameterList[U32(param_type >> 4) - 1];
+ }
+ ExtraParameter& getExtraParameterEntry(U16 param_type)
+ {
+ return mExtraParameterList[U32(param_type >> 4) - 1];
+ }
+ ExtraParameter* getExtraParameterEntryCreate(U16 param_type)
+ {
+ if (param_type <= LLNetworkData::PARAMS_MAX)
+ {
+ ExtraParameter& param = getExtraParameterEntry(param_type);
+ if (!param.is_invalid)
+ {
+ if (!param.data)
+ {
+ ExtraParameter* new_entry = createNewParameterEntry(param_type);
+ return new_entry;
+ }
+ return &param;
+ }
+ }
+ return nullptr;
+ }
bool unpackParameterEntry(U16 param_type, LLDataPacker *dp);
// This function checks to see if the given media URL has changed its version
@@ -749,6 +780,21 @@ private:
// Grabbed from UPDATE_FLAGS
U32 mFlags;
+ bool mFlexibleObjectDataInUse = false,
+ mLightParamsInUse = false,
+ mSculptParamsInUse = false,
+ mLightImageParamsInUse = false,
+ mExtendedMeshParamsInUse = false,
+ mRenderMaterialParamsInUse = false,
+ mReflectionProbeParamsInUse = false;
+ std::unique_ptr<LLFlexibleObjectData> mFlexibleObjectData;
+ std::unique_ptr<LLLightParams> mLightParams;
+ std::unique_ptr<LLSculptParams> mSculptParams;
+ std::unique_ptr<LLLightImageParams> mLightImageParams;
+ std::unique_ptr<LLExtendedMeshParams> mExtendedMeshParams;
+ std::unique_ptr<LLRenderMaterialParams> mRenderMaterialParams;
+ std::unique_ptr<LLReflectionProbeParams> mReflectionProbeParams;
+
static std::map<std::string, U32> sObjectDataMap;
public:
// Sent to sim in UPDATE_FLAGS, received in ObjectPhysicsProperties
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 1b38fed3bb..50edb408c7 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -65,6 +65,7 @@
#include "lltoolmgr.h"
#include "lltoolpie.h"
#include "llkeyboard.h"
+#include "llmeshrepository.h"
#include "u64.h"
#include "llviewertexturelist.h"
#include "lldatapacker.h"
@@ -1398,6 +1399,8 @@ void LLViewerObjectList::killAllObjects()
llassert((objectp == gAgentAvatarp) || objectp->isDead());
}
+ gMeshRepo.unregisterAllMeshes();
+
cleanDeadObjects(false);
if(!mObjects.empty())
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index 83b8aa8d03..fb6fa8bac4 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -312,7 +312,6 @@ public:
//virtual
bool isRecentlyVisible() const;
- LLViewerOctreePartition* getSpatialPartition()const {return mSpatialPartition;}
bool isAnyRecentlyVisible() const;
static U32 getNewOcclusionQueryObjectName();
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 432da2e990..6a029645fb 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -881,7 +881,8 @@ LLParcel* LLViewerParcelMgr::getCollisionParcel() const
void LLViewerParcelMgr::render()
{
- if (mSelected && mRenderSelection && gSavedSettings.getBOOL("RenderParcelSelection") && !gDisconnected)
+ static LLCachedControl<bool> render_parcel_selection(gSavedSettings, "RenderParcelSelection");
+ if (mSelected && mRenderSelection && render_parcel_selection() && !gDisconnected)
{
// Rendering is done in agent-coordinates, so need to supply
// an appropriate offset to the render code.
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index cf92850762..17d2edee4d 100755
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -63,9 +63,9 @@ LLUIColor LLViewerParcelOverlay::sForSaleColor;
LLUIColor LLViewerParcelOverlay::sAuctionColor;
LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_width_meters)
-: mRegion( region ),
- mParcelGridsPerEdge( S32( region_width_meters / PARCEL_GRID_STEP_METERS ) ),
- mDirty( false ),
+: mRegion(region),
+ mParcelGridsPerEdge(S32(region_width_meters / PARCEL_GRID_STEP_METERS)),
+ mDirty(false),
mTimeSinceLastUpdate(),
mOverlayTextureIdx(-1)
{
@@ -467,9 +467,9 @@ void LLViewerParcelOverlay::updatePropertyLines()
{
for (S32 col = 0; col < GRIDS_PER_EDGE; col++)
{
- U8 overlay = mOwnership[row*GRIDS_PER_EDGE+col];
+ U8 overlay = mOwnership[row * GRIDS_PER_EDGE + col];
S32 colorIndex = overlay & PARCEL_COLOR_MASK;
- switch(colorIndex)
+ switch (colorIndex)
{
case PARCEL_SELF:
case PARCEL_GROUP:
@@ -483,11 +483,11 @@ void LLViewerParcelOverlay::updatePropertyLines()
const LLColor4U& color = colors[colorIndex];
- F32 left = col*GRID_STEP;
- F32 right = left+GRID_STEP;
+ F32 left = col * GRID_STEP;
+ F32 right = left + GRID_STEP;
- F32 bottom = row*GRID_STEP;
- F32 top = bottom+GRID_STEP;
+ F32 bottom = row * GRID_STEP;
+ F32 top = bottom + GRID_STEP;
// West edge
if (overlay & PARCEL_WEST_LINE)
@@ -528,99 +528,121 @@ void LLViewerParcelOverlay::addPropertyLine(F32 start_x, F32 start_y, F32 dx, F3
Edge& edge = mEdges.back();
edge.color = color;
+ // Detailized rendering vertices:
+ // A B C D E F G
+ // *-*------*--------*--------*------*-* : 'outside' vertices are placed right on the border
+ // *------*--------*--------*------* : 'inside' vertices are shifted on LINE_WIDTH inside
+
+ // Simplified rendering vertices:
+ // A G
+ // *-----------------------------------*
+ // *-----------------------------------*
+
F32 outside_x = start_x;
F32 outside_y = start_y;
- F32 outside_z = 0.f;
- F32 inside_x = start_x + tick_dx;
- F32 inside_y = start_y + tick_dy;
- F32 inside_z = 0.f;
+ F32 outside_z = land.resolveHeightRegion(outside_x, outside_y);
+ F32 inside_x = start_x + tick_dx;
+ F32 inside_y = start_y + tick_dy;
+ F32 inside_z = land.resolveHeightRegion(inside_x, inside_y);
+
+ auto move = [&](F32 distance)
+ {
+ outside_x += dx * distance;
+ outside_y += dy * distance;
+ outside_z = land.resolveHeightRegion(outside_x, outside_y);
+ inside_x += dx * distance;
+ inside_y += dy * distance;
+ inside_z = land.resolveHeightRegion(inside_x, inside_y);
+ };
- auto split = [&](const LLVector3& start, F32 x, F32 y, F32 z, F32 part)
+ auto split = [&](U32 lod, const LLVector4a& start, F32 x, F32 y, F32 z, F32 part)
{
- F32 new_x = start.mV[VX] + (x - start.mV[VX]) * part;
- F32 new_y = start.mV[VY] + (y - start.mV[VY]) * part;
- F32 new_z = start.mV[VZ] + (z - start.mV[VZ]) * part;
- edge.vertices.emplace_back(new_x, new_y, new_z);
+ F32 new_x = start[VX] + (x - start[VX]) * part;
+ F32 new_y = start[VY] + (y - start[VY]) * part;
+ edge.pushVertex(lod, new_x, new_y, water_z, 0);
};
- auto checkForSplit = [&]()
+ auto checkForSplit = [&](U32 lod)
{
- const LLVector3& last_outside = edge.vertices.back();
- F32 z0 = last_outside.mV[VZ];
+ const std::vector<LLVector4a>& vertices = edge.verticesUnderWater[lod];
+ const LLVector4a& last_outside = vertices.back();
+ F32 z0 = last_outside[VZ];
F32 z1 = outside_z;
if ((z0 >= water_z && z1 >= water_z) || (z0 < water_z && z1 < water_z))
return;
F32 part = (water_z - z0) / (z1 - z0);
- const LLVector3& last_inside = edge.vertices[edge.vertices.size() - 2];
- split(last_inside, inside_x, inside_y, inside_z, part);
- split(last_outside, outside_x, outside_y, outside_z, part);
+ const LLVector4a& last_inside = vertices[vertices.size() - 2];
+ split(lod, last_inside, inside_x, inside_y, inside_z, part);
+ split(lod, last_outside, outside_x, outside_y, outside_z, part);
};
- // First part, only one vertex
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
-
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
-
- inside_x += dx * LINE_WIDTH;
- inside_y += dy * LINE_WIDTH;
-
- outside_x += dx * LINE_WIDTH;
- outside_y += dy * LINE_WIDTH;
-
- // Then the "actual edge"
- inside_z = land.resolveHeightRegion( inside_x, inside_y );
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
+ auto pushTwoVertices = [&](U32 lod)
+ {
+ LLVector3 out(outside_x, outside_y, outside_z);
+ LLVector3 in(inside_x, inside_y, inside_z);
+ if (fabs(inside_z - outside_z) < LINE_WIDTH / 5)
+ {
+ edge.pushVertex(lod, inside_x, inside_y, inside_z, water_z);
+ }
+ else
+ {
+ // Make the line thinner if heights differ too much
+ LLVector3 dist(in - out);
+ F32 coef = dist.length() / LINE_WIDTH;
+ LLVector3 new_in(out + dist / coef);
+ edge.pushVertex(lod, new_in[VX], new_in[VY], new_in[VZ], water_z);
+ }
+ edge.pushVertex(lod, outside_x, outside_y, outside_z, water_z);
+ };
- edge.vertices.emplace_back(inside_x, inside_y, inside_z);
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
+ // Point A simplified (first two vertices)
+ pushTwoVertices(1);
- inside_x += dx * (dx - LINE_WIDTH);
- inside_y += dy * (dy - LINE_WIDTH);
+ // Point A detailized (only one vertex)
+ edge.pushVertex(0, outside_x, outside_y, outside_z, water_z);
- outside_x += dx * (dx - LINE_WIDTH);
- outside_y += dy * (dy - LINE_WIDTH);
+ // Point B (two vertices)
+ move(LINE_WIDTH);
+ pushTwoVertices(0);
- // Middle part, full width
+ // Points C, D, E
+ F32 distance = 1.f - LINE_WIDTH;
constexpr S32 GRID_STEP = (S32)PARCEL_GRID_STEP_METERS;
- for (S32 i = 1; i < GRID_STEP; i++)
+ for (U32 i = 1; i < GRID_STEP; ++i)
{
- inside_z = land.resolveHeightRegion( inside_x, inside_y );
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
-
- checkForSplit();
-
- edge.vertices.emplace_back(inside_x, inside_y, inside_z);
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
-
- inside_x += dx;
- inside_y += dy;
-
- outside_x += dx;
- outside_y += dy;
+ move(distance);
+ checkForSplit(0);
+ pushTwoVertices(0);
+ distance = 1.f;
}
- // Extra buffer for edge
- inside_x -= dx * LINE_WIDTH;
- inside_y -= dy * LINE_WIDTH;
-
- outside_x -= dx * LINE_WIDTH;
- outside_y -= dy * LINE_WIDTH;
-
- inside_z = land.resolveHeightRegion( inside_x, inside_y );
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
-
- checkForSplit();
+ // Point F (two vertices)
+ move(1.f - LINE_WIDTH);
+ checkForSplit(0);
+ pushTwoVertices(0);
- edge.vertices.emplace_back(inside_x, inside_y, inside_z);
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
+ // Point G simplified (last two vertices)
+ move(LINE_WIDTH);
+ pushTwoVertices(1);
- outside_x += dx * LINE_WIDTH;
- outside_y += dy * LINE_WIDTH;
+ // Point G detailized (only one vertex)
+ edge.pushVertex(0, outside_x, outside_y, outside_z, water_z);
+}
- // Last edge is not drawn to the edge
- outside_z = land.resolveHeightRegion( outside_x, outside_y );
+void LLViewerParcelOverlay::Edge::pushVertex(U32 lod, F32 x, F32 y, F32 z, F32 water_z)
+{
+ verticesUnderWater[lod].emplace_back(x, y, z);
+ gGL.transform(verticesUnderWater[lod].back());
- edge.vertices.emplace_back(outside_x, outside_y, outside_z);
+ if (z >= water_z)
+ {
+ verticesAboveWater[lod].push_back(verticesUnderWater[lod].back());
+ }
+ else
+ {
+ verticesAboveWater[lod].emplace_back(x, y, water_z);
+ gGL.transform(verticesAboveWater[lod].back());
+ }
}
void LLViewerParcelOverlay::setDirty()
@@ -665,6 +687,9 @@ void LLViewerParcelOverlay::renderPropertyLines()
if (!show)
return;
+ LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_GPU_ZONE("Property Lines");
+
LLSurface& land = mRegion->getLand();
bool render_water = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER);
@@ -702,6 +727,8 @@ void LLViewerParcelOverlay::renderPropertyLines()
// Stomp the camera into two dimensions
LLVector3 camera_region = mRegion->getPosRegionFromGlobal( gAgentCamera.getCameraPositionGlobal() );
+ bool draw_underwater = camera_region.mV[VZ] < water_z ||
+ !gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_WATER);
// Set up a cull plane 2 * PARCEL_GRID_STEP_METERS behind
// the camera. The cull plane normal is the camera's at axis.
@@ -709,15 +736,23 @@ void LLViewerParcelOverlay::renderPropertyLines()
cull_plane_point *= -2.f * PARCEL_GRID_STEP_METERS;
cull_plane_point += camera_region;
- bool render_hidden = LLSelectMgr::sRenderHiddenSelections && LLFloaterReg::instanceVisible("build");
+ bool render_hidden = !draw_underwater &&
+ LLSelectMgr::sRenderHiddenSelections &&
+ LLFloaterReg::instanceVisible("build");
constexpr F32 PROPERTY_LINE_CLIP_DIST_SQUARED = 256.f * 256.f;
+ const F32 PROPERTY_LINE_LOD0_DIST_SQUARED = PROPERTY_LINE_CLIP_DIST_SQUARED / 25;
for (const Edge& edge : mEdges)
{
- LLVector3 center = edge.vertices[edge.vertices.size() >> 1];
+ const std::vector<LLVector4a>& vertices0 = edge.verticesAboveWater[0];
+ const F32* first = vertices0.front().getF32ptr();
+ const F32* last = vertices0.back().getF32ptr();
+ LLVector3 center((first[VX] + last[VX]) / 2, (first[VY] + last[VY]) / 2, (first[VZ] + last[VZ]) / 2);
+ gGL.untransform(center);
- if (dist_vec_squared2D(center, camera_region) > PROPERTY_LINE_CLIP_DIST_SQUARED)
+ F32 dist_squared = dist_vec_squared(center, camera_region);
+ if (dist_squared > PROPERTY_LINE_CLIP_DIST_SQUARED)
{
continue;
}
@@ -731,43 +766,33 @@ void LLViewerParcelOverlay::renderPropertyLines()
continue;
}
+ U32 lod = dist_squared < PROPERTY_LINE_LOD0_DIST_SQUARED ? 0 : 1;
+
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.color4ubv(edge.color.mV);
- for (const LLVector3& vertex : edge.vertices)
+ if (draw_underwater)
{
- if (render_hidden || camera_z < water_z || vertex.mV[2] >= water_z)
- {
- gGL.vertex3fv(vertex.mV);
- }
- else
- {
- LLVector3 visible = vertex;
- visible.mV[VZ] = water_z;
- gGL.vertex3fv(visible.mV);
- }
+ gGL.vertexBatchPreTransformed(edge.verticesUnderWater[lod]);
}
-
- gGL.end();
-
- if (render_hidden)
+ else
{
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
+ gGL.vertexBatchPreTransformed(edge.verticesAboveWater[lod]);
- gGL.begin(LLRender::TRIANGLE_STRIP);
+ if (render_hidden)
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
- LLColor4U color = edge.color;
- color.mV[VALPHA] /= 4;
- gGL.color4ubv(color.mV);
+ LLColor4U color = edge.color;
+ color.mV[VALPHA] /= 4;
+ gGL.color4ubv(color.mV);
- for (const LLVector3& vertex : edge.vertices)
- {
- gGL.vertex3fv(vertex.mV);
+ gGL.vertexBatchPreTransformed(edge.verticesUnderWater[lod]);
}
-
- gGL.end();
}
+
+ gGL.end();
}
gGL.popMatrix();
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 50bef02ddf..7271c85701 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -116,7 +116,10 @@ private:
struct Edge
{
- std::vector<LLVector3> vertices;
+ void pushVertex(U32 lod, F32 x, F32 y, F32 z, F32 water_z);
+ // LOD: 0 - detailized, 1 - simplified
+ std::vector<LLVector4a> verticesAboveWater[2];
+ std::vector<LLVector4a> verticesUnderWater[2];
LLColor4U color;
};
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index c77dd9cc08..a3c241456d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1332,7 +1332,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
// Check the whitelist, if there's media (otherwise just show it)
if (te->getMediaData() == NULL || te->getMediaData()->checkCandidateUrl(url))
{
- if ( obj != mDragHoveredObject.get())
+ if (obj != mDragHoveredObject)
{
// Highlight the dragged object
LLSelectMgr::getInstance()->unhighlightObjectOnly(mDragHoveredObject);
@@ -3394,13 +3394,11 @@ void append_xui_tooltip(LLView* viewp, LLToolTip::Params& params)
}
}
-static LLTrace::BlockTimerStatHandle ftm("Update UI");
-
// Update UI based on stored mouse position from mouse-move
// event processing.
void LLViewerWindow::updateUI()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(ftm);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
static std::string last_handle_msg;
@@ -3418,12 +3416,15 @@ void LLViewerWindow::updateUI()
}
}
- LLConsole::updateClass();
+ {
+ LL_PROFILE_ZONE_NAMED("UI updateClass");
+ LLConsole::updateClass();
- // execute postponed arrange calls
- LLAccordionCtrl::updateClass();
- // animate layout stacks so we have up to date rect for world view
- LLLayoutStack::updateClass();
+ // execute postponed arrange calls
+ LLAccordionCtrl::updateClass();
+ // animate layout stacks so we have up to date rect for world view
+ LLLayoutStack::updateClass();
+ }
// use full window for world view when not rendering UI
bool world_view_uses_full_window = gAgentCamera.cameraMouselook() || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
@@ -3852,6 +3853,7 @@ void LLViewerWindow::updateUI()
void LLViewerWindow::updateLayout()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
if (gFloaterTools != NULL
&& tool != NULL
@@ -4331,15 +4333,15 @@ void LLViewerWindow::pickAsync( S32 x,
bool pick_unselectable,
bool pick_reflection_probes)
{
+ static LLCachedControl<bool> select_invisible_objects(gSavedSettings, "SelectInvisibleObjects");
// "Show Debug Alpha" means no object actually transparent
bool in_build_mode = LLFloaterReg::instanceVisible("build");
- if (LLDrawPoolAlpha::sShowDebugAlpha
- || (in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")))
+ if (LLDrawPoolAlpha::sShowDebugAlpha || (in_build_mode && select_invisible_objects))
{
pick_transparent = true;
}
- LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, false, pick_reflection_probes, pick_unselectable, true, callback);
+ LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, false, pick_reflection_probes, true, pick_unselectable, callback);
schedulePick(pick_info);
}
@@ -4363,7 +4365,6 @@ void LLViewerWindow::schedulePick(LLPickInfo& pick_info)
mWindow->delayInputProcessing();
}
-
void LLViewerWindow::performPick()
{
if (!mPicks.empty())
@@ -4397,8 +4398,9 @@ void LLViewerWindow::returnEmptyPicks()
// Performs the GL object/land pick.
LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, bool pick_transparent, bool pick_rigged, bool pick_particle, bool pick_unselectable, bool pick_reflection_probe)
{
+ static LLCachedControl<bool> select_invisible_objects(gSavedSettings, "SelectInvisibleObjects");
bool in_build_mode = LLFloaterReg::instanceVisible("build");
- if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha)
+ if ((in_build_mode && select_invisible_objects) || LLDrawPoolAlpha::sShowDebugAlpha)
{
// build mode allows interaction with all transparent objects
// "Show Debug Alpha" means no object actually transparent
@@ -4406,7 +4408,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, bool pick_transp
}
// shortcut queueing in mPicks and just update mLastPick in place
- MASK key_mask = gKeyboard->currentMask(true);
+ MASK key_mask = gKeyboard->currentMask(true);
mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, true, false, NULL);
mLastPick.fetchResults();
@@ -6131,14 +6133,14 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
bool pick_rigged,
bool pick_particle,
bool pick_reflection_probe,
- bool pick_uv_coords,
+ bool pick_surface_info,
bool pick_unselectable,
void (*pick_callback)(const LLPickInfo& pick_info))
: mMousePt(mouse_pos),
mKeyMask(keyboard_mask),
mPickCallback(pick_callback),
mPickType(PICK_INVALID),
- mWantSurfaceInfo(pick_uv_coords),
+ mWantSurfaceInfo(pick_surface_info),
mObjectFace(-1),
mUVCoords(-1.f, -1.f),
mSTCoords(-1.f, -1.f),
diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp
index 085e386ec9..d1de2f55da 100644
--- a/indra/newview/llvoicewebrtc.cpp
+++ b/indra/newview/llvoicewebrtc.cpp
@@ -2549,10 +2549,7 @@ void LLVoiceWebRTCConnection::OnRenegotiationNeeded()
LL::WorkQueue::postMaybe(mMainQueue,
[=, this] {
LL_DEBUGS("Voice") << "Voice channel requires renegotiation." << LL_ENDL;
- if (!mShutDown)
- {
- setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
- }
+ setVoiceConnectionState(VOICE_STATE_SESSION_RETRY);
mCurrentStatus = LLVoiceClientStatusObserver::ERROR_UNKNOWN;
});
}
@@ -2898,9 +2895,10 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
// this connection.
// For spatial this connection will come up as muted, but will be set to the appropriate
// value later on when we determine the regions we connect to.
- if (!isSpatial())
+ if (isSpatial())
{
- mWebRTCAudioInterface->setMute(mMuted);
+ // we'll determine primary state later and set mute accordinly
+ mPrimary = false;
}
mWebRTCAudioInterface->setReceiveVolume(mSpeakerVolume);
LLWebRTCVoiceClient::getInstance()->OnConnectionEstablished(mChannelID, mRegionID);
@@ -2924,6 +2922,10 @@ bool LLVoiceWebRTCConnection::connectionStateMachine()
LLWebRTCVoiceClient::getInstance()->updatePosition();
LLWebRTCVoiceClient::getInstance()->sendPositionUpdate(true);
}
+ else
+ {
+ mWebRTCAudioInterface->setMute(mMuted);
+ }
}
break;
}
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 9c0f4baf28..b328d3a414 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -250,10 +250,12 @@ LLVOVolume::~LLVOVolume()
delete mVolumeImpl;
mVolumeImpl = NULL;
- gMeshRepo.unregisterMesh(this);
+ unregisterOldMeshAndSkin();
if(!mMediaImplList.empty())
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_MEDIA("delete volume media list");
+
for(U32 i = 0 ; i < mMediaImplList.size() ; i++)
{
if(mMediaImplList[i].notNull())
@@ -351,7 +353,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
U8 sculpt_type = 0;
if (isSculpted())
{
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = getSculptParams();
if (sculpt_params)
{
sculpt_id = sculpt_params->getSculptTexture();
@@ -924,7 +926,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
if (getLightTextureID().notNull())
{
- LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ LLLightImageParams* params = getLightImageParams();
LLUUID id = params->getLightTexture();
mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE);
if (mLightTexture.notNull())
@@ -1048,6 +1050,28 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
return mDrawable;
}
+// Inverse of gMeshRepo.loadMesh and gMeshRepo.getSkinInfo, combined into one function
+// Assume a Collada mesh never changes after being set.
+void LLVOVolume::unregisterOldMeshAndSkin()
+{
+ if (mVolumep)
+ {
+ const LLVolumeParams& params = mVolumep->getParams();
+ if ((params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
+ {
+ // object is being deleted, so it will no longer need to request
+ // meshes.
+ for (S32 lod = 0; lod != LLVolumeLODGroup::NUM_LODS; ++lod)
+ {
+ gMeshRepo.unregisterMesh(this, params, lod);
+ }
+ // This volume may or may not have a skin
+ gMeshRepo.unregisterSkinInfo(params.getSculptID(), this);
+ }
+ }
+}
+
+
bool LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bool unique_volume)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
@@ -1082,7 +1106,7 @@ bool LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
setParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE, true, false);
if (!mVolumeImpl)
{
- LLFlexibleObjectData* data = (LLFlexibleObjectData*)getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
+ LLFlexibleObjectData* data = getFlexibleObjectData();
mVolumeImpl = new LLVolumeImplFlexible(this, data);
}
}
@@ -1193,7 +1217,7 @@ void LLVOVolume::updateSculptTexture()
if (isSculpted() && !isMesh())
{
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLSculptParams *sculpt_params = getSculptParams();
if (sculpt_params)
{
LLUUID id = sculpt_params->getSculptTexture();
@@ -3053,7 +3077,7 @@ void LLVOVolume::setLightTextureID(LLUUID id)
{
old_texturep->removeVolume(LLRender::LIGHT_TEX, this);
}
- LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ LLLightImageParams* param_block = getLightImageParams();
if (param_block && param_block->getLightTexture() != id)
{
param_block->setLightTexture(id);
@@ -3083,7 +3107,7 @@ void LLVOVolume::setLightTextureID(LLUUID id)
void LLVOVolume::setSpotLightParams(LLVector3 params)
{
- LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ LLLightImageParams* param_block = getLightImageParams();
if (param_block && param_block->getParams() != params)
{
param_block->setParams(params);
@@ -3125,7 +3149,7 @@ void LLVOVolume::setLightSRGBColor(const LLColor3& color)
void LLVOVolume::setLightLinearColor(const LLColor3& color)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getLinearColor() != color)
@@ -3140,7 +3164,7 @@ void LLVOVolume::setLightLinearColor(const LLColor3& color)
void LLVOVolume::setLightIntensity(F32 intensity)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getLinearColor().mV[3] != intensity)
@@ -3153,7 +3177,7 @@ void LLVOVolume::setLightIntensity(F32 intensity)
void LLVOVolume::setLightRadius(F32 radius)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getRadius() != radius)
@@ -3166,7 +3190,7 @@ void LLVOVolume::setLightRadius(F32 radius)
void LLVOVolume::setLightFalloff(F32 falloff)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getFalloff() != falloff)
@@ -3179,7 +3203,7 @@ void LLVOVolume::setLightFalloff(F32 falloff)
void LLVOVolume::setLightCutoff(F32 cutoff)
{
- LLLightParams *param_block = (LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ LLLightParams *param_block = getLightParams();
if (param_block)
{
if (param_block->getCutoff() != cutoff)
@@ -3194,7 +3218,7 @@ void LLVOVolume::setLightCutoff(F32 cutoff)
bool LLVOVolume::getIsLight() const
{
- mIsLight = getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
+ mIsLight = getLightParams() != nullptr;
return mIsLight;
}
@@ -3210,7 +3234,7 @@ LLColor3 LLVOVolume::getLightSRGBBaseColor() const
LLColor3 LLVOVolume::getLightLinearBaseColor() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return LLColor3(param_block->getLinearColor());
@@ -3223,7 +3247,7 @@ LLColor3 LLVOVolume::getLightLinearBaseColor() const
LLColor3 LLVOVolume::getLightLinearColor() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return LLColor3(param_block->getLinearColor()) * param_block->getLinearColor().mV[3];
@@ -3241,33 +3265,27 @@ LLColor3 LLVOVolume::getLightSRGBColor() const
return ret;
}
-LLUUID LLVOVolume::getLightTextureID() const
+const LLUUID& LLVOVolume::getLightTextureID() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ const LLLightImageParams *param_block = getLightImageParams();
+ if (param_block)
{
- const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (param_block)
- {
- return param_block->getLightTexture();
- }
+ return param_block->getLightTexture();
}
return LLUUID::null;
}
-LLVector3 LLVOVolume::getSpotLightParams() const
+const LLVector3& LLVOVolume::getSpotLightParams() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ const LLLightImageParams *param_block = getLightImageParams();
+ if (param_block)
{
- const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (param_block)
- {
- return param_block->getParams();
- }
+ return param_block->getParams();
}
- return LLVector3();
+ return LLVector3::zero;
}
F32 LLVOVolume::getSpotLightPriority() const
@@ -3304,8 +3322,8 @@ void LLVOVolume::updateSpotLightPriority()
bool LLVOVolume::isLightSpotlight() const
{
- LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ const LLLightImageParams* params = getLightImageParams();
+ if (params)
{
return params->isLightSpotlight();
}
@@ -3315,7 +3333,7 @@ bool LLVOVolume::isLightSpotlight() const
LLViewerTexture* LLVOVolume::getLightTexture()
{
- LLUUID id = getLightTextureID();
+ const LLUUID& id = getLightTextureID();
if (id.notNull())
{
@@ -3326,7 +3344,7 @@ LLViewerTexture* LLVOVolume::getLightTexture()
}
else
{
- mLightTexture = NULL;
+ mLightTexture = nullptr;
}
return mLightTexture;
@@ -3334,7 +3352,7 @@ LLViewerTexture* LLVOVolume::getLightTexture()
F32 LLVOVolume::getLightIntensity() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return param_block->getLinearColor().mV[3];
@@ -3347,7 +3365,7 @@ F32 LLVOVolume::getLightIntensity() const
F32 LLVOVolume::getLightRadius() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return param_block->getRadius();
@@ -3360,7 +3378,7 @@ F32 LLVOVolume::getLightRadius() const
F32 LLVOVolume::getLightFalloff(const F32 fudge_factor) const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return param_block->getFalloff() * fudge_factor;
@@ -3373,7 +3391,7 @@ F32 LLVOVolume::getLightFalloff(const F32 fudge_factor) const
F32 LLVOVolume::getLightCutoff() const
{
- const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT);
+ const LLLightParams *param_block = getLightParams();
if (param_block)
{
return param_block->getCutoff();
@@ -3386,7 +3404,7 @@ F32 LLVOVolume::getLightCutoff() const
bool LLVOVolume::isReflectionProbe() const
{
- return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ return getReflectionProbeParams() != nullptr;
}
bool LLVOVolume::setIsReflectionProbe(bool is_probe)
@@ -3411,7 +3429,7 @@ bool LLVOVolume::setIsReflectionProbe(bool is_probe)
bool LLVOVolume::setReflectionProbeAmbiance(F32 ambiance)
{
- LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getAmbiance() != ambiance)
@@ -3427,7 +3445,7 @@ bool LLVOVolume::setReflectionProbeAmbiance(F32 ambiance)
bool LLVOVolume::setReflectionProbeNearClip(F32 near_clip)
{
- LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getClipDistance() != near_clip)
@@ -3443,7 +3461,7 @@ bool LLVOVolume::setReflectionProbeNearClip(F32 near_clip)
bool LLVOVolume::setReflectionProbeIsBox(bool is_box)
{
- LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getIsBox() != is_box)
@@ -3459,7 +3477,7 @@ bool LLVOVolume::setReflectionProbeIsBox(bool is_box)
bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
{
- LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getIsDynamic() != is_dynamic)
@@ -3475,7 +3493,7 @@ bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror)
{
- LLReflectionProbeParams *param_block = (LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
if (param_block->getIsMirror() != is_mirror)
@@ -3498,7 +3516,7 @@ bool LLVOVolume::setReflectionProbeIsMirror(bool is_mirror)
F32 LLVOVolume::getReflectionProbeAmbiance() const
{
- const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getAmbiance();
@@ -3511,7 +3529,7 @@ F32 LLVOVolume::getReflectionProbeAmbiance() const
F32 LLVOVolume::getReflectionProbeNearClip() const
{
- const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getClipDistance();
@@ -3524,7 +3542,7 @@ F32 LLVOVolume::getReflectionProbeNearClip() const
bool LLVOVolume::getReflectionProbeIsBox() const
{
- const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getIsBox();
@@ -3535,7 +3553,7 @@ bool LLVOVolume::getReflectionProbeIsBox() const
bool LLVOVolume::getReflectionProbeIsDynamic() const
{
- const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getIsDynamic();
@@ -3546,8 +3564,7 @@ bool LLVOVolume::getReflectionProbeIsDynamic() const
bool LLVOVolume::getReflectionProbeIsMirror() const
{
- const LLReflectionProbeParams *param_block =
- (const LLReflectionProbeParams *) getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ const LLReflectionProbeParams* param_block = getReflectionProbeParams();
if (param_block)
{
return param_block->getIsMirror();
@@ -3568,7 +3585,7 @@ U32 LLVOVolume::getVolumeInterfaceID() const
bool LLVOVolume::isFlexible() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE))
+ if (getFlexibleObjectData())
{
LLVolume* volume = getVolume();
if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE)
@@ -3587,7 +3604,7 @@ bool LLVOVolume::isFlexible() const
bool LLVOVolume::isSculpted() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ if (getSculptParams())
{
return true;
}
@@ -3599,7 +3616,7 @@ bool LLVOVolume::isMesh() const
{
if (isSculpted())
{
- LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ const LLSculptParams *sculpt_params = getSculptParams();
if (sculpt_params)
{
U8 sculpt_type = sculpt_params->getSculptType();
@@ -3617,7 +3634,7 @@ bool LLVOVolume::isMesh() const
bool LLVOVolume::hasLightTexture() const
{
- if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
+ if (getLightImageParams())
{
return true;
}
@@ -3737,8 +3754,7 @@ bool LLVOVolume::isRiggedMesh() const
//----------------------------------------------------------------------------
U32 LLVOVolume::getExtendedMeshFlags() const
{
- const LLExtendedMeshParams *param_block =
- (const LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
+ const LLExtendedMeshParams *param_block = getExtendedMeshParams();
if (param_block)
{
return param_block->getFlags();
@@ -3783,8 +3799,7 @@ void LLVOVolume::setExtendedMeshFlags(U32 flags)
{
bool in_use = true;
setParameterEntryInUse(LLNetworkData::PARAMS_EXTENDED_MESH, in_use, true);
- LLExtendedMeshParams *param_block =
- (LLExtendedMeshParams *)getParameterEntry(LLNetworkData::PARAMS_EXTENDED_MESH);
+ LLExtendedMeshParams *param_block = (LLExtendedMeshParams *)getExtendedMeshParams();
if (param_block)
{
param_block->setFlags(flags);
@@ -3842,11 +3857,12 @@ void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_pare
}
if (old_volp && old_volp->isAnimatedObject())
{
- if (old_volp->getControlAvatar())
+ LLControlAvatar* cav = old_volp->getControlAvatar();
+ if (cav)
{
// We have been removed from an animated object, need to do cleanup.
- old_volp->getControlAvatar()->updateAttachmentOverrides();
- old_volp->getControlAvatar()->updateAnimations();
+ cav->updateAttachmentOverrides();
+ cav->updateAnimations();
}
}
}
@@ -5131,7 +5147,7 @@ U32 LLVOVolume::getPartitionType() const
{
return LLViewerRegion::PARTITION_HUD;
}
- if (isAnimatedObject() && getControlAvatar())
+ if (isAnimatedObjectFast() && getControlAvatar())
{
return LLViewerRegion::PARTITION_CONTROL_AV;
}
@@ -5757,11 +5773,18 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
// Standard rigged mesh attachments:
- bool rigged = !vobj->isAnimatedObject() && skinInfo && vobj->isAttachment();
+ bool is_animated = vobj->isAnimatedObject();
+ bool rigged = !is_animated && skinInfo && vobj->isAttachment();
// Animated objects. Have to check for isRiggedMesh() to
// exclude static objects in animated object linksets.
- rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() &&
- vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying);
+ if (!rigged && is_animated && vobj->isRiggedMesh())
+ {
+ LLControlAvatar* cav = vobj->getControlAvatar();
+ if (cav)
+ {
+ rigged = cav->mPlaying;
+ }
+ }
bool any_rigged_face = false;
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 97a5131260..b6044bc319 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -227,6 +227,7 @@ public:
void setTexture(const S32 face);
S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];}
+ void unregisterOldMeshAndSkin();
/*virtual*/ bool setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override;
void updateSculptTexture();
void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;}
@@ -283,9 +284,9 @@ public:
// Get the light color in sRGB color space scaled by intensity.
LLColor3 getLightSRGBColor() const;
- LLUUID getLightTextureID() const;
+ const LLUUID& getLightTextureID() const;
bool isLightSpotlight() const;
- LLVector3 getSpotLightParams() const;
+ const LLVector3& getSpotLightParams() const;
void updateSpotLightPriority();
F32 getSpotLightPriority() const;
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 614d1afc2a..072743505f 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "llwatchdog.h"
+#include "llmutex.h"
#include "llthread.h"
#include "llappviewer.h"
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index a319aa00bc..f603274335 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -34,6 +34,7 @@
#include "llagent.h"
#include "llappviewer.h"
+#include "llfloatermarketplace.h"
#include "llfloaterwebcontent.h"
#include "llfloaterreg.h"
#include "lllogininstance.h"
@@ -74,12 +75,20 @@ void LLWeb::loadURL(const std::string& url, const std::string& target, const std
}
// static
-// Explicitly open a Web URL using the Web content floater
+// Explicitly open a Web URL using the Web content floater or Marketplace floater
void LLWeb::loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid, bool dev_mode)
{
LLFloaterWebContent::Params p;
p.url(url).target(target).id(uuid).dev_mode(dev_mode);
- LLFloaterReg::showInstance("web_content", p);
+
+ if (LLFloaterMarketplace::isMarketplaceURL(url))
+ {
+ LLFloaterReg::showInstance("marketplace", p);
+ }
+ else
+ {
+ LLFloaterReg::showInstance("web_content", p);
+ }
}
// static
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 153bee3aef..1db36649fa 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -118,6 +118,7 @@ LLVector3d LLSimInfo::getGlobalOrigin() const
{
return from_region_handle(mHandle);
}
+
LLVector3 LLSimInfo::getLocalPos(LLVector3d global_pos) const
{
LLVector3d sim_origin = from_region_handle(mHandle);
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 6b2bd3e6fb..1be6a6cfff 100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -517,26 +517,38 @@ void LLWorldMapView::draw()
// Draw the region name in the lower left corner
if (mMapScale >= DRAW_TEXT_THRESHOLD)
{
- std::string mesg;
+ static LLCachedControl<bool> print_coords(gSavedSettings, "MapShowGridCoords");
+ static LLFontGL* font = LLFontGL::getFontSansSerifSmallBold();
+
+ auto print = [&](std::string text, F32 x, F32 y, bool use_ellipses)
+ {
+ font->renderUTF8(text, 0,
+ (F32)llfloor(left + x), (F32)llfloor(bottom + y),
+ LLColor4::white,
+ LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
+ S32_MAX, //max_chars
+ (S32)mMapScale, //max_pixels
+ NULL,
+ use_ellipses);
+ };
+
+ std::string grid_name = info->getName();
if (info->isDown())
{
- mesg = llformat( "%s (%s)", info->getName().c_str(), sStringsMap["offline"].c_str());
+ grid_name += " (" + sStringsMap["offline"] + ")";
}
- else
+
+ if (print_coords)
{
- mesg = info->getName();
+ print(grid_name, 3, 14, true);
+ // Obtain and print the grid map coordinates
+ LLVector3d region_pos = info->getGlobalOrigin();
+ std::string grid_coords = llformat("[%.0f, %.0f]", region_pos[VX] / 256, region_pos[VY] / 256);
+ print(grid_coords, 3, 2, false);
}
- if (!mesg.empty())
+ else
{
- LLFontGL::getFontSansSerifSmallBold()->renderUTF8(
- mesg, 0,
- (F32)llfloor(left + 3), (F32)llfloor(bottom + 2),
- LLColor4::white,
- LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW,
- S32_MAX, //max_chars
- (S32)mMapScale, //max_pixels
- NULL,
- /*use_ellipses*/true);
+ print(grid_name, 3, 2, true);
}
}
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 4316b850e3..3b72e512da 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -5536,7 +5536,7 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
if (light->mDrawable.notNull() && light->mDrawable->isState(LLDrawable::ACTIVE))
{
// moving lights get a little higher priority (too much causes artifacts)
- dist = llmax(dist - light->getLightRadius()*0.25f, 0.f);
+ dist = llmax(dist - radius * 0.25f, 0.f);
}
return dist;
}
diff --git a/indra/newview/skins/default/xui/en/floater_test_combobox.xml b/indra/newview/skins/default/xui/en/floater_test_combobox.xml
index 4211d624ac..0d75685223 100644
--- a/indra/newview/skins/default/xui/en/floater_test_combobox.xml
+++ b/indra/newview/skins/default/xui/en/floater_test_combobox.xml
@@ -155,4 +155,36 @@
name="item3"
value="tx" />
</combo_box>
+ <text
+ type="string"
+ length="1"
+ height="16"
+ layout="topleft"
+ left_delta="0"
+ top_pad="24"
+ width="200">
+ Multiple columns:
+ </text>
+ <combo_box
+ name="multi_column_combo"
+ layout="topleft"
+ height="20"
+ width="150"
+ left_delta="0"
+ top_pad="4">
+ <combo_item name="combo_item1" value="0">
+ <column width="40" name="label" label="|Abc|" />
+ <column name="longtext" label="Match full text" />
+ </combo_item>
+
+ <combo_item name="combo_item2" value="1">
+ <column name="label" label="*Abc*" />
+ <column name="longtext" label="Match substring" />
+ </combo_item>
+
+ <combo_item name="combo_item3" value="2">
+ <column name="label" label="/ *. /" />
+ <column name="longtext" label="Match regular expression" />
+ </combo_item>
+ </combo_box>
</floater>
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 0ce64b7a83..b0635a2229 100644
--- a/indra/newview/skins/default/xui/en/floater_world_map.xml
+++ b/indra/newview/skins/default/xui/en/floater_world_map.xml
@@ -109,7 +109,7 @@
</panel>
<panel
follows="right|top"
- height="126"
+ height="150"
top_pad="4"
width="238"
left="1"
@@ -285,6 +285,30 @@
by owner
</text>
+ <check_box
+ name="grid_coords_chk"
+ control_name="MapShowGridCoords"
+ layout="topleft"
+ follows="top|right"
+ top_pad="2"
+ left="3"
+ height="16"
+ width="22"
+ />
+ <text
+ name="grid_coords_label"
+ type="string"
+ layout="topleft"
+ follows="top|right"
+ top_delta="2"
+ left_pad="3"
+ height="16"
+ width="220"
+ halign="left"
+ length="1" >
+ Show grid map coordinates
+ </text>
+
<button
follows="top|right"
height="22"
@@ -455,7 +479,7 @@
<panel
follows="right|top|bottom"
- height="235"
+ height="220"
top_pad="0"
width="238"
name="layout_panel_4">
@@ -573,7 +597,7 @@
draw_stripes="false"
bg_writeable_color="MouseGray"
follows="all"
- height="145"
+ height="130"
layout="topleft"
left="28"
name="search_results"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index dbd513afe8..d278bac075 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -4425,9 +4425,9 @@ Click OK to install.
</notification>
<notification
- icon="alertmodal.tga"
+ icon="alert.tga"
name="PromptOptionalUpdate"
- type="alertmodal">
+ type="alert">
Version [VERSION] has been downloaded and is ready to install.
Release notes: [URL]
diff --git a/indra/newview/skins/default/xui/en/panel_group_general.xml b/indra/newview/skins/default/xui/en/panel_group_general.xml
index 7290cbb5c6..74bc7736f9 100644
--- a/indra/newview/skins/default/xui/en/panel_group_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_general.xml
@@ -86,6 +86,15 @@ Hover your mouse over the options for more help.
name="btn_join"
visible="true"
width="120" />
+ <button
+ follows="left|top"
+ left_pad="6"
+ top_delta="0"
+ height="23"
+ label="Activate"
+ name="btn_activate"
+ visible="true"
+ width="120" />
</panel>
<text_editor
type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index ddddb4855f..aa641a35f7 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -113,7 +113,7 @@
width="70">
<combo_box.item
enabled="true"
- label="1:00 AM"
+ label="1:00 PM"
name="12H"
value="0" />
<combo_box.item
diff --git a/indra/newview/skins/default/xui/en/panel_region_general.xml b/indra/newview/skins/default/xui/en/panel_region_general.xml
index 6ef1b6e44a..47e1e669d1 100644
--- a/indra/newview/skins/default/xui/en/panel_region_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_general.xml
@@ -33,6 +33,28 @@
unknown
</text>
<text
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ top_delta="0"
+ right="-100"
+ name="estate_id_lbl"
+ width="80">
+ Estate ID:
+ </text>
+ <line_editor
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ top_delta="0"
+ name="estate_id"
+ enabled="false"
+ right="-10"
+ initial_value="unknown"
+ width="85" />
+ <text
follows="left|top"
font="SansSerif"
height="20"
@@ -55,6 +77,39 @@
unknown
</text>
<text
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ top_delta="0"
+ right="-100"
+ name="grid_position_lbl"
+ width="80">
+ Grid Position:
+ </text>
+ <line_editor
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ right="-55"
+ name="grid_position_x"
+ enabled="false"
+ top_delta="0"
+ default_text="n/a"
+ width="40" />
+ <line_editor
+ follows="right|top"
+ font="SansSerif"
+ height="20"
+ layout="topleft"
+ right="-10"
+ name="grid_position_y"
+ enabled="false"
+ top_delta="0"
+ default_text="n/a"
+ width="40" />
+ <text
follows="left|top"
font="SansSerif"
height="20"