summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcharacter/llkeyframemotion.cpp34
-rw-r--r--indra/llcommon/CMakeLists.txt2
-rw-r--r--indra/llcommon/llapp.cpp44
-rw-r--r--indra/llcommon/llapp.h22
-rw-r--r--indra/llcommon/llerror.h1
-rw-r--r--indra/llcommon/llerrorthread.cpp133
-rw-r--r--indra/llcommon/llerrorthread.h46
-rw-r--r--indra/llinventory/llsettingssky.cpp1
-rw-r--r--indra/llmath/llvolume.cpp25
-rw-r--r--indra/llmath/llvolume.h9
-rw-r--r--indra/llmath/llvolumemgr.cpp18
-rw-r--r--indra/llmessage/llcachename.cpp4
-rw-r--r--indra/llprimitive/llmaterial.cpp18
-rw-r--r--indra/llprimitive/llmaterial.h2
-rw-r--r--indra/llrender/llfontgl.cpp24
-rw-r--r--indra/llrender/llfontgl.h2
-rw-r--r--indra/llrender/llimagegl.cpp9
-rw-r--r--indra/llrender/llshadermgr.cpp3
-rw-r--r--indra/llrender/llshadermgr.h1
-rw-r--r--indra/llui/llfolderviewitem.cpp2
-rw-r--r--indra/llui/lliconctrl.cpp26
-rw-r--r--indra/llui/lliconctrl.h3
-rw-r--r--indra/llui/lllayoutstack.cpp19
-rw-r--r--indra/llui/lllayoutstack.h1
-rw-r--r--indra/llui/llmenugl.cpp7
-rw-r--r--indra/llui/llmenugl.h1
-rw-r--r--indra/llui/llpanel.h1
-rw-r--r--indra/llui/lltextbase.cpp10
-rw-r--r--indra/llui/lltextbase.h2
-rw-r--r--indra/llui/lltextbox.cpp3
-rw-r--r--indra/llui/lluicolortable.cpp6
-rw-r--r--indra/llui/llview.cpp6
-rw-r--r--indra/llui/llview.h1
-rw-r--r--indra/llwindow/llwindow.h3
-rw-r--r--indra/newview/app_settings/settings.xml90
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl1
-rw-r--r--indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/previewV.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl12
-rw-r--r--indra/newview/featuretable.txt10
-rw-r--r--indra/newview/featuretable_mac.txt10
-rw-r--r--indra/newview/llappviewer.cpp161
-rw-r--r--indra/newview/llappviewer.h1
-rw-r--r--indra/newview/llappviewerlinux.cpp2
-rw-r--r--indra/newview/llappviewermacosx.cpp2
-rw-r--r--indra/newview/llappviewerwin32.cpp2
-rw-r--r--indra/newview/llavatarpropertiesprocessor.h1
-rw-r--r--indra/newview/lldrawpoolalpha.cpp1
-rw-r--r--indra/newview/llfilepicker.cpp3
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp24
-rw-r--r--indra/newview/llfloatereditextdaycycle.h2
-rw-r--r--indra/newview/llfloaterenvironmentadjust.cpp7
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp6
-rw-r--r--indra/newview/llfloaterimnearbychat.cpp2
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp6
-rw-r--r--indra/newview/llfloaterimsessiontab.h1
-rw-r--r--indra/newview/llfloaterregioninfo.cpp14
-rw-r--r--indra/newview/llfloaterregioninfo.h1
-rw-r--r--indra/newview/llfloatertranslationsettings.cpp248
-rw-r--r--indra/newview/llfloatertranslationsettings.h32
-rw-r--r--indra/newview/llinspecttoast.cpp7
-rw-r--r--indra/newview/llinventorymodel.cpp6
-rw-r--r--indra/newview/llinventorymodelbackgroundfetch.cpp66
-rw-r--r--indra/newview/llinventorypanel.cpp6
-rw-r--r--indra/newview/llmaterialeditor.cpp4
-rw-r--r--indra/newview/llmeshrepository.cpp80
-rw-r--r--indra/newview/llmeshrepository.h4
-rw-r--r--indra/newview/llmodelpreview.cpp115
-rw-r--r--indra/newview/llmutelist.h1
-rw-r--r--indra/newview/llpaneleditsky.cpp11
-rw-r--r--indra/newview/llpaneleditsky.h2
-rw-r--r--indra/newview/llpanelface.cpp124
-rw-r--r--indra/newview/llpanelface.h15
-rw-r--r--indra/newview/llpanelobjectinventory.cpp3
-rw-r--r--indra/newview/llpanelprofile.cpp60
-rw-r--r--indra/newview/llpanelprofilepicks.cpp1
-rw-r--r--indra/newview/llpanelwearing.cpp2
-rw-r--r--indra/newview/llreflectionmap.cpp2
-rw-r--r--indra/newview/llreflectionmapmanager.cpp9
-rw-r--r--indra/newview/llscripteditor.cpp2
-rw-r--r--indra/newview/llselectmgr.cpp24
-rw-r--r--indra/newview/llselectmgr.h4
-rw-r--r--indra/newview/llsettingsvo.cpp8
-rw-r--r--indra/newview/llspatialpartition.cpp37
-rw-r--r--indra/newview/llspatialpartition.h5
-rw-r--r--indra/newview/llstartup.cpp13
-rw-r--r--indra/newview/lltooldraganddrop.cpp20
-rw-r--r--indra/newview/lltranslate.cpp870
-rw-r--r--indra/newview/lltranslate.h17
-rw-r--r--indra/newview/llviewercontrol.cpp3
-rw-r--r--indra/newview/llviewerinput.cpp5
-rw-r--r--indra/newview/llviewermenu.cpp7
-rw-r--r--indra/newview/llviewermessage.cpp2
-rw-r--r--indra/newview/llviewerobject.cpp24
-rw-r--r--indra/newview/llviewerobject.h1
-rw-r--r--indra/newview/llviewerobjectlist.cpp4
-rwxr-xr-xindra/newview/llviewerregion.cpp7
-rw-r--r--indra/newview/llviewershadermgr.cpp23
-rw-r--r--indra/newview/llviewerstats.cpp2
-rw-r--r--indra/newview/llviewertexturelist.cpp2
-rw-r--r--indra/newview/llviewerwindow.cpp3
-rw-r--r--indra/newview/llviewerwindow.h2
-rw-r--r--indra/newview/llvoavatar.cpp80
-rw-r--r--indra/newview/llvoavatar.h1
-rw-r--r--indra/newview/llvocache.cpp20
-rw-r--r--indra/newview/llvoicevivox.cpp48
-rw-r--r--indra/newview/llvoicevivox.h7
-rw-r--r--indra/newview/llvovolume.cpp102
-rw-r--r--indra/newview/llvovolume.h3
-rw-r--r--indra/newview/llvowater.cpp41
-rw-r--r--indra/newview/llworld.cpp3
-rw-r--r--indra/newview/pipeline.cpp64
-rw-r--r--indra/newview/pipeline.h6
-rw-r--r--indra/newview/skins/default/textures/icons/profile_badge_beta.pngbin0 -> 3223 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.pngbin0 -> 3221 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_badge_lifetime.pngbin0 -> 3302 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_badge_linden.pngbin0 -> 3521 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.pngbin0 -> 3311 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.pngbin0 -> 3301 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml8
-rw-r--r--indra/newview/skins/default/xui/en/floater_scene_load_stats.xml12
-rw-r--r--indra/newview/skins/default/xui/en/floater_translation_settings.xml216
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml47
-rw-r--r--indra/newview/skins/default/xui/en/panel_profile_secondlife.xml56
-rw-r--r--indra/newview/skins/default/xui/pt/panel_edit_hair.xml2
127 files changed, 2412 insertions, 1078 deletions
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index 6720f902bd..3cef382bbf 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -1391,6 +1391,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
// get number of joint motions
//-------------------------------------------------------------------------
U32 num_motions = 0;
+ S32 rotation_dupplicates = 0;
+ S32 position_dupplicates = 0;
if (!dp.unpackU32(num_motions, "num_joints"))
{
LL_WARNS() << "can't read number of joints"
@@ -1621,6 +1623,12 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
rCurve->mKeys[time] = rot_key;
}
+ if (joint_motion->mRotationCurve.mNumKeys > joint_motion->mRotationCurve.mKeys.size())
+ {
+ rotation_dupplicates++;
+ LL_INFOS() << "Motion: " << asset_id << " had dupplicate rotation keys that were removed" << LL_ENDL;
+ }
+
//---------------------------------------------------------------------
// scan position curve header
//---------------------------------------------------------------------
@@ -1723,9 +1731,24 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo
}
}
+ if (joint_motion->mPositionCurve.mNumKeys > joint_motion->mPositionCurve.mKeys.size())
+ {
+ position_dupplicates++;
+ }
+
joint_motion->mUsage = joint_state->getUsage();
}
+ if (rotation_dupplicates > 0)
+ {
+ LL_INFOS() << "Motion: " << asset_id << " had " << rotation_dupplicates << " dupplicate rotation keys that were removed" << LL_ENDL;
+ }
+
+ if (position_dupplicates > 0)
+ {
+ LL_INFOS() << "Motion: " << asset_id << " had " << position_dupplicates << " dupplicate position keys that were removed" << LL_ENDL;
+ }
+
//-------------------------------------------------------------------------
// get number of constraints
//-------------------------------------------------------------------------
@@ -2005,10 +2028,13 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
JointMotion* joint_motionp = mJointMotionList->getJointMotion(i);
success &= dp.packString(joint_motionp->mJointName, "joint_name");
success &= dp.packS32(joint_motionp->mPriority, "joint_priority");
- success &= dp.packS32(joint_motionp->mRotationCurve.mNumKeys, "num_rot_keys");
+ success &= dp.packS32(joint_motionp->mRotationCurve.mKeys.size(), "num_rot_keys");
- LL_DEBUGS("BVH") << "Joint " << joint_motionp->mJointName << LL_ENDL;
- for (RotationCurve::key_map_t::value_type& rot_pair : joint_motionp->mRotationCurve.mKeys)
+ LL_DEBUGS("BVH") << "Joint " << i
+ << " name: " << joint_motionp->mJointName
+ << " Rotation keys: " << joint_motionp->mRotationCurve.mKeys.size()
+ << " Position keys: " << joint_motionp->mPositionCurve.mKeys.size() << LL_ENDL;
+ for (RotationCurve::key_map_t::value_type& rot_pair : joint_motionp->mRotationCurve.mKeys)
{
RotationKey& rot_key = rot_pair.second;
U16 time_short = F32_to_U16(rot_key.mTime, 0.f, mJointMotionList->mDuration);
@@ -2028,7 +2054,7 @@ BOOL LLKeyframeMotion::serialize(LLDataPacker& dp) const
LL_DEBUGS("BVH") << " rot: t " << rot_key.mTime << " angles " << rot_angles.mV[VX] <<","<< rot_angles.mV[VY] <<","<< rot_angles.mV[VZ] << LL_ENDL;
}
- success &= dp.packS32(joint_motionp->mPositionCurve.mNumKeys, "num_pos_keys");
+ success &= dp.packS32(joint_motionp->mPositionCurve.mKeys.size(), "num_pos_keys");
for (PositionCurve::key_map_t::value_type& pos_pair : joint_motionp->mPositionCurve.mKeys)
{
PositionKey& pos_key = pos_pair.second;
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 516813aae1..fa9c6eaa79 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -40,7 +40,6 @@ set(llcommon_SOURCE_FILES
lldependencies.cpp
lldictionary.cpp
llerror.cpp
- llerrorthread.cpp
llevent.cpp
lleventapi.cpp
lleventcoro.cpp
@@ -153,7 +152,6 @@ set(llcommon_HEADER_FILES
llendianswizzle.h
llerror.h
llerrorcontrol.h
- llerrorthread.h
llevent.h
lleventapi.h
lleventcoro.h
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index d839b19c99..b99166991f 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -39,7 +39,6 @@
#include "llcommon.h"
#include "llapr.h"
#include "llerrorcontrol.h"
-#include "llerrorthread.h"
#include "llframetimer.h"
#include "lllivefile.h"
#include "llmemory.h"
@@ -108,12 +107,7 @@ LLAppErrorHandler LLApp::sErrorHandler = NULL;
BOOL LLApp::sErrorThreadRunning = FALSE;
-LLApp::LLApp() : mThreadErrorp(NULL)
-{
- commonCtor();
-}
-
-void LLApp::commonCtor()
+LLApp::LLApp()
{
// Set our status to running
setStatus(APP_STATUS_RUNNING);
@@ -143,12 +137,6 @@ void LLApp::commonCtor()
mCrashReportPipeStr = L"\\\\.\\pipe\\LLCrashReporterPipe";
}
-LLApp::LLApp(LLErrorThread *error_thread) :
- mThreadErrorp(error_thread)
-{
- commonCtor();
-}
-
LLApp::~LLApp()
{
@@ -158,13 +146,6 @@ LLApp::~LLApp()
mLiveFiles.clear();
setStopped();
- // HACK: wait for the error thread to clean itself
- ms_sleep(20);
- if (mThreadErrorp)
- {
- delete mThreadErrorp;
- mThreadErrorp = NULL;
- }
SUBSYSTEM_CLEANUP_DBG(LLCommon);
}
@@ -393,27 +374,6 @@ void LLApp::setupErrorHandling(bool second_instance)
#endif // ! LL_BUGSPLAT
#endif // ! LL_WINDOWS
-
-#ifdef LL_BUGSPLAT
- // do not start our own error thread
-#else // ! LL_BUGSPLAT
- startErrorThread();
-#endif
-}
-
-void LLApp::startErrorThread()
-{
- //
- // Start the error handling thread, which is responsible for taking action
- // when the app goes into the APP_STATUS_ERROR state
- //
- if(!mThreadErrorp)
- {
- LL_INFOS() << "Starting error thread" << LL_ENDL;
- mThreadErrorp = new LLErrorThread();
- mThreadErrorp->setUserData((void *) this);
- mThreadErrorp->start();
- }
}
void LLApp::setErrorHandler(LLAppErrorHandler handler)
@@ -476,7 +436,7 @@ void LLApp::setStatus(EAppStatus status)
// static
void LLApp::setError()
{
- // set app status to ERROR so that the LLErrorThread notices
+ // set app status to ERROR
setStatus(APP_STATUS_ERROR);
}
diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
index c65fe21c9c..c832c8b142 100644
--- a/indra/llcommon/llapp.h
+++ b/indra/llcommon/llapp.h
@@ -34,7 +34,6 @@
#include <atomic>
#include <chrono>
// Forward declarations
-class LLErrorThread;
class LLLiveFile;
#if LL_LINUX
#include <signal.h>
@@ -53,7 +52,6 @@ void clear_signals();
class LL_COMMON_API LLApp
{
- friend class LLErrorThread;
public:
typedef enum e_app_status
{
@@ -67,11 +65,6 @@ public:
LLApp();
virtual ~LLApp();
-protected:
- LLApp(LLErrorThread* error_thread);
- void commonCtor();
-public:
-
/**
* @brief Return the static app instance if one was created.
*/
@@ -257,14 +250,14 @@ public:
void setupErrorHandling(bool mSecondInstance=false);
void setErrorHandler(LLAppErrorHandler handler);
- static void runErrorHandler(); // run shortly after we detect an error, ran in the relatively robust context of the LLErrorThread - preferred.
+ static void runErrorHandler(); // run shortly after we detect an error
//@}
-
+
// the maximum length of the minidump filename returned by getMiniDumpFilename()
static const U32 MAX_MINDUMP_PATH_LENGTH = 256;
// change the directory where Breakpad minidump files are written to
- void setDebugFileNames(const std::string &path);
+ void setDebugFileNames(const std::string &path);
// Return the Google Breakpad minidump filename after a crash.
char *getMiniDumpFilename() { return mMinidumpPath; }
@@ -310,13 +303,11 @@ protected:
void stepFrame();
private:
- void startErrorThread();
-
// Contains the filename of the minidump file after a crash.
char mMinidumpPath[MAX_MINDUMP_PATH_LENGTH];
- std::string mStaticDebugFileName;
- std::string mDynamicDebugFileName;
+ std::string mStaticDebugFileName;
+ std::string mDynamicDebugFileName;
// *NOTE: On Windows, we need a routine to reset the structured
// exception handler when some evil driver has taken it over for
@@ -324,9 +315,6 @@ private:
typedef int(*signal_handler_func)(int signum);
static LLAppErrorHandler sErrorHandler;
- // Default application threads
- LLErrorThread* mThreadErrorp; // Waits for app to go to status ERROR, then runs the error callback
-
// This is the application level runnable scheduler.
LLRunner mRunner;
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index 08eb323c4a..f229b4964a 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -276,7 +276,6 @@ namespace LLError
// used to indicate no class info known for logging
//LLCallStacks keeps track of call stacks and output the call stacks to log file
- //when LLAppViewer::handleViewerCrash() is triggered.
//
//Note: to be simple, efficient and necessary to keep track of correct call stacks,
//LLCallStacks is designed not to be thread-safe.
diff --git a/indra/llcommon/llerrorthread.cpp b/indra/llcommon/llerrorthread.cpp
deleted file mode 100644
index f6bc68b5c1..0000000000
--- a/indra/llcommon/llerrorthread.cpp
+++ /dev/null
@@ -1,133 +0,0 @@
-/**
- * @file llerrorthread.cpp
- *
- * $LicenseInfo:firstyear=2004&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 "llerrorthread.h"
-
-#include "llapp.h"
-#include "lltimer.h" // ms_sleep()
-
-LLErrorThread::LLErrorThread()
- : LLThread("Error"),
- mUserDatap(NULL)
-{
-}
-
-LLErrorThread::~LLErrorThread()
-{
-}
-
-void LLErrorThread::setUserData(void* user_data)
-{
- mUserDatap = user_data;
-}
-
-
-void* LLErrorThread::getUserData() const
-{
- return mUserDatap;
-}
-
-#if !LL_WINDOWS
-//
-// Various signal/error handling functions that can't be put into the class
-//
-void get_child_status(const int waitpid_status, int &process_status, bool &exited, bool do_logging)
-{
- exited = false;
- process_status = -1;
- // The child process exited. Call its callback, and then clean it up
- if (WIFEXITED(waitpid_status))
- {
- process_status = WEXITSTATUS(waitpid_status);
- exited = true;
- if (do_logging)
- {
- LL_INFOS() << "get_child_status - Child exited cleanly with return of " << process_status << LL_ENDL;
- }
- return;
- }
- else if (WIFSIGNALED(waitpid_status))
- {
- process_status = WTERMSIG(waitpid_status);
- exited = true;
- if (do_logging)
- {
- LL_INFOS() << "get_child_status - Child died because of uncaught signal " << process_status << LL_ENDL;
-#ifdef WCOREDUMP
- if (WCOREDUMP(waitpid_status))
- {
- LL_INFOS() << "get_child_status - Child dumped core" << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "get_child_status - Child didn't dump core" << LL_ENDL;
- }
-#endif
- }
- return;
- }
- else if (do_logging)
- {
- // This is weird. I just dump the waitpid status into the status code,
- // not that there's any way of telling what it is...
- LL_INFOS() << "get_child_status - Got SIGCHILD but child didn't exit" << LL_ENDL;
- process_status = waitpid_status;
- }
-
-}
-#endif
-
-void LLErrorThread::run()
-{
- LLApp::sErrorThreadRunning = TRUE;
- // This thread sits and waits for the sole purpose
- // of waiting for the signal/exception handlers to flag the
- // application state as APP_STATUS_ERROR.
- LL_INFOS() << "thread_error - Waiting for an error" << LL_ENDL;
-
- S32 counter = 0;
- while (! (LLApp::isError() || LLApp::isStopped()))
- {
- ms_sleep(10);
- counter++;
- }
- if (LLApp::isError())
- {
- // The app is in an error state, run the application's error handler.
- //LL_INFOS() << "thread_error - An error has occurred, running error callback!" << LL_ENDL;
- // Run the error handling callback
- LLApp::runErrorHandler();
- }
- else
- {
- // Everything is okay, a clean exit.
- //LL_INFOS() << "thread_error - Application exited cleanly" << LL_ENDL;
- }
-
- //LL_INFOS() << "thread_error - Exiting" << LL_ENDL;
- LLApp::sErrorThreadRunning = FALSE;
-}
-
diff --git a/indra/llcommon/llerrorthread.h b/indra/llcommon/llerrorthread.h
deleted file mode 100644
index 474cef3a50..0000000000
--- a/indra/llcommon/llerrorthread.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file llerrorthread.h
- * @brief Specialized thread to handle runtime errors.
- *
- * $LicenseInfo:firstyear=2004&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_LLERRORTHREAD_H
-#define LL_LLERRORTHREAD_H
-
-#include "llthread.h"
-
-class LL_COMMON_API LLErrorThread : public LLThread
-{
-public:
- LLErrorThread();
- ~LLErrorThread();
-
- /*virtual*/ void run(void);
- void setUserData(void *user_data);
- void *getUserData() const;
-
-protected:
- void* mUserDatap; // User data associated with this thread
-};
-
-#endif // LL_LLERRORTHREAD_H
diff --git a/indra/llinventory/llsettingssky.cpp b/indra/llinventory/llsettingssky.cpp
index 6521ec8b43..8338245897 100644
--- a/indra/llinventory/llsettingssky.cpp
+++ b/indra/llinventory/llsettingssky.cpp
@@ -1142,6 +1142,7 @@ void LLSettingsSky::setSkyIceLevel(F32 ice_level)
void LLSettingsSky::setReflectionProbeAmbiance(F32 ambiance)
{
+ mCanAutoAdjust = false; // we've now touched this sky in a "new" way, it can no longer auto adjust
setValue(SETTING_REFLECTION_PROBE_AMBIANCE, ambiance);
}
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 91e463cc32..0e3792fda3 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2056,7 +2056,8 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mDetail = detail;
mSculptLevel = -2;
mSurfaceArea = 1.f; //only calculated for sculpts, defaults to 1 for all other prims
- mIsMeshAssetLoaded = FALSE;
+ mIsMeshAssetLoaded = false;
+ mIsMeshAssetUnavaliable = false;
mLODScaleBias.setVec(1,1,1);
mHullPoints = NULL;
mHullIndices = NULL;
@@ -2804,14 +2805,32 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
}
-BOOL LLVolume::isMeshAssetLoaded()
+bool LLVolume::isMeshAssetLoaded()
{
return mIsMeshAssetLoaded;
}
-void LLVolume::setMeshAssetLoaded(BOOL loaded)
+void LLVolume::setMeshAssetLoaded(bool loaded)
{
mIsMeshAssetLoaded = loaded;
+ if (loaded)
+ {
+ mIsMeshAssetUnavaliable = false;
+ }
+}
+
+void LLVolume::setMeshAssetUnavaliable(bool unavaliable)
+{
+ // Don't set it if at least one lod loaded
+ if (!mIsMeshAssetLoaded)
+ {
+ mIsMeshAssetUnavaliable = unavaliable;
+ }
+}
+
+bool LLVolume::isMeshAssetUnavaliable()
+{
+ return mIsMeshAssetUnavaliable;
}
void LLVolume::copyFacesTo(std::vector<LLVolumeFace> &faces) const
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index ad6a669531..afed98ff36 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -1111,15 +1111,18 @@ private:
bool unpackVolumeFacesInternal(const LLSD& mdl);
public:
- virtual void setMeshAssetLoaded(BOOL loaded);
- virtual BOOL isMeshAssetLoaded();
+ virtual void setMeshAssetLoaded(bool loaded);
+ virtual bool isMeshAssetLoaded();
+ virtual void setMeshAssetUnavaliable(bool unavaliable);
+ virtual bool isMeshAssetUnavaliable();
protected:
BOOL mUnique;
F32 mDetail;
S32 mSculptLevel;
F32 mSurfaceArea; //unscaled surface area
- BOOL mIsMeshAssetLoaded;
+ bool mIsMeshAssetLoaded;
+ bool mIsMeshAssetUnavaliable;
const LLVolumeParams mParams;
LLPath *mPathp;
diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp
index 89cdb1c6b9..9399504529 100644
--- a/indra/llmath/llvolumemgr.cpp
+++ b/indra/llmath/llvolumemgr.cpp
@@ -89,7 +89,7 @@ BOOL LLVolumeMgr::cleanup()
// Note however that LLVolumeLODGroup that contains the volume
// also holds a LLPointer so the volume will only go away after
// anything holding the volume and the LODGroup are destroyed
-LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 detail)
+LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32 lod)
{
LLVolumeLODGroup* volgroupp;
if (mDataMutex)
@@ -109,7 +109,7 @@ LLVolume* LLVolumeMgr::refVolume(const LLVolumeParams &volume_params, const S32
{
mDataMutex->unlock();
}
- return volgroupp->refLOD(detail);
+ return volgroupp->refLOD(lod);
}
// virtual
@@ -287,18 +287,18 @@ bool LLVolumeLODGroup::cleanupRefs()
return res;
}
-LLVolume* LLVolumeLODGroup::refLOD(const S32 detail)
+LLVolume* LLVolumeLODGroup::refLOD(const S32 lod)
{
- llassert(detail >=0 && detail < NUM_LODS);
- mAccessCount[detail]++;
+ llassert(lod >=0 && lod < NUM_LODS);
+ mAccessCount[lod]++;
mRefs++;
- if (mVolumeLODs[detail].isNull())
+ if (mVolumeLODs[lod].isNull())
{
- mVolumeLODs[detail] = new LLVolume(mVolumeParams, mDetailScales[detail]);
+ mVolumeLODs[lod] = new LLVolume(mVolumeParams, mDetailScales[lod]);
}
- mLODRefs[detail]++;
- return mVolumeLODs[detail];
+ mLODRefs[lod]++;
+ return mVolumeLODs[lod];
}
BOOL LLVolumeLODGroup::derefLOD(LLVolume *volumep)
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 66bd85f4e6..a2e85cf6c2 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -552,7 +552,9 @@ std::string LLCacheName::buildUsername(const std::string& full_name)
// if the input wasn't a correctly formatted legacy name, just return it
// cleaned up from a potential terminal "Resident"
- return cleanFullName(full_name);
+ std::string clean_name = cleanFullName(full_name);
+ LLStringUtil::toLower(clean_name);
+ return clean_name;
}
//static
diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
index 37525e4a3d..f6cb3c8b70 100644
--- a/indra/llprimitive/llmaterial.cpp
+++ b/indra/llprimitive/llmaterial.cpp
@@ -438,18 +438,18 @@ bool LLMaterial::operator != (const LLMaterial& rhs) const
}
-U32 LLMaterial::getShaderMask(U32 alpha_mode)
+U32 LLMaterial::getShaderMask(U32 alpha_mode, BOOL is_alpha)
{ //NEVER incorporate this value into the message system -- this function will vary depending on viewer implementation
- U32 ret = 0;
- //two least significant bits are "diffuse alpha mode"
- if (alpha_mode != DIFFUSE_ALPHA_MODE_DEFAULT)
+ //two least significant bits are "diffuse alpha mode"
+ U32 ret = alpha_mode;
+ if (ret == DIFFUSE_ALPHA_MODE_DEFAULT)
{
- ret = alpha_mode;
- }
- else
- {
- ret = getDiffuseAlphaMode();
+ ret = getDiffuseAlphaMode();
+ if (ret == DIFFUSE_ALPHA_MODE_BLEND && !is_alpha)
+ {
+ ret = DIFFUSE_ALPHA_MODE_NONE;
+ }
}
llassert(ret < SHADER_COUNT);
diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
index d715671ae1..b46d85c2d1 100644
--- a/indra/llprimitive/llmaterial.h
+++ b/indra/llprimitive/llmaterial.h
@@ -124,7 +124,7 @@ public:
bool operator == (const LLMaterial& rhs) const;
bool operator != (const LLMaterial& rhs) const;
- U32 getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT);
+ U32 getShaderMask(U32 alpha_mode, BOOL is_alpha);
LLUUID getHash() const;
protected:
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 1bf061bc8d..6f4f2ec62c 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -494,7 +494,7 @@ F32 LLFontGL::getWidthF32(const std::string& utf8text, S32 begin_offset, S32 max
return getWidthF32(wtext.c_str(), begin_offset, max_chars);
}
-F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars) const
+F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars, bool no_padding) const
{
const S32 LAST_CHARACTER = LLFontFreetype::LAST_CHAR_FULL;
@@ -517,12 +517,15 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
F32 advance = mFontFreetype->getXAdvance(fgi);
- // for the last character we want to measure the greater of its width and xadvance values
- // so keep track of the difference between these values for the each character we measure
- // so we can fix things up at the end
- width_padding = llmax( 0.f, // always use positive padding amount
- width_padding - advance, // previous padding left over after advance of current character
- (F32)(fgi->mWidth + fgi->mXBearing) - advance); // difference between width of this character and advance to next character
+ if (!no_padding)
+ {
+ // for the last character we want to measure the greater of its width and xadvance values
+ // so keep track of the difference between these values for the each character we measure
+ // so we can fix things up at the end
+ width_padding = llmax(0.f, // always use positive padding amount
+ width_padding - advance, // previous padding left over after advance of current character
+ (F32)(fgi->mWidth + fgi->mXBearing) - advance); // difference between width of this character and advance to next character
+ }
cur_x += advance;
llwchar next_char = wchars[i+1];
@@ -539,8 +542,11 @@ F32 LLFontGL::getWidthF32(const llwchar* wchars, S32 begin_offset, S32 max_chars
cur_x = (F32)ll_round(cur_x);
}
- // add in extra pixels for last character's width past its xadvance
- cur_x += width_padding;
+ if (!no_padding)
+ {
+ // add in extra pixels for last character's width past its xadvance
+ cur_x += width_padding;
+ }
return cur_x / sScaleX;
}
diff --git a/indra/llrender/llfontgl.h b/indra/llrender/llfontgl.h
index 3b58a37d33..93c6b78ce8 100644
--- a/indra/llrender/llfontgl.h
+++ b/indra/llrender/llfontgl.h
@@ -138,7 +138,7 @@ public:
F32 getWidthF32(const std::string& utf8text) const;
F32 getWidthF32(const llwchar* wchars) const;
F32 getWidthF32(const std::string& text, S32 offset, S32 max_chars ) const;
- F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars) const;
+ F32 getWidthF32(const llwchar* wchars, S32 offset, S32 max_chars, bool no_padding = false) const;
// The following are called often, frequently with large buffers, so do not use a string interface
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index 3e3a3095e3..b77f98d65e 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -905,9 +905,16 @@ BOOL LLImageGL::setImage(const U8* data_in, BOOL data_hasmips /* = FALSE */, S32
stop_glerror();
if (prev_mip_data)
- delete[] prev_mip_data;
+ {
+ if (prev_mip_data != cur_mip_data)
+ delete[] prev_mip_data;
+ prev_mip_data = nullptr;
+ }
if (cur_mip_data)
+ {
delete[] cur_mip_data;
+ cur_mip_data = nullptr;
+ }
mGLTextureCreated = false;
return FALSE;
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 177cad2508..6730a12d6c 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -1309,8 +1309,9 @@ void LLShaderMgr::initAttribsAndUniforms()
mReservedUniforms.push_back("warmthAmount");
mReservedUniforms.push_back("glowStrength");
mReservedUniforms.push_back("glowDelta");
+ mReservedUniforms.push_back("glowNoiseMap");
- llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_DELTA+1);
+ llassert(mReservedUniforms.size() == LLShaderMgr::GLOW_NOISE_MAP+1);
mReservedUniforms.push_back("minimum_alpha");
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index cfa824c361..53c8323cff 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -132,6 +132,7 @@ public:
GLOW_WARMTH_AMOUNT, // "warmthAmount"
GLOW_STRENGTH, // "glowStrength"
GLOW_DELTA, // "glowDelta"
+ GLOW_NOISE_MAP, // "glowNoiseMap"
MINIMUM_ALPHA, // "minimum_alpha"
EMISSIVE_BRIGHTNESS, // "emissive_brightness"
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index eba93beed9..e2b5279aab 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -395,7 +395,7 @@ S32 LLFolderViewItem::arrange( S32* width, S32* height )
// it is purely visual, so it is fine to do at our laisure
refreshSuffix();
}
- mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight;
+ mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight;
mLabelWidthDirty = false;
}
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index e01aba402e..2791377a5e 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -37,6 +37,8 @@
#include "lluiimage.h"
#include "llwindow.h"
+#include "llgltexture.h"
+
static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon");
LLIconCtrl::Params::Params()
@@ -94,6 +96,22 @@ BOOL LLIconCtrl::handleHover(S32 x, S32 y, MASK mask)
return LLUICtrl::handleHover(x, y, mask);
}
+void LLIconCtrl::onVisibilityChange(BOOL new_visibility)
+{
+ LLUICtrl::onVisibilityChange(new_visibility);
+ if (mPriority == LLGLTexture::BOOST_ICON)
+ {
+ if (new_visibility)
+ {
+ loadImage(getValue(), mPriority);
+ }
+ else
+ {
+ mImagep = nullptr;
+ }
+ }
+}
+
// virtual
// value might be a string or a UUID
void LLIconCtrl::setValue(const LLSD& value)
@@ -110,6 +128,14 @@ void LLIconCtrl::setValue(const LLSD& value, S32 priority)
tvalue = LLSD(LLUUID(value.asString()));
}
LLUICtrl::setValue(tvalue);
+
+ loadImage(tvalue, priority);
+}
+
+void LLIconCtrl::loadImage(const LLSD& tvalue, S32 priority)
+{
+ if(mPriority == LLGLTexture::BOOST_ICON && !getVisible()) return;
+
if (tvalue.isUUID())
{
mImagep = LLUI::getUIImageByID(tvalue.asUUID(), priority);
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index 9c3b517bca..5d6c544571 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -72,6 +72,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
// lluictrl overrides
+ void onVisibilityChange(BOOL new_visibility);
virtual void setValue(const LLSD& value );
std::string getImageName() const;
@@ -95,6 +96,8 @@ protected:
bool mInteractable;
private:
+ void loadImage(const LLSD& value, S32 priority);
+
LLUIColor mColor;
LLPointer<LLUIImage> mImagep;
};
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 77938edf27..ae9dba5945 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -282,6 +282,17 @@ void LLLayoutStack::draw()
}
}
+void LLLayoutStack::deleteAllChildren()
+{
+ mPanels.clear();
+ LLView::deleteAllChildren();
+
+ // Not really needed since nothing is left to
+ // display, but for the sake of consistency
+ updateFractionalSizes();
+ mNeedsLayout = true;
+}
+
void LLLayoutStack::removeChild(LLView* view)
{
LLLayoutPanel* embedded_panelp = findEmbeddedPanel(dynamic_cast<LLPanel*>(view));
@@ -289,12 +300,14 @@ void LLLayoutStack::removeChild(LLView* view)
if (embedded_panelp)
{
mPanels.erase(std::find(mPanels.begin(), mPanels.end(), embedded_panelp));
- delete embedded_panelp;
+ LLView::removeChild(view);
updateFractionalSizes();
mNeedsLayout = true;
}
-
- LLView::removeChild(view);
+ else
+ {
+ LLView::removeChild(view);
+ }
}
BOOL LLLayoutStack::postBuild()
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index f772dbc6b4..22f11eb20f 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -67,6 +67,7 @@ public:
virtual ~LLLayoutStack();
/*virtual*/ void draw();
+ /*virtual*/ void deleteAllChildren();
/*virtual*/ void removeChild(LLView*);
/*virtual*/ BOOL postBuild();
/*virtual*/ bool addChild(LLView* child, S32 tab_group = 0);
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 5cb840fd61..33c4b6ec73 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1882,6 +1882,13 @@ bool LLMenuGL::addContextChild(LLView* view, S32 tab_group)
return false;
}
+
+void LLMenuGL::deleteAllChildren()
+{
+ mItems.clear();
+ LLUICtrl::deleteAllChildren();
+}
+
void LLMenuGL::removeChild( LLView* ctrl)
{
// previously a dynamic_cast with if statement to check validity
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index f84c4d41eb..9d3be8d94f 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -442,6 +442,7 @@ public:
/*virtual*/ void drawBackground(LLMenuItemGL* itemp, F32 alpha);
/*virtual*/ void setVisible(BOOL visible);
/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
+ /*virtual*/ void deleteAllChildren();
/*virtual*/ void removeChild( LLView* ctrl);
/*virtual*/ BOOL postBuild();
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index b8f47ef6ba..8018365d3e 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -127,6 +127,7 @@ public:
virtual void clearCtrls(); // overridden in LLPanelObject and LLPanelVolume
// Border controls
+ const LLViewBorder* getBorder() const { return mBorder; }
void addBorder( LLViewBorder::Params p);
void addBorder();
void removeBorder();
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 82a3c01c6d..8732a7ce45 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -361,7 +361,7 @@ void LLTextBase::onValueChange(S32 start, S32 end)
{
}
-std::vector<LLRect> LLTextBase::getSelctionRects()
+std::vector<LLRect> LLTextBase::getSelectionRects()
{
// Nor supposed to be called without selection
llassert(hasSelection());
@@ -458,7 +458,7 @@ void LLTextBase::drawSelectionBackground()
// Draw selection even if we don't have keyboard focus for search/replace
if (hasSelection() && !mLineInfoList.empty())
{
- std::vector<LLRect> selection_rects = getSelctionRects();
+ std::vector<LLRect> selection_rects = getSelectionRects();
// Draw the selection box (we're using a box instead of reversing the colors on the selected text).
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -1356,9 +1356,9 @@ void LLTextBase::draw()
drawCursor();
}
- mDocumentView->setVisible(FALSE);
+ mDocumentView->setVisibleDirect(FALSE);
LLUICtrl::draw();
- mDocumentView->setVisible(TRUE);
+ mDocumentView->setVisibleDirect(TRUE);
}
@@ -3464,7 +3464,7 @@ bool LLNormalTextSegment::getDimensionsF32(S32 first_char, S32 num_chars, F32& w
height = mFontHeight;
const LLWString &text = getWText();
// if last character is a newline, then return true, forcing line break
- width = mStyle->getFont()->getWidthF32(text.c_str(), mStart + first_char, num_chars);
+ width = mStyle->getFont()->getWidthF32(text.c_str(), mStart + first_char, num_chars, true);
}
return false;
}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index e3cf56a5ee..3611ab0499 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -638,7 +638,7 @@ protected:
return mLabel.getString() + getToolTip();
}
- std::vector<LLRect> getSelctionRects();
+ std::vector<LLRect> getSelectionRects();
protected:
// text segmentation and flow
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index c567451973..521dabf9d4 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -171,7 +171,8 @@ void LLTextBox::reshapeToFitText(BOOL called_from_parent)
S32 width = getTextPixelWidth();
S32 height = getTextPixelHeight();
- reshape( width + 2 * mHPad, height + 2 * mVPad, called_from_parent );
+ //consider investigating reflow() to find missing width pixel (see SL-17045 changes)
+ reshape( width + 2 * mHPad + 1, height + 2 * mVPad, called_from_parent );
}
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
index 244f0c6f00..096336045c 100644
--- a/indra/llui/lluicolortable.cpp
+++ b/indra/llui/lluicolortable.cpp
@@ -200,7 +200,6 @@ LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& defa
void LLUIColorTable::setColor(const std::string& name, const LLColor4& color)
{
setColor(name, color, mUserSetColors);
- setColor(name, color, mLoadedColors);
}
bool LLUIColorTable::loadFromSettings()
@@ -229,6 +228,11 @@ void LLUIColorTable::saveUserSettings() const
it != mUserSetColors.end();
++it)
{
+ // Compare user color value with the default value, skip if equal
+ string_color_map_t::const_iterator itd = mLoadedColors.find(it->first);
+ if(itd != mLoadedColors.end() && itd->second == it->second)
+ continue;
+
ColorEntryParams color_entry;
color_entry.name = it->first;
color_entry.color.value = it->second;
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 9ba71913d0..3344300635 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -576,8 +576,10 @@ void LLView::deleteAllChildren()
while (!mChildList.empty())
{
- LLView* viewp = mChildList.front();
- delete viewp; // will remove the child from mChildList
+ LLView* viewp = mChildList.front();
+ viewp->mParentView = NULL;
+ delete viewp;
+ mChildList.pop_front();
}
}
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index bec45df78a..8aa97aac39 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -287,6 +287,7 @@ public:
void setAllChildrenEnabled(BOOL b);
virtual void setVisible(BOOL visible);
+ void setVisibleDirect(BOOL visible) { mVisible = visible; }
const BOOL& getVisible() const { return mVisible; }
virtual void setEnabled(BOOL enabled);
BOOL getEnabled() const { return mEnabled; }
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index b1408d894f..f435d46584 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -118,7 +118,8 @@ public:
// Sets cursor, may set to arrow+hourglass
virtual void setCursor(ECursorType cursor) { mNextCursor = cursor; };
- virtual ECursorType getCursor() const;
+ virtual ECursorType getCursor() const;
+ virtual ECursorType getNextCursor() const { return mNextCursor; };
virtual void updateCursor() = 0;
virtual void captureMouse() = 0;
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 270d5e6869..f5e7f865ab 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -9351,6 +9351,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderPostProcessingHDR</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable HDR for post processing buffer</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderMaxOpenGLVersion</key>
<map>
<key>Comment</key>
@@ -10166,6 +10177,17 @@
<key>Value</key>
<integer>9</integer>
</map>
+ <key>RenderGlowHDR</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable HDR for glow map</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderGlowStrength</key>
<map>
<key>Comment</key>
@@ -10214,6 +10236,17 @@
<key>Value</key>
<real>1.3</real>
</map>
+ <key>RenderGlowNoise</key>
+ <map>
+ <key>Comment</key>
+ <string>Enables glow noise (dithering). Reduces banding from glow in certain cases.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
<key>DisableAllRenderTypes</key>
<map>
<key>Comment</key>
@@ -10601,27 +10634,38 @@
<key>Value</key>
<integer>3</integer>
</map>
- <key>RenderSkyHDRScale</key>
+ <key>RenderSkyAutoAdjustLegacy</key>
<map>
<key>Comment</key>
- <string>Amount to over-brighten sun for HDR effect during the day</string>
+ <string>If true, automatically adjust legacy skies (those without a probe ambiance value) to take advantage of probes and HDR. This is the "opt-out" button for HDR and tonemapping when coupled with a sky setting that predates PBR.</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
- <string>F32</string>
+ <string>Boolean</string>
<key>Value</key>
- <real>1.0</real>
+ <integer>1</integer>
</map>
- <key>RenderSkyAutoAdjustLegacy</key>
+ <key>RenderSkyAutoAdjustAmbientScale</key>
<map>
<key>Comment</key>
- <string>If true, automatically adjust legacy skies (those without a probe ambiance value) to take advantage of probes and HDR. This is the "opt-out" button for HDR and tonemapping when coupled with a sky setting that predates PBR.</string>
+ <string>Amount to scale ambient when auto-adjusting legacy skies</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
+ <string>F32</string>
<key>Value</key>
+ <real>0.5</real>
+ </map>
+ <key>RenderSkyAutoAdjustHDRScale</key>
+ <map>
+ <key>Comment</key>
+ <string>HDR Scale value to use when auto-adjusting legacy skies</string>
+ <key>Persist</key>
<integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>2.0</real>
</map>
<key>RenderReflectionProbeMaxLocalLightAmbiance</key>
<map>
@@ -10643,7 +10687,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0.4</real>
+ <real>0.5</real>
</map>
<key>RenderShaderLODThreshold</key>
<map>
@@ -13127,13 +13171,13 @@
<key>TranslationService</key>
<map>
<key>Comment</key>
- <string>Translation API to use. (google|bing)</string>
+ <string>Translation API to use. (google|azure)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>String</string>
<key>Value</key>
- <string>bing</string>
+ <string>azure</string>
</map>
<key>GoogleTranslateAPIKey</key>
<map>
@@ -13149,7 +13193,7 @@
<key>BingTranslateAPIKey</key>
<map>
<key>Comment</key>
- <string>Bing AppID to use with the Microsoft Translator API</string>
+ <string>(Deprecated) Bing AppID to use with the Microsoft Translator API</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -13157,6 +13201,28 @@
<key>Value</key>
<string></string>
</map>
+ <key>AzureTranslateAPIKey</key>
+ <map>
+ <key>Comment</key>
+ <string>Azure Translation service data to use with the MS Azure Translator API</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>LLSD</string>
+ <key>Value</key>
+ <string></string>
+ </map>
+ <key>DeepLTranslateAPIKey</key>
+ <map>
+ <key>Comment</key>
+ <string>DeepL Translation service data to use with the DeepL Translator API</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>LLSD</string>
+ <key>Value</key>
+ <string></string>
+ </map>
<key>TutorialURL</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index e0e97bb938..f6870c3ff0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -110,7 +110,7 @@ void main()
// Combine
vec3 color;
color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
- color.rgb= max(vec3(0), color.rgb);
+ color.rgb = clamp(color.rgb, vec3(0), vec3(1));
color.rgb *= 2.0;
/// Gamma correct for WL (soft clip effect).
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index cc4c3b5dce..9d9ba49d82 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -84,6 +84,7 @@ void main()
color.rgb += rainbow(optic_d);
color.rgb += halo_22;
color.rgb *= 2.;
+ color.rgb = clamp(color.rgb, vec3(0), vec3(5));
frag_data[0] = vec4(0);
frag_data[1] = vec4(0);
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
index 7a5e14566b..b5437d43d2 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
@@ -28,6 +28,10 @@
out vec4 frag_color;
uniform sampler2D diffuseMap;
+#if HAS_NOISE
+uniform sampler2D glowNoiseMap;
+uniform vec2 screen_res;
+#endif
uniform float minLuminance;
uniform float maxExtractAlpha;
uniform vec3 lumWeights;
@@ -44,7 +48,16 @@ void main()
float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) );
float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) );
- frag_color.rgb = col.rgb;
+#if HAS_NOISE
+ float TRUE_NOISE_RES = 128; // See mTrueNoiseMap
+ // *NOTE: Usually this is vary_fragcoord not vary_texcoord0, but glow extraction is in screen space
+ vec3 glow_noise = texture(glowNoiseMap, vary_texcoord0.xy * (screen_res / TRUE_NOISE_RES)).xyz;
+ // Dithering. Reduces banding effects in the reduced precision glow buffer.
+ float NOISE_DEPTH = 64.0;
+ col.rgb += glow_noise / NOISE_DEPTH;
+ col.rgb = max(col.rgb, vec3(0));
+#endif
+ frag_color.rgb = col.rgb;
frag_color.a = max(col.a, mix(lum, warmth, warmthAmount) * maxExtractAlpha);
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index b474a5803f..f51b0f4d9e 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -25,7 +25,6 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
in vec3 position;
@@ -54,14 +53,27 @@ float calcDirectionalLight(vec3 n, vec3 l)
//====================================================================================================
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+#endif
+
void main()
{
- //transform vertex
- vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec3 norm;
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vec4(position.xyz, 1.0);
+ gl_Position = projection_matrix * pos;
+ norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+#else
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ norm = normalize(normal_matrix * normal);
+#endif
+
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vec3 norm = normalize(normal_matrix * normal);
vec4 col = vec4(0,0,0,1);
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
index 48cf234aa0..41a848a14f 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
@@ -36,8 +36,6 @@ vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
{
light *= atten.r;
additive = srgb_to_linear(additive*2.0);
- // magic 1.25 here is to match the default RenderSkyHDRScale -- this parameter needs to be plumbed into sky settings or something
- // so it's available to all shaders that call atmosFragLighting instead of just softenLightF.glsl
additive *= sky_hdr_scale;
light += additive;
return light;
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
index 298ddf92a7..adbf7abdd1 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -368,7 +368,8 @@ return texCUBE(envMap, ReflDirectionWS);
// dir - ray direction in clip space
// i - probe index in refBox/refSphere
// d - distance to nearest wall in clip space
-vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
+// scale - scale of box, default 1.0
+vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale)
{
// Intersection with OBB convert to unit box space
// Transform in local unit parallax cube space (scaled and rotated)
@@ -379,7 +380,7 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
d = 1.0-max(max(abs(PositionLS.x), abs(PositionLS.y)), abs(PositionLS.z));
- vec3 Unitary = vec3(1.0f, 1.0f, 1.0f);
+ vec3 Unitary = vec3(scale);
vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS;
vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS;
vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect);
@@ -391,6 +392,11 @@ vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
return IntersectPositionCS;
}
+vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
+{
+ return boxIntersect(origin, dir, i, d, 1.0);
+}
+
void debugBoxCol(vec3 ro, vec3 rd, float t, vec3 p, inout vec4 col)
{
vec3 v = ro + rd * t;
@@ -539,7 +545,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int
if (refIndex[i].w < 0)
{
float d = 0.0;
- v = boxIntersect(pos, dir, i, d);
+ v = boxIntersect(pos, dir, i, d, 3.0);
w = max(d, 0.001);
}
else
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index ec2467200a..39f7996c7c 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 57
+version 58
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -163,7 +163,7 @@ RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 1
//
-// Medium High Graphics Settings (deferred enabled)
+// Medium High Graphics Settings
//
list MidHigh
RenderAnisotropic 1 1
@@ -192,7 +192,7 @@ RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 2
//
-// High Graphics Settings (deferred + SSAO)
+// High Graphics Settings (SSAO + sun shadows)
//
list High
RenderAnisotropic 1 1
@@ -212,7 +212,7 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
-RenderShadowDetail 1 0
+RenderShadowDetail 1 1
WLSkyDetail 1 96
RenderFSAASamples 1 2
RenderReflectionsEnabled 1 1
@@ -221,7 +221,7 @@ RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 3
//
-// High Ultra Graphics Settings (deferred + SSAO + shadows)
+// High Ultra Graphics Settings (deferred + SSAO + all shadows)
//
list HighUltra
RenderAnisotropic 1 1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 0687a3cea1..cce403c7aa 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 52
+version 53
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -161,7 +161,7 @@ RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 0
//
-// Medium High Graphics Settings (deferred enabled)
+// Medium High Graphics Settings
//
list MidHigh
RenderAnisotropic 1 1
@@ -190,7 +190,7 @@ RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 0
//
-// High Graphics Settings (deferred + SSAO)
+// High Graphics Settings (SSAO + sun shadows)
//
list High
RenderAnisotropic 1 1
@@ -210,7 +210,7 @@ RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
-RenderShadowDetail 1 0
+RenderShadowDetail 1 1
WLSkyDetail 1 96
RenderFSAASamples 1 2
RenderReflectionsEnabled 1 1
@@ -219,7 +219,7 @@ RenderScreenSpaceReflections 1 0
RenderReflectionProbeLevel 1 1
//
-// High Ultra Graphics Settings (deferred + SSAO + shadows)
+// High Ultra Graphics Settings (SSAO + all shadows)
//
list HighUltra
RenderAnisotropic 1 1
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index abef25e34f..343778fe03 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3574,8 +3574,6 @@ void LLAppViewer::writeSystemInfo()
// "CrashNotHandled" is set here, while things are running well,
// in case of a freeze. If there is a freeze, the crash logger will be launched
// and can read this value from the debug_info.log.
- // If the crash is handled by LLAppViewer::handleViewerCrash, ie not a freeze,
- // then the value of "CrashNotHandled" will be set to true.
gDebugInfo["CrashNotHandled"] = LLSD::Boolean(true);
#else // LL_BUGSPLAT
// "CrashNotHandled" is obsolete; it used (not very successsfully)
@@ -3667,163 +3665,6 @@ void getFileList()
}
#endif
-void LLAppViewer::handleViewerCrash()
-{
- LL_INFOS("CRASHREPORT") << "Handle viewer crash entry." << LL_ENDL;
-
- LL_INFOS("CRASHREPORT") << "Last render pool type: " << LLPipeline::sCurRenderPoolType << LL_ENDL ;
-
- LLMemory::logMemoryInfo(true) ;
-
- //print out recorded call stacks if there are any.
- LLError::LLCallStacks::print();
-
- LLAppViewer* pApp = LLAppViewer::instance();
- if (pApp->beingDebugged())
- {
- // This will drop us into the debugger.
- abort();
- }
-
- if (LLApp::isCrashloggerDisabled())
- {
- abort();
- }
-
- // Returns whether a dialog was shown.
- // Only do the logic in here once
- if (pApp->mReportedCrash)
- {
- return;
- }
- pApp->mReportedCrash = TRUE;
-
- // Insert crash host url (url to post crash log to) if configured.
- std::string crashHostUrl = gSavedSettings.get<std::string>("CrashHostUrl");
- if(crashHostUrl != "")
- {
- gDebugInfo["Dynamic"]["CrashHostUrl"] = crashHostUrl;
- }
-
- LLParcel* parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
- if ( parcel && parcel->getMusicURL()[0])
- {
- gDebugInfo["Dynamic"]["ParcelMusicURL"] = parcel->getMusicURL();
- }
- if ( parcel && parcel->getMediaURL()[0])
- {
- gDebugInfo["Dynamic"]["ParcelMediaURL"] = parcel->getMediaURL();
- }
-
- gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
- gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = LLSD::Integer(LLMemory::getCurrentRSS() / 1024);
-
- if(gLogoutInProgress)
- {
- gDebugInfo["Dynamic"]["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH;
- }
- else
- {
- gDebugInfo["Dynamic"]["LastExecEvent"] = gLLErrorActivated ? LAST_EXEC_LLERROR_CRASH : LAST_EXEC_OTHER_CRASH;
- }
-
- if(gAgent.getRegion())
- {
- gDebugInfo["Dynamic"]["CurrentSimHost"] = gAgent.getRegion()->getSimHostName();
- gDebugInfo["Dynamic"]["CurrentRegion"] = gAgent.getRegion()->getName();
-
- const LLVector3& loc = gAgent.getPositionAgent();
- gDebugInfo["Dynamic"]["CurrentLocationX"] = loc.mV[0];
- gDebugInfo["Dynamic"]["CurrentLocationY"] = loc.mV[1];
- gDebugInfo["Dynamic"]["CurrentLocationZ"] = loc.mV[2];
- }
-
- if(LLAppViewer::instance()->mMainloopTimeout)
- {
- gDebugInfo["Dynamic"]["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
- }
-
- // The crash is being handled here so set this value to false.
- // Otherwise the crash logger will think this crash was a freeze.
- gDebugInfo["Dynamic"]["CrashNotHandled"] = LLSD::Boolean(false);
-
- //Write out the crash status file
- //Use marker file style setup, as that's the simplest, especially since
- //we're already in a crash situation
- if (gDirUtilp)
- {
- std::string crash_marker_file_name = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,
- gLLErrorActivated
- ? LLERROR_MARKER_FILE_NAME
- : ERROR_MARKER_FILE_NAME);
- LLAPRFile crash_marker_file ;
- crash_marker_file.open(crash_marker_file_name, LL_APR_WB);
- if (crash_marker_file.getFileHandle())
- {
- LL_INFOS("MarkerFile") << "Created crash marker file " << crash_marker_file_name << LL_ENDL;
- recordMarkerVersion(crash_marker_file);
- }
- else
- {
- LL_WARNS("MarkerFile") << "Cannot create error marker file " << crash_marker_file_name << LL_ENDL;
- }
- }
- else
- {
- LL_WARNS("MarkerFile") << "No gDirUtilp with which to create error marker file name" << LL_ENDL;
- }
-
-#ifdef LL_WINDOWS
- Sleep(200);
-#endif
-
- char *minidump_file = pApp->getMiniDumpFilename();
- LL_DEBUGS("CRASHREPORT") << "minidump file name " << minidump_file << LL_ENDL;
- if(minidump_file && minidump_file[0] != 0)
- {
- gDebugInfo["Dynamic"]["MinidumpPath"] = minidump_file;
- }
- else
- {
-#ifdef LL_WINDOWS
- getFileList();
-#else
- LL_WARNS("CRASHREPORT") << "no minidump file?" << LL_ENDL;
-#endif
- }
- gDebugInfo["Dynamic"]["CrashType"]="crash";
-
- if (gMessageSystem && gDirUtilp)
- {
- std::string filename;
- filename = gDirUtilp->getExpandedFilename(LL_PATH_DUMP, "stats.log");
- LL_DEBUGS("CRASHREPORT") << "recording stats " << filename << LL_ENDL;
- llofstream file(filename.c_str(), std::ios_base::binary);
- if(file.good())
- {
- gMessageSystem->summarizeLogs(file);
- file.close();
- }
- else
- {
- LL_WARNS("CRASHREPORT") << "problem recording stats" << LL_ENDL;
- }
- }
-
- if (gMessageSystem)
- {
- gMessageSystem->getCircuitInfo(gDebugInfo["CircuitInfo"]);
- gMessageSystem->stopLogging();
- }
-
- if (LLWorld::instanceExists()) LLWorld::getInstance()->getInfo(gDebugInfo["Dynamic"]);
-
- gDebugInfo["FatalMessage"] = LLError::getFatalMessage();
-
- // Close the debug file
- pApp->writeDebugInfo(false); //false answers the isStatic question with the least overhead.
-}
-
// static
void LLAppViewer::recordMarkerVersion(LLAPRFile& marker_file)
{
@@ -4675,7 +4516,6 @@ public:
static LLTrace::BlockTimerStatHandle FTM_AUDIO_UPDATE("Update Audio");
static LLTrace::BlockTimerStatHandle FTM_CLEANUP("Cleanup");
static LLTrace::BlockTimerStatHandle FTM_CLEANUP_DRAWABLES("Drawables");
-static LLTrace::BlockTimerStatHandle FTM_CLEANUP_OBJECTS("Objects");
static LLTrace::BlockTimerStatHandle FTM_IDLE_CB("Idle Callbacks");
static LLTrace::BlockTimerStatHandle FTM_LOD_UPDATE("Update LOD");
static LLTrace::BlockTimerStatHandle FTM_OBJECTLIST_UPDATE("Update Objectlist");
@@ -4972,7 +4812,6 @@ void LLAppViewer::idle()
{
LL_RECORD_BLOCK_TIME(FTM_CLEANUP);
{
- LL_RECORD_BLOCK_TIME(FTM_CLEANUP_OBJECTS);
gObjectList.cleanDeadObjects();
}
{
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 6e35da1b10..6d1496d517 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -115,7 +115,6 @@ public:
virtual bool restoreErrorTrap() = 0; // Require platform specific override to reset error handling mechanism.
// return false if the error trap needed restoration.
- static void handleViewerCrash(); // Hey! The viewer crashed. Do this, soon.
void checkForCrash();
// Thread accessors
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index dc487967fc..9f58f90326 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -80,8 +80,6 @@ int main( int argc, char **argv )
// install unexpected exception handler
gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
- // install crash handlers
- viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
bool ok = viewer_app_ptr->init();
if(!ok)
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index cb5cac6f2d..8b313a321b 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -83,8 +83,6 @@ void constructViewer()
}
gViewerAppPtr = new LLAppViewerMacOSX();
-
- gViewerAppPtr->setErrorHandler(LLAppViewer::handleViewerCrash);
}
bool initViewer()
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index fde8ff5c1f..8cf80f388b 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -428,8 +428,6 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
gOldTerminateHandler = std::set_terminate(exceptionTerminateHandler);
- viewer_app_ptr->setErrorHandler(LLAppViewer::handleViewerCrash);
-
// Set a debug info flag to indicate if multiple instances are running.
bool found_other_instance = !create_app_mutex();
gDebugInfo["FoundOtherInstanceAtStartup"] = LLSD::Boolean(found_other_instance);
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index f778634d25..10cde35f9c 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -85,6 +85,7 @@ struct LLAvatarData
std::string profile_url;
U8 caption_index;
std::string caption_text;
+ std::string customer_type;
U32 flags;
BOOL allow_publish;
};
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 07b7be0fc8..3a71dfb0c1 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -282,6 +282,7 @@ void LLDrawPoolAlpha::renderDebugAlpha()
gGL.diffuseColor4f(1, 0, 0, 1);
gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::getSmokeImage());
+
renderAlphaHighlight();
pushUntexturedBatches(LLRenderPass::PASS_ALPHA_MASK);
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index c2667bedaa..353861969c 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -200,8 +200,6 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
break;
case FFLOAD_COLLADA:
mOFN.lpstrFilter = COLLADA_FILTER \
- L"\0";
- break;
case FFLOAD_XML:
mOFN.lpstrFilter = XML_FILTER \
L"\0";
@@ -780,7 +778,6 @@ void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension,
creator = "\?\?\?\?";
extension = "xaf";
break;
-
case LLFilePicker::FFSAVE_GLTF:
type = "\?\?\?\?";
creator = "\?\?\?\?";
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index 6e8143384a..bb47feaa95 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -475,6 +475,8 @@ void LLFloaterEditExtDayCycle::refresh()
void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
{
setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
+
+ showHDRNotification(std::dynamic_pointer_cast<LLSettingsDay>(settings));
}
void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)
@@ -1710,6 +1712,28 @@ void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track)
}
}
+void LLFloaterEditExtDayCycle::showHDRNotification(const LLSettingsDay::ptr_t &pday)
+{
+ for (U32 i = LLSettingsDay::TRACK_GROUND_LEVEL; i <= LLSettingsDay::TRACK_MAX; i++)
+ {
+ LLSettingsDay::CycleTrack_t &day_track = pday->getCycleTrack(i);
+
+ LLSettingsDay::CycleTrack_t::iterator iter = day_track.begin();
+ LLSettingsDay::CycleTrack_t::iterator end = day_track.end();
+
+ while (iter != end)
+ {
+ LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(iter->second);
+ if (sky && sky->canAutoAdjust())
+ {
+ LLNotificationsUtil::add("AutoAdjustHDRSky");
+ return;
+ }
+ iter++;
+ }
+ }
+}
+
void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 source_track, S32 dest_track, LLSettingsBase::TrackPosition frame)
{
std::function<void()> cb = [this, settings, frame, source_track, dest_track]()
diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h
index ab5d12fa36..025a2ee5d1 100644
--- a/indra/newview/llfloatereditextdaycycle.h
+++ b/indra/newview/llfloatereditextdaycycle.h
@@ -188,6 +188,8 @@ private:
bool isRemovingFrameAllowed();
bool isAddingFrameAllowed();
+ void showHDRNotification(const LLSettingsDay::ptr_t &pday);
+
LLSettingsDay::ptr_t mEditDay; // edited copy
LLSettingsDay::Seconds mDayLength;
U32 mCurrentTrack;
diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp
index f9e8963479..18be4fffda 100644
--- a/indra/newview/llfloaterenvironmentadjust.cpp
+++ b/indra/newview/llfloaterenvironmentadjust.cpp
@@ -174,7 +174,8 @@ void LLFloaterEnvironmentAdjust::refresh()
getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setValue(mLiveSky->getCloudNoiseTextureId());
getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setValue(mLiveWater->getNormalMapID());
- getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(mLiveSky->getReflectionProbeAmbiance());
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(mLiveSky->getReflectionProbeAmbiance(should_auto_adjust));
LLColor3 glow(mLiveSky->getGlow());
@@ -488,7 +489,9 @@ void LLFloaterEnvironmentAdjust::onReflectionProbeAmbianceChanged()
void LLFloaterEnvironmentAdjust::updateGammaLabel()
{
if (!mLiveSky) return;
- F32 ambiance = mLiveSky->getReflectionProbeAmbiance();
+
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ F32 ambiance = mLiveSky->getReflectionProbeAmbiance(should_auto_adjust);
if (ambiance != 0.f)
{
childSetValue("scene_gamma_label", getString("hdr_string"));
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index b9dc14ac1a..bb6584302d 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -182,6 +182,12 @@ void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::p
syncronizeTabs();
refresh();
LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+
+ // teach user about HDR settings
+ if (mSettings && ((LLSettingsSky*)mSettings.get())->canAutoAdjust())
+ {
+ LLNotificationsUtil::add("AutoAdjustHDRSky");
+ }
}
void LLFloaterFixedEnvironment::syncronizeTabs()
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index f1807f1c5b..0d2c6d8e4c 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -108,6 +108,8 @@ LLFloaterIMNearbyChat::LLFloaterIMNearbyChat(const LLSD& llsd)
mEnableCallbackRegistrar.add("Avatar.EnableGearItem", boost::bind(&cb_do_nothing));
mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&cb_do_nothing));
mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&cb_do_nothing));
+
+ mMinFloaterHeight = EXPANDED_MIN_HEIGHT;
}
//static
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index 78271369d2..af4e7f5aff 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -92,6 +92,8 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2));
mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2));
mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&cb_group_do_nothing));
+
+ mMinFloaterHeight = getMinHeight();
}
LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
@@ -934,10 +936,13 @@ void LLFloaterIMSessionTab::reshapeFloater(bool collapse)
S32 height = mContentPanel->getRect().getHeight() + mToolbarPanel->getRect().getHeight()
+ mChatLayoutPanel->getRect().getHeight() - mChatLayoutPanelHeight + 2;
floater_rect.mTop -= height;
+
+ setResizeLimits(getMinWidth(), floater_rect.getHeight());
}
else
{
floater_rect.mTop = floater_rect.mBottom + mFloaterHeight;
+ setResizeLimits(getMinWidth(), mMinFloaterHeight);
}
enableResizeCtrls(true, true, !collapse);
@@ -962,6 +967,7 @@ void LLFloaterIMSessionTab::restoreFloater()
setShape(floater_rect, true);
mBodyStack->updateLayout();
mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon"));
+ setResizeLimits(getMinWidth(), mMinFloaterHeight);
setMessagePaneExpanded(true);
saveCollapsedState();
mInputEditor->enableSingleLineMode(false);
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 9f00917647..d478922617 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -152,6 +152,7 @@ protected:
bool mMessagePaneExpanded;
bool mIsParticipantListExpanded;
+ S32 mMinFloaterHeight;
LLIMModel::LLIMSession* mSession;
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index da7a4733c7..a24f04ccfb 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -317,7 +317,6 @@ void LLFloaterRegionInfo::onOpen(const LLSD& key)
}
refreshFromRegion(gAgent.getRegion());
requestRegionInfo();
- requestMeshRezInfo();
if (!mGodLevelChangeSlot.connected())
{
@@ -1006,19 +1005,6 @@ bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const L
return false;
}
-void LLFloaterRegionInfo::requestMeshRezInfo()
-{
- std::string sim_console_url = gAgent.getRegionCapability("SimConsoleAsync");
-
- if (!sim_console_url.empty())
- {
- std::string request_str = "get mesh_rez_enabled";
-
- LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(sim_console_url, LLSD(request_str),
- "Requested mesh_rez_enabled", "Error requesting mesh_rez_enabled");
- }
-}
-
// setregioninfo
// strings[0] = 'Y' - block terraform, 'N' - not
// strings[1] = 'Y' - block fly, 'N' - not
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index c34dbb62e8..3eb39b250f 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -102,7 +102,6 @@ public:
void onRegionChanged();
void requestRegionInfo();
- void requestMeshRezInfo();
void enableTopButtons();
void disableTopButtons();
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index 082bb888b1..d29ecbbf95 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -45,15 +45,9 @@
LLFloaterTranslationSettings::LLFloaterTranslationSettings(const LLSD& key)
: LLFloater(key)
, mMachineTranslationCB(NULL)
-, mLanguageCombo(NULL)
-, mTranslationServiceRadioGroup(NULL)
-, mBingAPIKeyEditor(NULL)
-, mGoogleAPIKeyEditor(NULL)
-, mBingVerifyBtn(NULL)
-, mGoogleVerifyBtn(NULL)
-, mOKBtn(NULL)
-, mBingKeyVerified(false)
+, mAzureKeyVerified(false)
, mGoogleKeyVerified(false)
+, mDeepLKeyVerified(false)
{
}
@@ -63,24 +57,54 @@ BOOL LLFloaterTranslationSettings::postBuild()
mMachineTranslationCB = getChild<LLCheckBoxCtrl>("translate_chat_checkbox");
mLanguageCombo = getChild<LLComboBox>("translate_language_combo");
mTranslationServiceRadioGroup = getChild<LLRadioGroup>("translation_service_rg");
- mBingAPIKeyEditor = getChild<LLLineEditor>("bing_api_key");
+ mAzureAPIEndpointEditor = getChild<LLComboBox>("azure_api_endpoint_combo");
+ mAzureAPIKeyEditor = getChild<LLLineEditor>("azure_api_key");
+ mAzureAPIRegionEditor = getChild<LLLineEditor>("azure_api_region");
mGoogleAPIKeyEditor = getChild<LLLineEditor>("google_api_key");
- mBingVerifyBtn = getChild<LLButton>("verify_bing_api_key_btn");
+ mDeepLAPIDomainCombo = getChild<LLComboBox>("deepl_api_domain_combo");
+ mDeepLAPIKeyEditor = getChild<LLLineEditor>("deepl_api_key");
+ mAzureVerifyBtn = getChild<LLButton>("verify_azure_api_key_btn");
mGoogleVerifyBtn = getChild<LLButton>("verify_google_api_key_btn");
+ mDeepLVerifyBtn = getChild<LLButton>("verify_deepl_api_key_btn");
mOKBtn = getChild<LLButton>("ok_btn");
mMachineTranslationCB->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::updateControlsEnabledState, this));
mTranslationServiceRadioGroup->setCommitCallback(boost::bind(&LLFloaterTranslationSettings::updateControlsEnabledState, this));
mOKBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnOK, this));
getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloater::closeFloater, this, false));
- mBingVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnBingVerify, this));
+ mAzureVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnAzureVerify, this));
mGoogleVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnGoogleVerify, this));
+ mDeepLVerifyBtn->setClickedCallback(boost::bind(&LLFloaterTranslationSettings::onBtnDeepLVerify, this));
+
+ mAzureAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1));
+ mAzureAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this), NULL);
+ mAzureAPIRegionEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1));
+ mAzureAPIRegionEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onAzureKeyEdited, this), NULL);
+
+ mAzureAPIEndpointEditor->setFocusLostCallback([this](LLFocusableElement*)
+ {
+ setAzureVerified(false, false, 0);
+ });
+ mAzureAPIEndpointEditor->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param)
+ {
+ setAzureVerified(false, false, 0);
+ });
- mBingAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1));
- mBingAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onBingKeyEdited, this), NULL);
mGoogleAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1));
mGoogleAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onGoogleKeyEdited, this), NULL);
+ mDeepLAPIKeyEditor->setFocusReceivedCallback(boost::bind(&LLFloaterTranslationSettings::onEditorFocused, this, _1));
+ mDeepLAPIKeyEditor->setKeystrokeCallback(boost::bind(&LLFloaterTranslationSettings::onDeepLKeyEdited, this), NULL);
+
+ mDeepLAPIDomainCombo->setFocusLostCallback([this](LLFocusableElement*)
+ {
+ setDeepLVerified(false, false, 0);
+ });
+ mDeepLAPIDomainCombo->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param)
+ {
+ setDeepLVerified(false, false, 0);
+ });
+
center();
return TRUE;
}
@@ -92,17 +116,28 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key)
mLanguageCombo->setSelectedByValue(gSavedSettings.getString("TranslateLanguage"), TRUE);
mTranslationServiceRadioGroup->setSelectedByValue(gSavedSettings.getString("TranslationService"), TRUE);
- std::string bing_key = gSavedSettings.getString("BingTranslateAPIKey");
- if (!bing_key.empty())
+ LLSD azure_key = gSavedSettings.getLLSD("AzureTranslateAPIKey");
+ if (azure_key.isMap() && !azure_key["id"].asString().empty())
{
- mBingAPIKeyEditor->setText(bing_key);
- mBingAPIKeyEditor->setTentative(FALSE);
- verifyKey(LLTranslate::SERVICE_BING, bing_key, false);
+ mAzureAPIKeyEditor->setText(azure_key["id"].asString());
+ mAzureAPIKeyEditor->setTentative(false);
+ if (azure_key.has("region") && !azure_key["region"].asString().empty())
+ {
+ mAzureAPIRegionEditor->setText(azure_key["region"].asString());
+ mAzureAPIRegionEditor->setTentative(false);
+ }
+ else
+ {
+ mAzureAPIRegionEditor->setTentative(true);
+ }
+ mAzureAPIEndpointEditor->setValue(azure_key["endpoint"]);
+ verifyKey(LLTranslate::SERVICE_AZURE, azure_key, false);
}
else
{
- mBingAPIKeyEditor->setTentative(TRUE);
- mBingKeyVerified = FALSE;
+ mAzureAPIKeyEditor->setTentative(TRUE);
+ mAzureAPIRegionEditor->setTentative(true);
+ mAzureKeyVerified = FALSE;
}
std::string google_key = gSavedSettings.getString("GoogleTranslateAPIKey");
@@ -118,39 +153,74 @@ void LLFloaterTranslationSettings::onOpen(const LLSD& key)
mGoogleKeyVerified = FALSE;
}
+ LLSD deepl_key = gSavedSettings.getLLSD("DeepLTranslateAPIKey");
+ if (deepl_key.isMap() && !deepl_key["id"].asString().empty())
+ {
+ mDeepLAPIKeyEditor->setText(deepl_key["id"].asString());
+ mDeepLAPIKeyEditor->setTentative(false);
+ mDeepLAPIDomainCombo->setValue(deepl_key["domain"]);
+ verifyKey(LLTranslate::SERVICE_DEEPL, deepl_key, false);
+ }
+ else
+ {
+ mDeepLAPIKeyEditor->setTentative(TRUE);
+ mDeepLKeyVerified = FALSE;
+ }
+
updateControlsEnabledState();
}
-void LLFloaterTranslationSettings::setBingVerified(bool ok, bool alert)
+void LLFloaterTranslationSettings::setAzureVerified(bool ok, bool alert, S32 status)
{
if (alert)
{
- showAlert(ok ? "bing_api_key_verified" : "bing_api_key_not_verified");
+ showAlert(ok ? "azure_api_key_verified" : "azure_api_key_not_verified", status);
}
- mBingKeyVerified = ok;
+ mAzureKeyVerified = ok;
updateControlsEnabledState();
}
-void LLFloaterTranslationSettings::setGoogleVerified(bool ok, bool alert)
+void LLFloaterTranslationSettings::setGoogleVerified(bool ok, bool alert, S32 status)
{
if (alert)
{
- showAlert(ok ? "google_api_key_verified" : "google_api_key_not_verified");
+ showAlert(ok ? "google_api_key_verified" : "google_api_key_not_verified", status);
}
mGoogleKeyVerified = ok;
updateControlsEnabledState();
}
+void LLFloaterTranslationSettings::setDeepLVerified(bool ok, bool alert, S32 status)
+{
+ if (alert)
+ {
+ showAlert(ok ? "deepl_api_key_verified" : "deepl_api_key_not_verified", status);
+ }
+
+ mDeepLKeyVerified = ok;
+ updateControlsEnabledState();
+}
+
std::string LLFloaterTranslationSettings::getSelectedService() const
{
return mTranslationServiceRadioGroup->getSelectedValue().asString();
}
-std::string LLFloaterTranslationSettings::getEnteredBingKey() const
+LLSD LLFloaterTranslationSettings::getEnteredAzureKey() const
{
- return mBingAPIKeyEditor->getTentative() ? LLStringUtil::null : mBingAPIKeyEditor->getText();
+ LLSD key;
+ if (!mAzureAPIKeyEditor->getTentative())
+ {
+ key["endpoint"] = mAzureAPIEndpointEditor->getValue();
+ key["id"] = mAzureAPIKeyEditor->getText();
+ if (!mAzureAPIRegionEditor->getTentative())
+ {
+ key["region"] = mAzureAPIRegionEditor->getText();
+ }
+ }
+ return key;
}
std::string LLFloaterTranslationSettings::getEnteredGoogleKey() const
@@ -158,10 +228,26 @@ std::string LLFloaterTranslationSettings::getEnteredGoogleKey() const
return mGoogleAPIKeyEditor->getTentative() ? LLStringUtil::null : mGoogleAPIKeyEditor->getText();
}
-void LLFloaterTranslationSettings::showAlert(const std::string& msg_name) const
+LLSD LLFloaterTranslationSettings::getEnteredDeepLKey() const
+{
+ LLSD key;
+ if (!mDeepLAPIKeyEditor->getTentative())
+ {
+ key["domain"] = mDeepLAPIDomainCombo->getValue();
+ key["id"] = mDeepLAPIKeyEditor->getText();
+ }
+ return key;
+}
+
+void LLFloaterTranslationSettings::showAlert(const std::string& msg_name, S32 status) const
{
+ LLStringUtil::format_map_t string_args;
+ // For now just show an http error code, whole 'reason' string might be added later
+ string_args["[STATUS]"] = llformat("%d", status);
+ std::string message = getString(msg_name, string_args);
+
LLSD args;
- args["MESSAGE"] = getString(msg_name);
+ args["MESSAGE"] = message;
LLNotificationsUtil::add("GenericAlert", args);
}
@@ -170,34 +256,51 @@ void LLFloaterTranslationSettings::updateControlsEnabledState()
// Enable/disable controls based on the checkbox value.
bool on = mMachineTranslationCB->getValue().asBoolean();
std::string service = getSelectedService();
- bool bing_selected = service == "bing";
+ bool azure_selected = service == "azure";
bool google_selected = service == "google";
+ bool deepl_selected = service == "deepl";
mTranslationServiceRadioGroup->setEnabled(on);
mLanguageCombo->setEnabled(on);
- getChild<LLTextBox>("bing_api_key_label")->setEnabled(on);
- mBingAPIKeyEditor->setEnabled(on);
+ // MS Azure
+ getChild<LLTextBox>("azure_api_endoint_label")->setEnabled(on);
+ mAzureAPIEndpointEditor->setEnabled(on && azure_selected);
+ getChild<LLTextBox>("azure_api_key_label")->setEnabled(on);
+ mAzureAPIKeyEditor->setEnabled(on && azure_selected);
+ getChild<LLTextBox>("azure_api_region_label")->setEnabled(on);
+ mAzureAPIRegionEditor->setEnabled(on && azure_selected);
- getChild<LLTextBox>("google_api_key_label")->setEnabled(on);
- mGoogleAPIKeyEditor->setEnabled(on);
+ mAzureVerifyBtn->setEnabled(on && azure_selected &&
+ !mAzureKeyVerified && getEnteredAzureKey().isMap());
- mBingAPIKeyEditor->setEnabled(on && bing_selected);
- mGoogleAPIKeyEditor->setEnabled(on && google_selected);
+ // Google
+ getChild<LLTextBox>("google_api_key_label")->setEnabled(on);
+ mGoogleAPIKeyEditor->setEnabled(on && google_selected);
- mBingVerifyBtn->setEnabled(on && bing_selected &&
- !mBingKeyVerified && !getEnteredBingKey().empty());
mGoogleVerifyBtn->setEnabled(on && google_selected &&
!mGoogleKeyVerified && !getEnteredGoogleKey().empty());
- bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified);
+ // DeepL
+ getChild<LLTextBox>("deepl_api_domain_label")->setEnabled(on);
+ mDeepLAPIDomainCombo->setEnabled(on && deepl_selected);
+ getChild<LLTextBox>("deepl_api_key_label")->setEnabled(on);
+ mDeepLAPIKeyEditor->setEnabled(on && deepl_selected);
+
+ mDeepLVerifyBtn->setEnabled(on && deepl_selected &&
+ !mDeepLKeyVerified && getEnteredDeepLKey().isMap());
+
+ bool service_verified =
+ (azure_selected && mAzureKeyVerified)
+ || (google_selected && mGoogleKeyVerified)
+ || (deepl_selected && mDeepLKeyVerified);
gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified);
mOKBtn->setEnabled(!on || service_verified);
}
/*static*/
-void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, bool alert)
+void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, bool alert, S32 status)
{
LLFloaterTranslationSettings* floater =
LLFloaterReg::getTypedInstance<LLFloaterTranslationSettings>("prefs_translation");
@@ -210,20 +313,23 @@ void LLFloaterTranslationSettings::setVerificationStatus(int service, bool ok, b
switch (service)
{
- case LLTranslate::SERVICE_BING:
- floater->setBingVerified(ok, alert);
+ case LLTranslate::SERVICE_AZURE:
+ floater->setAzureVerified(ok, alert, status);
break;
case LLTranslate::SERVICE_GOOGLE:
- floater->setGoogleVerified(ok, alert);
+ floater->setGoogleVerified(ok, alert, status);
+ break;
+ case LLTranslate::SERVICE_DEEPL:
+ floater->setDeepLVerified(ok, alert, status);
break;
}
}
-void LLFloaterTranslationSettings::verifyKey(int service, const std::string& key, bool alert)
+void LLFloaterTranslationSettings::verifyKey(int service, const LLSD& key, bool alert)
{
LLTranslate::verifyKey(static_cast<LLTranslate::EService>(service), key,
- boost::bind(&LLFloaterTranslationSettings::setVerificationStatus, _1, _2, alert));
+ boost::bind(&LLFloaterTranslationSettings::setVerificationStatus, _1, _2, alert, _3));
}
void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control)
@@ -239,11 +345,13 @@ void LLFloaterTranslationSettings::onEditorFocused(LLFocusableElement* control)
}
}
-void LLFloaterTranslationSettings::onBingKeyEdited()
+void LLFloaterTranslationSettings::onAzureKeyEdited()
{
- if (mBingAPIKeyEditor->isDirty())
+ if (mAzureAPIKeyEditor->isDirty()
+ || mAzureAPIRegionEditor->isDirty())
{
- setBingVerified(false, false);
+ // todo: verify mAzureAPIEndpointEditor url
+ setAzureVerified(false, false, 0);
}
}
@@ -251,16 +359,24 @@ void LLFloaterTranslationSettings::onGoogleKeyEdited()
{
if (mGoogleAPIKeyEditor->isDirty())
{
- setGoogleVerified(false, false);
+ setGoogleVerified(false, false, 0);
}
}
-void LLFloaterTranslationSettings::onBtnBingVerify()
+void LLFloaterTranslationSettings::onDeepLKeyEdited()
{
- std::string key = getEnteredBingKey();
- if (!key.empty())
+ if (mDeepLAPIKeyEditor->isDirty())
+ {
+ setDeepLVerified(false, false, 0);
+ }
+}
+
+void LLFloaterTranslationSettings::onBtnAzureVerify()
+{
+ LLSD key = getEnteredAzureKey();
+ if (key.isMap())
{
- verifyKey(LLTranslate::SERVICE_BING, key);
+ verifyKey(LLTranslate::SERVICE_AZURE, key);
}
}
@@ -269,26 +385,40 @@ void LLFloaterTranslationSettings::onBtnGoogleVerify()
std::string key = getEnteredGoogleKey();
if (!key.empty())
{
- verifyKey(LLTranslate::SERVICE_GOOGLE, key);
+ verifyKey(LLTranslate::SERVICE_GOOGLE, LLSD(key));
}
}
+
+void LLFloaterTranslationSettings::onBtnDeepLVerify()
+{
+ LLSD key = getEnteredDeepLKey();
+ if (key.isMap())
+ {
+ verifyKey(LLTranslate::SERVICE_DEEPL, key);
+ }
+}
+
void LLFloaterTranslationSettings::onClose(bool app_quitting)
{
std::string service = gSavedSettings.getString("TranslationService");
- bool bing_selected = service == "bing";
+ bool azure_selected = service == "azure";
bool google_selected = service == "google";
+ bool deepl_selected = service == "deepl";
- bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified);
- gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified);
-
+ bool service_verified =
+ (azure_selected && mAzureKeyVerified)
+ || (google_selected && mGoogleKeyVerified)
+ || (deepl_selected && mDeepLKeyVerified);
+ gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified);
}
void LLFloaterTranslationSettings::onBtnOK()
{
gSavedSettings.setBOOL("TranslateChat", mMachineTranslationCB->getValue().asBoolean());
gSavedSettings.setString("TranslateLanguage", mLanguageCombo->getSelectedValue().asString());
gSavedSettings.setString("TranslationService", getSelectedService());
- gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
+ gSavedSettings.setLLSD("AzureTranslateAPIKey", getEnteredAzureKey());
gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
+ gSavedSettings.setLLSD("DeepLTranslateAPIKey", getEnteredDeepLKey());
closeFloater(false);
}
diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h
index 2a15eacded..eff0803fdd 100644
--- a/indra/newview/llfloatertranslationsettings.h
+++ b/indra/newview/llfloatertranslationsettings.h
@@ -42,38 +42,48 @@ public:
/*virtual*/ BOOL postBuild();
/*virtual*/ void onOpen(const LLSD& key);
- void setBingVerified(bool ok, bool alert);
- void setGoogleVerified(bool ok, bool alert);
+ void setAzureVerified(bool ok, bool alert, S32 status);
+ void setGoogleVerified(bool ok, bool alert, S32 status);
+ void setDeepLVerified(bool ok, bool alert, S32 status);
void onClose(bool app_quitting);
private:
std::string getSelectedService() const;
- std::string getEnteredBingKey() const;
+ LLSD getEnteredAzureKey() const;
std::string getEnteredGoogleKey() const;
- void showAlert(const std::string& msg_name) const;
+ LLSD getEnteredDeepLKey() const;
+ void showAlert(const std::string& msg_name, S32 status) const;
void updateControlsEnabledState();
- void verifyKey(int service, const std::string& key, bool alert = true);
+ void verifyKey(int service, const LLSD& key, bool alert = true);
void onEditorFocused(LLFocusableElement* control);
- void onBingKeyEdited();
+ void onAzureKeyEdited();
void onGoogleKeyEdited();
- void onBtnBingVerify();
+ void onDeepLKeyEdited();
+ void onBtnAzureVerify();
void onBtnGoogleVerify();
+ void onBtnDeepLVerify();
void onBtnOK();
- static void setVerificationStatus(int service, bool alert, bool ok);
+ static void setVerificationStatus(int service, bool alert, bool ok, S32 status);
LLCheckBoxCtrl* mMachineTranslationCB;
LLComboBox* mLanguageCombo;
- LLLineEditor* mBingAPIKeyEditor;
+ LLComboBox* mAzureAPIEndpointEditor;
+ LLLineEditor* mAzureAPIKeyEditor;
+ LLLineEditor* mAzureAPIRegionEditor;
LLLineEditor* mGoogleAPIKeyEditor;
+ LLComboBox* mDeepLAPIDomainCombo;
+ LLLineEditor* mDeepLAPIKeyEditor;
LLRadioGroup* mTranslationServiceRadioGroup;
- LLButton* mBingVerifyBtn;
+ LLButton* mAzureVerifyBtn;
LLButton* mGoogleVerifyBtn;
+ LLButton* mDeepLVerifyBtn;
LLButton* mOKBtn;
- bool mBingKeyVerified;
+ bool mAzureKeyVerified;
bool mGoogleKeyVerified;
+ bool mDeepLKeyVerified;
};
#endif // LL_LLFLOATERTRANSLATIONSETTINGS_H
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index 68801b0895..6f93a78ca6 100644
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -47,6 +47,7 @@ public:
/*virtual*/ void onOpen(const LLSD& notification_id);
/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
+ /*virtual*/ void deleteAllChildren();
/*virtual*/ void removeChild(LLView* child);
private:
void onToastDestroy(LLToast * toast);
@@ -122,6 +123,12 @@ BOOL LLInspectToast::handleToolTip(S32 x, S32 y, MASK mask)
return LLFloater::handleToolTip(x, y, mask);
}
+void LLInspectToast::deleteAllChildren()
+{
+ mPanel = NULL;
+ LLInspect::deleteAllChildren();
+}
+
// virtual
void LLInspectToast::removeChild(LLView* child)
{
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 7ccb8b807d..3bffd96038 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -592,7 +592,11 @@ const LLUUID LLInventoryModel::findCategoryUUIDForTypeInRoot(
}
}
- if(rv.isNull() && create_folder && root_id.notNull())
+ if(rv.isNull()
+ && root_id.notNull()
+ && create_folder
+ && preferred_type != LLFolderType::FT_MARKETPLACE_LISTINGS
+ && preferred_type != LLFolderType::FT_OUTBOX)
{
if (isInventoryUsable())
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 4a9b471a47..f544b318d6 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -30,8 +30,10 @@
#include "llagent.h"
#include "llappviewer.h"
#include "llcallbacklist.h"
-#include "llinventorypanel.h"
#include "llinventorymodel.h"
+#include "llinventorypanel.h"
+#include "llnotificationsutil.h"
+#include "llstartup.h"
#include "llviewercontrol.h"
#include "llviewerinventory.h"
#include "llviewermessage.h"
@@ -408,6 +410,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
// *TODO: Think I'd like to get a shared pointer to this and share it
// among all the folder requests.
uuid_vec_t recursive_cats;
+ uuid_vec_t all_cats; // dupplicate avoidance
LLSD folder_request_body;
LLSD folder_request_body_lib;
@@ -438,7 +441,8 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
if (cat)
{
- if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion())
+ if (LLViewerInventoryCategory::VERSION_UNKNOWN == cat->getVersion()
+ && std::find(all_cats.begin(), all_cats.end(), cat_id) == all_cats.end())
{
LLSD folder_sd;
folder_sd["folder_id"] = cat->getUUID();
@@ -477,6 +481,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
{
recursive_cats.push_back(cat_id);
}
+ all_cats.push_back(cat_id);
}
else
{
@@ -796,6 +801,63 @@ void BGFolderHttpHandler::processFailure(LLCore::HttpStatus status, LLCore::Http
<< LLCoreHttpUtil::responseToString(response) << "]" << LL_ENDL;
// Could use a 404 test here to try to detect revoked caps...
+
+ if(status == LLCore::HttpStatus(HTTP_FORBIDDEN))
+ {
+ // Too large, split into two if possible
+ if (gDisconnected || LLApp::isExiting())
+ {
+ return;
+ }
+
+ const std::string url(gAgent.getRegionCapability("FetchInventoryDescendents2"));
+ if (url.empty())
+ {
+ LL_WARNS(LOG_INV) << "Failed to get AIS2 cap" << LL_ENDL;
+ return;
+ }
+
+ S32 size = mRequestSD["folders"].size();
+
+ if (size > 1)
+ {
+ // Can split, assume that this isn't the library
+ LLSD folders;
+ uuid_vec_t recursive_cats;
+ LLSD::array_iterator iter = mRequestSD["folders"].beginArray();
+ LLSD::array_iterator end = mRequestSD["folders"].endArray();
+ while (iter != end)
+ {
+ folders.append(*iter);
+ LLUUID fodler_id = iter->get("folder_id").asUUID();
+ if (std::find(mRecursiveCatUUIDs.begin(), mRecursiveCatUUIDs.end(), fodler_id) != mRecursiveCatUUIDs.end())
+ {
+ recursive_cats.push_back(fodler_id);
+ }
+ if (folders.size() == (S32)(size / 2))
+ {
+ LLSD request_body;
+ request_body["folders"] = folders;
+ LLCore::HttpHandler::ptr_t handler(new BGFolderHttpHandler(request_body, recursive_cats));
+ gInventory.requestPost(false, url, request_body, handler, "Inventory Folder");
+ recursive_cats.clear();
+ folders.clear();
+ }
+ iter++;
+ }
+
+ LLSD request_body;
+ request_body["folders"] = folders;
+ LLCore::HttpHandler::ptr_t handler(new BGFolderHttpHandler(request_body, recursive_cats));
+ gInventory.requestPost(false, url, request_body, handler, "Inventory Folder");
+ return;
+ }
+ else
+ {
+ // Can't split
+ LLNotificationsUtil::add("InventoryLimitReachedAIS");
+ }
+ }
// This was originally the request retry logic for the inventory
// request which tested on HTTP_INTERNAL_ERROR status. This
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 2c9ed26a39..8d86cf765c 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1268,8 +1268,10 @@ BOOL LLInventoryPanel::handleHover(S32 x, S32 y, MASK mask)
{
BOOL handled = LLView::handleHover(x, y, mask);
if(handled)
- {
- ECursorType cursor = getWindow()->getCursor();
+ {
+ // getCursor gets current cursor, setCursor sets next cursor
+ // check that children didn't set own 'next' cursor
+ ECursorType cursor = getWindow()->getNextCursor();
if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() && cursor == UI_CURSOR_ARROW)
{
// replace arrow cursor with arrow and hourglass cursor
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
index 609d8ea5d7..3a0e64985c 100644
--- a/indra/newview/llmaterialeditor.cpp
+++ b/indra/newview/llmaterialeditor.cpp
@@ -1327,9 +1327,7 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std:
[](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response)
{
// done callback
- LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL;
- LLSD params = llsd::map("ASSET_ID", new_asset_id);
- LLNotificationsUtil::add("MaterialCreated", params);
+ LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL;
},
nullptr // failure callback, floater already closed
);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 67bf6827ad..2118ee74d3 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3021,7 +3021,7 @@ S32 LLMeshRepository::getActualMeshLOD(LLMeshHeader& header, S32 lod)
}
//search up to find then ext available higher lod
- for (S32 i = lod+1; i < 4; ++i)
+ for (S32 i = lod+1; i < LLVolumeLODGroup::NUM_LODS; ++i)
{
if (header.mLodSize[i] > 0)
{
@@ -3183,7 +3183,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status)
// Can't get the header so none of the LODs will be available
LLMutexLock lock(gMeshRepo.mThread->mMutex);
- for (int i(0); i < 4; ++i)
+ for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i)
{
gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i));
}
@@ -3212,7 +3212,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
// Can't get the header so none of the LODs will be available
LLMutexLock lock(gMeshRepo.mThread->mMutex);
- for (int i(0); i < 4; ++i)
+ for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i)
{
gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i));
}
@@ -3293,7 +3293,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
// headerReceived() parsed header, but header's data is invalid so none of the LODs will be available
LLMutexLock lock(gMeshRepo.mThread->mMutex);
- for (int i(0); i < 4; ++i)
+ for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i)
{
gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i));
}
@@ -3654,7 +3654,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
// Manage time-to-load metrics for mesh download operations.
metricsProgress(1);
- if (detail < 0 || detail >= 4)
+ if (detail < 0 || detail >= LLVolumeLODGroup::NUM_LODS)
{
return detail;
}
@@ -3717,7 +3717,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
}
//no lower LOD is a available, is a higher lod available?
- for (S32 i = detail+1; i < 4; ++i)
+ for (S32 i = detail+1; i < LLVolumeLODGroup::NUM_LODS; ++i)
{
LLVolume* lod = group->refLOD(i);
if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
@@ -3918,7 +3918,7 @@ void LLMeshRepository::notifyLoadedMeshes()
//create score map
std::map<LLUUID, F32> score_map;
- for (U32 i = 0; i < 4; ++i)
+ for (U32 i = 0; i < LLVolumeLODGroup::NUM_LODS; ++i)
{
for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter)
{
@@ -4067,7 +4067,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
if (sys_volume)
{
sys_volume->copyVolumeFaces(volume);
- sys_volume->setMeshAssetLoaded(TRUE);
+ sys_volume->setMeshAssetLoaded(true);
LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);
}
else
@@ -4099,6 +4099,12 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params,
{
F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod);
+ LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, lod);
+ if (sys_volume)
+ {
+ sys_volume->setMeshAssetUnavaliable(true);
+ }
+
for (LLVOVolume* vobj : obj_iter->second)
{
if (vobj)
@@ -4255,6 +4261,37 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
return false;
}
+bool LLMeshRepository::hasSkinInfo(const LLUUID& mesh_id)
+{
+ if (mesh_id.isNull())
+ {
+ return false;
+ }
+
+ if (mThread->hasSkinInfoInHeader(mesh_id))
+ {
+ return true;
+ }
+
+ const LLMeshSkinInfo* skininfo = getSkinInfo(mesh_id);
+ if (skininfo)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool LLMeshRepository::hasHeader(const LLUUID& mesh_id)
+{
+ if (mesh_id.isNull())
+ {
+ return false;
+ }
+
+ return mThread->hasHeader(mesh_id);
+}
+
bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
{
LLMutexLock lock(mHeaderMutex);
@@ -4271,6 +4308,29 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
return false;
}
+bool LLMeshRepoThread::hasSkinInfoInHeader(const LLUUID& mesh_id)
+{
+ LLMutexLock lock(mHeaderMutex);
+ mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+ if (iter != mMeshHeader.end() && iter->second.first > 0)
+ {
+ LLMeshHeader& mesh = iter->second.second;
+ if (mesh.mSkinOffset >= 0
+ && mesh.mSkinSize > 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool LLMeshRepoThread::hasHeader(const LLUUID& mesh_id)
+{
+ LLMutexLock lock(mHeaderMutex);
+ mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+ return iter != mMeshHeader.end();
+}
void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
@@ -4420,7 +4480,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by
{
LL_WARNS() << mesh_id << "bytes mismatch " << *bytes << " " << data.getSizeTotal() << LL_ENDL;
}
- if (bytes_visible && (lod >=0) && (lod < 4) && (*bytes_visible != data.getSizeByLOD(lod)))
+ if (bytes_visible && (lod >=0) && (lod < LLVolumeLODGroup::NUM_LODS) && (*bytes_visible != data.getSizeByLOD(lod)))
{
LL_WARNS() << mesh_id << "bytes_visible mismatch " << *bytes_visible << " " << data.getSizeByLOD(lod) << LL_ENDL;
}
@@ -4580,7 +4640,7 @@ bool LLMeshCostData::init(const LLMeshHeader& header)
static LLCachedControl<U32> minimum_size(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free"
static LLCachedControl<U32> bytes_per_triangle(gSavedSettings, "MeshBytesPerTriangle", 16);
- for (S32 i=0; i<4; i++)
+ for (S32 i=0; i<LLVolumeLODGroup::NUM_LODS; i++)
{
mEstTrisByLOD[i] = llmax((F32)mSizeByLOD[i] - (F32)metadata_discount, (F32)minimum_size) / (F32)bytes_per_triangle;
}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 619e076fa6..89cd2d867f 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -401,6 +401,8 @@ public:
bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
bool hasPhysicsShapeInHeader(const LLUUID& mesh_id);
+ bool hasSkinInfoInHeader(const LLUUID& mesh_id);
+ bool hasHeader(const LLUUID& mesh_id);
void notifyLoadedMeshes();
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
@@ -650,6 +652,8 @@ public:
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
void fetchPhysicsShape(const LLUUID& mesh_id);
bool hasPhysicsShape(const LLUUID& mesh_id);
+ bool hasSkinInfo(const LLUUID& mesh_id);
+ bool hasHeader(const LLUUID& mesh_id);
void buildHull(const LLVolumeParams& params, S32 detail);
void buildPhysicsMesh(LLModel::Decomposition& decomp);
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index c98e0e1bbe..6ceffd452e 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -2751,6 +2751,16 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
base_iter++;
+ bool skinned = include_skin_weights && !mdl->mSkinWeights.empty();
+
+ LLMatrix4a mat_normal;
+ if (skinned)
+ {
+ glh::matrix4f m((F32*)mdl->mSkinInfo.mBindShapeMatrix.getF32ptr());
+ m = m.inverse().transpose();
+ mat_normal.loadu(m.m);
+ }
+
S32 num_faces = mdl->getNumVolumeFaces();
for (S32 i = 0; i < num_faces; ++i)
{
@@ -2765,7 +2775,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
LLVertexBuffer* vb = NULL;
- bool skinned = include_skin_weights && !mdl->mSkinWeights.empty();
+
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
@@ -2803,6 +2813,15 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
LLVector4a::memcpyNonAliased16((F32*)vertex_strider.get(), (F32*)vf.mPositions, num_vertices * 4 * sizeof(F32));
+ if (skinned)
+ {
+ for (U32 i = 0; i < num_vertices; ++i)
+ {
+ LLVector4a* v = (LLVector4a*)vertex_strider.get();
+ mdl->mSkinInfo.mBindShapeMatrix.affineTransform(*v, *v);
+ vertex_strider++;
+ }
+ }
if (vf.mTexCoords)
{
vb->getTexCoord0Strider(tc_strider);
@@ -2813,7 +2832,25 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
if (vf.mNormals)
{
vb->getNormalStrider(normal_strider);
- LLVector4a::memcpyNonAliased16((F32*)normal_strider.get(), (F32*)vf.mNormals, num_vertices * 4 * sizeof(F32));
+
+ if (skinned)
+ {
+ F32* normals = (F32*)normal_strider.get();
+ LLVector4a* src = vf.mNormals;
+ LLVector4a* end = src + num_vertices;
+
+ while (src < end)
+ {
+ LLVector4a normal;
+ mat_normal.rotate(*src++, normal);
+ normal.store4a(normals);
+ normals += 4;
+ }
+ }
+ else
+ {
+ LLVector4a::memcpyNonAliased16((F32*)normal_strider.get(), (F32*)vf.mNormals, num_vertices * 4 * sizeof(F32));
+ }
}
if (skinned)
@@ -3276,7 +3313,7 @@ BOOL LLModelPreview::render()
refresh();
}
- gObjectPreviewProgram.bind();
+ gObjectPreviewProgram.bind(skin_weight);
gGL.loadIdentity();
gPipeline.enableLightsPreview();
@@ -3351,11 +3388,11 @@ BOOL LLModelPreview::render()
}
gGL.pushMatrix();
+
LLMatrix4 mat = instance.mTransform;
gGL.multMatrix((GLfloat*)mat.mMatrix);
-
-
+
U32 num_models = mVertexBuffer[mPreviewLOD][model].size();
for (U32 i = 0; i < num_models; ++i)
{
@@ -3685,65 +3722,41 @@ BOOL LLModelPreview::render()
{
LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
- const LLVolumeFace& face = model->getVolumeFace(i);
-
- LLStrider<LLVector3> position;
- buffer->getVertexStrider(position);
-
- LLStrider<LLVector4> weight;
- buffer->getWeight4Strider(weight);
+ model->mSkinInfo.updateHash();
+ LLRenderPass::uploadMatrixPalette(mPreviewAvatar, &model->mSkinInfo);
- //quick 'n dirty software vertex skinning
-
- //build matrix palette
-
- LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
- LLSkinningUtil::initSkinningMatrixPalette(mat, joint_count,
- skin, getPreviewAvatar());
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix;
- U32 max_joints = LLSkinningUtil::getMaxJointCount();
- for (U32 j = 0; j < buffer->getNumVerts(); ++j)
+ if (textures)
{
- LLMatrix4a final_mat;
- F32 *wptr = weight[j].mV;
- LLSkinningUtil::getPerVertexSkinMatrix(wptr, mat, true, final_mat, max_joints);
-
- //VECTORIZE THIS
- LLVector4a& v = face.mPositions[j];
+ int materialCnt = instance.mModel->mMaterialList.size();
+ if (i < materialCnt)
+ {
+ const std::string& binding = instance.mModel->mMaterialList[i];
+ const LLImportMaterial& material = instance.mMaterial[binding];
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
+ gGL.diffuseColor4fv(material.mDiffuseColor.mV);
- position[j][0] = dst[0];
- position[j][1] = dst[1];
- position[j][2] = dst[2];
+ // Find the tex for this material, bind it, and add it to our set
+ //
+ LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
+ if (tex)
+ {
+ mTextureSet.insert(tex);
+ }
+ }
}
-
- llassert(model->mMaterialList.size() > i);
- const std::string& binding = instance.mModel->mMaterialList[i];
- const LLImportMaterial& material = instance.mMaterial[binding];
-
- buffer->unmapBuffer();
-
- buffer->setBuffer();
- gGL.diffuseColor4fv(material.mDiffuseColor.mV);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // Find the tex for this material, bind it, and add it to our set
- //
- LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
- if (tex)
+ else
{
- mTextureSet.insert(tex);
+ gGL.diffuseColor4fv(PREVIEW_BASE_COL.mV);
}
+ buffer->setBuffer();
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
if (edges)
{
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV);
glLineWidth(PREVIEW_EDGE_WIDTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 2c45014321..14840f1b2e 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -99,6 +99,7 @@ public:
BOOL isMuted(const LLUUID& id, const std::string& name = LLStringUtil::null, U32 flags = 0) const;
// Workaround for username-based mute search, a lot of string conversions so use cautiously
+ // Expects lower case username
BOOL isMuted(const std::string& username, U32 flags = 0) const;
// Alternate (convenience) form for places we don't need to pass the name, but do need flags
diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp
index a14af27e59..0a7a4763be 100644
--- a/indra/newview/llpaneleditsky.cpp
+++ b/indra/newview/llpaneleditsky.cpp
@@ -36,6 +36,7 @@
#include "llsettingssky.h"
#include "llenvironment.h"
#include "llatmosphere.h"
+#include "llviewercontrol.h"
namespace
{
@@ -207,14 +208,16 @@ void LLPanelSettingsSkyAtmosTab::refresh()
F32 moisture_level = mSkySettings->getSkyMoistureLevel();
F32 droplet_radius = mSkySettings->getSkyDropletRadius();
F32 ice_level = mSkySettings->getSkyIceLevel();
- F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance();
+
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance(should_auto_adjust);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setValue(moisture_level);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setValue(droplet_radius);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setValue(ice_level);
getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(rp_ambiance);
- updateGammaLabel();
+ updateGammaLabel(should_auto_adjust);
}
//-------------------------------------------------------------------------
@@ -332,10 +335,10 @@ void LLPanelSettingsSkyAtmosTab::onReflectionProbeAmbianceChanged()
}
-void LLPanelSettingsSkyAtmosTab::updateGammaLabel()
+void LLPanelSettingsSkyAtmosTab::updateGammaLabel(bool auto_adjust)
{
if (!mSkySettings) return;
- F32 ambiance = mSkySettings->getReflectionProbeAmbiance();
+ F32 ambiance = mSkySettings->getReflectionProbeAmbiance(auto_adjust);
if (ambiance != 0.f)
{
childSetValue("scene_gamma_label", getString("hdr_string"));
diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h
index 33af667ab7..523cc134a8 100644
--- a/indra/newview/llpaneleditsky.h
+++ b/indra/newview/llpaneleditsky.h
@@ -80,7 +80,7 @@ private:
void onDropletRadiusChanged();
void onIceLevelChanged();
void onReflectionProbeAmbianceChanged();
- void updateGammaLabel();
+ void updateGammaLabel(bool auto_adjust = false);
};
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 6b737b6895..721b1482d9 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -520,7 +520,11 @@ void LLPanelFace::sendTexture()
{
id = mTextureCtrl->getImageAssetID();
}
- LLSelectMgr::getInstance()->selectionSetImage(id);
+ if (!LLSelectMgr::getInstance()->selectionSetImage(id))
+ {
+ // need to refresh value in texture ctrl
+ refresh();
+ }
}
}
@@ -1000,7 +1004,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{ //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible)
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
- if( objectp
+ if (objectp
&& objectp->getPCode() == LL_PCODE_VOLUME
&& objectp->permModify())
{
@@ -1030,7 +1034,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
mComboMatMedia->setEnabled(editable);
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+
if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE)
{
radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
@@ -1054,7 +1059,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
// *NOTE: The "identical" variable is currently only used to decide if
// the texgen control should be tentative - this is not used by GLTF
// materials. -Cosmic;2022-11-09
- bool identical = true; // true because it is anded below
+ bool identical = true; // true because it is anded below
bool identical_diffuse = false;
bool identical_norm = false;
bool identical_spec = false;
@@ -1071,12 +1076,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
getChildView("color label")->setEnabled(editable);
}
- LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch");
+ LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("colorswatch");
- LLColor4 color = LLColor4::white;
- bool identical_color = false;
+ LLColor4 color = LLColor4::white;
+ bool identical_color = false;
- if(color_swatch)
+ if (color_swatch)
{
LLSelectedTE::getColor(color, identical_color);
LLColor4 prev_color = color_swatch->get();
@@ -1110,7 +1115,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLCtrlSelectionInterface* combobox_shininess = childGetSelectionInterface("combobox shininess");
if (combobox_shininess)
- {
+ {
combobox_shininess->selectNthItem((S32)shiny);
}
@@ -1130,8 +1135,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinycolorswatch")->setTentative(!identical_spec);
LLColorSwatchCtrl* mShinyColorSwatch = getChild<LLColorSwatchCtrl>("shinycolorswatch");
- if(mShinyColorSwatch)
- {
+ if (mShinyColorSwatch)
+ {
mShinyColorSwatch->setValid(editable);
mShinyColorSwatch->setEnabled( editable );
mShinyColorSwatch->setCanApplyImmediately( editable );
@@ -1149,18 +1154,18 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
bumpy = norm_map_id.isNull() ? bumpy : BUMPY_TEXTURE;
if (combobox_bumpiness)
- {
+ {
combobox_bumpiness->selectNthItem((S32)bumpy);
- }
+ }
else
- {
+ {
LL_WARNS() << "failed childGetSelectionInterface for 'combobox bumpiness'" << LL_ENDL;
- }
+ }
getChildView("combobox bumpiness")->setEnabled(editable);
getChild<LLUICtrl>("combobox bumpiness")->setTentative(!identical_bumpy);
getChildView("label bumpiness")->setEnabled(editable);
- }
+ }
// Texture
{
@@ -1174,25 +1179,25 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
bool identical_image_format = false;
LLSelectedTE::getImageFormat(image_format, identical_image_format);
- mIsAlpha = FALSE;
- switch (image_format)
- {
- case GL_RGBA:
- case GL_ALPHA:
- {
- mIsAlpha = TRUE;
- }
- break;
-
- case GL_RGB: break;
- default:
- {
- LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
- }
- break;
+ mIsAlpha = FALSE;
+ switch (image_format)
+ {
+ case GL_RGBA:
+ case GL_ALPHA:
+ {
+ mIsAlpha = TRUE;
}
+ break;
- if(LLViewerMedia::getInstance()->textureHasMedia(id))
+ case GL_RGB: break;
+ default:
+ {
+ LL_WARNS() << "Unexpected tex format in LLPanelFace...resorting to no alpha" << LL_ENDL;
+ }
+ break;
+ }
+
+ if (LLViewerMedia::getInstance()->textureHasMedia(id))
{
getChildView("button align")->setEnabled(editable);
}
@@ -1244,7 +1249,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
else if (id.isNull())
{
- // None selected
+ // None selected
texture_ctrl->setTentative(FALSE);
texture_ctrl->setEnabled(FALSE);
texture_ctrl->setImageAssetID(LLUUID::null);
@@ -1257,7 +1262,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
else
{
- // Tentative: multiple selected with different textures
+ // Tentative: multiple selected with different textures
texture_ctrl->setTentative(TRUE);
texture_ctrl->setEnabled(editable && !has_pbr_material);
texture_ctrl->setImageAssetID(id);
@@ -1268,7 +1273,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
texture_ctrl->setBakeTextureEnabled(TRUE);
}
-
}
if (shinytexture_ctrl)
@@ -1526,15 +1530,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
combobox_texgen->selectNthItem(((S32)selected_texgen) >> 1);
}
else
- {
+ {
LL_WARNS() << "failed childGetSelectionInterface for 'combobox texgen'" << LL_ENDL;
- }
+ }
getChildView("combobox texgen")->setEnabled(editable);
getChild<LLUICtrl>("combobox texgen")->setTentative(!identical);
getChildView("tex gen")->setEnabled(editable);
-
- }
+ }
{
U8 fullbright_flag = 0;
@@ -1564,7 +1567,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLComboBox* mComboTexGen = getChild<LLComboBox>("combobox texgen");
if (mComboTexGen)
- {
+ {
S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
bool enabled = editable && (index != 1);
bool identical_repeats = true;
@@ -1660,14 +1663,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
if (!mIsAlpha)
{ // ... unless there is no alpha channel in the texture, in which case alpha mode MUST ebe none
alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
- }
+ }
combobox_alphamode->selectNthItem(alpha_mode);
- }
- else
- {
+ }
+ else
+ {
LL_WARNS() << "failed childGetSelectionInterface for 'combobox alphamode'" << LL_ENDL;
- }
+ }
getChild<LLUICtrl>("maskcutoff")->setValue(material->getAlphaMaskCutoff());
updateAlphaControls();
@@ -1679,15 +1682,15 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
texture_ctrl->setImageAssetID(material->getSpecularID());
if (!material->getSpecularID().isNull() && (shiny == SHINY_TEXTURE))
- {
+ {
material->getSpecularOffset(offset_x,offset_y);
material->getSpecularRepeat(repeat_x,repeat_y);
if (identical_planar_texgen)
- {
+ {
repeat_x *= 2.0f;
repeat_y *= 2.0f;
- }
+ }
rot = material->getSpecularRotation();
getChild<LLUICtrl>("shinyScaleU")->setValue(repeat_x);
@@ -1700,7 +1703,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("mirror")->setValue(material->getEnvironmentIntensity());
updateShinyControls(!material->getSpecularID().isNull(), true);
- }
+ }
// Assert desired colorswatch color to match material AFTER updateShinyControls
// to avoid getting overwritten with the default on some UI state changes.
@@ -1768,14 +1771,14 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
pbr_ctrl->setEnabled(FALSE);
}
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
- if(texture_ctrl)
+ if (texture_ctrl)
{
texture_ctrl->setImageAssetID( LLUUID::null );
texture_ctrl->setEnabled( FALSE ); // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl.
// texture_ctrl->setValid(FALSE);
}
LLColorSwatchCtrl* mColorSwatch = getChild<LLColorSwatchCtrl>("colorswatch");
- if(mColorSwatch)
+ if (mColorSwatch)
{
mColorSwatch->setEnabled( FALSE );
mColorSwatch->setFallbackImage(LLUI::getUIImage("locked_image.j2c") );
@@ -1890,7 +1893,6 @@ void LLPanelFace::updateCopyTexButton()
&& (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1));
std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options");
mMenuClipboardTexture->setToolTip(tooltip);
-
}
void LLPanelFace::refresh()
@@ -3050,7 +3052,11 @@ void LLPanelFace::onCommitPbr(const LLSD& data)
{
id = pbr_ctrl->getImageAssetID();
}
- LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id);
+ if (!LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id))
+ {
+ // If failed to set material, refresh pbr_ctrl's value
+ refresh();
+ }
}
}
@@ -3074,8 +3080,14 @@ void LLPanelFace::onSelectPbr(const LLSD& data)
{
id = pbr_ctrl->getImageAssetID();
}
- LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id);
- LLSelectedTEMaterial::setMaterialID(this, id);
+ if (LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id))
+ {
+ LLSelectedTEMaterial::setMaterialID(this, id);
+ }
+ else
+ {
+ refresh();
+ }
}
}
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index f6d6d99d9f..0b7486232d 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -138,8 +138,9 @@ protected:
void sendTexGen(); // applies and sends bump map
void sendShiny(U32 shininess); // applies and sends shininess
void sendFullbright(); // applies and sends full bright
+
void sendMirror();
- void sendGlow();
+ void sendGlow();
void alignTestureLayer();
void updateCopyTexButton();
@@ -262,7 +263,6 @@ protected:
private:
-
bool isAlpha() { return mIsAlpha; }
// Convenience funcs to keep the visual flack to a minimum
@@ -271,10 +271,10 @@ private:
LLUUID getCurrentSpecularMap();
U32 getCurrentShininess();
U32 getCurrentBumpiness();
- U8 getCurrentDiffuseAlphaMode();
- U8 getCurrentAlphaMaskCutoff();
- U8 getCurrentEnvIntensity();
- U8 getCurrentGlossiness();
+ U8 getCurrentDiffuseAlphaMode();
+ U8 getCurrentAlphaMaskCutoff();
+ U8 getCurrentEnvIntensity();
+ U8 getCurrentGlossiness();
F32 getCurrentBumpyRot();
F32 getCurrentBumpyScaleU();
F32 getCurrentBumpyScaleV();
@@ -350,7 +350,7 @@ private:
U32 new_alpha_mode = new_material->getDiffuseAlphaMode();
LLUUID new_normal_map_id = new_material->getNormalID();
- LLUUID new_spec_map_id = new_material->getSpecularID();
+ LLUUID new_spec_map_id = new_material->getSpecularID();
if ((new_alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND) && !is_alpha_face)
{
@@ -595,7 +595,6 @@ public:
class LLSelectedTE
{
public:
-
static void getFace(class LLFace*& face_to_return, bool& identical_face);
static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face);
static void getTexId(LLUUID& id, bool& identical);
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 2db8620d2d..3f8ed30d62 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -1427,7 +1427,8 @@ void LLPanelObjectInventory::reset()
LLEditMenuHandler::gEditMenuHandler = mFolders;
}
- LLRect scroller_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
+ int offset = hasBorder() ? getBorder()->getBorderWidth() << 1 : 0;
+ LLRect scroller_rect(0, getRect().getHeight() - offset, getRect().getWidth() - offset, 0);
LLScrollContainer::Params scroll_p;
scroll_p.name("task inventory scroller");
scroll_p.rect(scroller_rect);
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 816633b545..bf3b4837f0 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -159,6 +159,7 @@ void request_avatar_properties_coro(std::string cap_url, LLUUID agent_id)
avatar_data->fl_about_text = result["fl_about_text"].asString();
avatar_data->born_on = result["member_since"].asDate();
avatar_data->profile_url = getProfileURL(agent_id.asString());
+ avatar_data->customer_type = result["customer_type"].asString();
avatar_data->flags = 0;
@@ -1051,6 +1052,8 @@ void LLPanelProfileSecondLife::resetData()
mCantEditObjectsIcon->setEnabled(false);
childSetVisible("partner_layout", FALSE);
+ childSetVisible("badge_layout", FALSE);
+ childSetVisible("partner_spacer_layout", TRUE);
}
void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data)
@@ -1258,6 +1261,59 @@ void LLPanelProfileSecondLife::fillAccountStatus(const LLAvatarData* avatar_data
std::string caption_text = getString("CaptionTextAcctInfo", args);
getChild<LLUICtrl>("account_info")->setValue(caption_text);
+
+ const S32 LINDEN_EMPLOYEE_INDEX = 3;
+ LLDate sl_release;
+ sl_release.fromYMDHMS(2003, 6, 23, 0, 0, 0);
+ std::string customer_lower = avatar_data->customer_type;
+ LLStringUtil::toLower(customer_lower);
+ if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX)
+ {
+ getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Linden");
+ getChild<LLUICtrl>("badge_text")->setValue(getString("BadgeLinden"));
+ childSetVisible("badge_layout", TRUE);
+ childSetVisible("partner_spacer_layout", FALSE);
+ }
+ else if (avatar_data->born_on < sl_release)
+ {
+ getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Beta");
+ getChild<LLUICtrl>("badge_text")->setValue(getString("BadgeBeta"));
+ childSetVisible("badge_layout", TRUE);
+ childSetVisible("partner_spacer_layout", FALSE);
+ }
+ else if (customer_lower == "beta_lifetime")
+ {
+ getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Beta_Lifetime");
+ getChild<LLUICtrl>("badge_text")->setValue(getString("BadgeBetaLifetime"));
+ childSetVisible("badge_layout", TRUE);
+ childSetVisible("partner_spacer_layout", FALSE);
+ }
+ else if (customer_lower == "lifetime")
+ {
+ getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Lifetime");
+ getChild<LLUICtrl>("badge_text")->setValue(getString("BadgeLifetime"));
+ childSetVisible("badge_layout", TRUE);
+ childSetVisible("partner_spacer_layout", FALSE);
+ }
+ else if (customer_lower == "secondlifetime_premium")
+ {
+ getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Premium_Lifetime");
+ getChild<LLUICtrl>("badge_text")->setValue(getString("BadgePremiumLifetime"));
+ childSetVisible("badge_layout", TRUE);
+ childSetVisible("partner_spacer_layout", FALSE);
+ }
+ else if (customer_lower == "secondlifetime_premium_plus")
+ {
+ getChild<LLUICtrl>("badge_icon")->setValue("Profile_Badge_Pplus_Lifetime");
+ getChild<LLUICtrl>("badge_text")->setValue(getString("BadgePremiumPlusLifetime"));
+ childSetVisible("badge_layout", TRUE);
+ childSetVisible("partner_spacer_layout", FALSE);
+ }
+ else
+ {
+ childSetVisible("badge_layout", FALSE);
+ childSetVisible("partner_spacer_layout", TRUE);
+ }
}
void LLPanelProfileSecondLife::fillRightsData()
@@ -1412,7 +1468,7 @@ void LLPanelProfileSecondLife::updateOnlineStatus()
}
else
{
- childSetVisible("frind_layout", false);
+ childSetVisible("friend_layout", false);
childSetVisible("online_layout", false);
childSetVisible("offline_layout", false);
}
@@ -1420,7 +1476,7 @@ void LLPanelProfileSecondLife::updateOnlineStatus()
void LLPanelProfileSecondLife::processOnlineStatus(bool is_friend, bool show_online, bool online)
{
- childSetVisible("frind_layout", is_friend);
+ childSetVisible("friend_layout", is_friend);
childSetVisible("online_layout", online && show_online);
childSetVisible("offline_layout", !online && show_online);
}
diff --git a/indra/newview/llpanelprofilepicks.cpp b/indra/newview/llpanelprofilepicks.cpp
index 45d0252e4f..db3a3c6de5 100644
--- a/indra/newview/llpanelprofilepicks.cpp
+++ b/indra/newview/llpanelprofilepicks.cpp
@@ -529,6 +529,7 @@ void LLPanelProfilePick::setAvatarId(const LLUUID& avatar_id)
pick_name = parcel->getName();
pick_desc = parcel->getDesc();
snapshot_id = parcel->getSnapshotID();
+ mPickDescription->setParseHTML(false);
}
LLViewerRegion* region = gAgent.getRegion();
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 3347c40687..bc9f0cef83 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -566,7 +566,7 @@ void LLPanelWearing::onRemoveAttachment()
{
LLSelectMgr::getInstance()->deselectAll();
LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]);
- LLSelectMgr::getInstance()->sendDropAttachment();
+ LLSelectMgr::getInstance()->sendDetach();
}
}
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
index 72dab0cba8..efaf068bd2 100644
--- a/indra/newview/llreflectionmap.cpp
+++ b/indra/newview/llreflectionmap.cpp
@@ -117,7 +117,7 @@ void LLReflectionMap::autoAdjustOrigin()
{
int face = -1;
LLVector4a intersection;
- LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], true, false, true, &face, &intersection);
+ LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], false, false, true, &face, &intersection);
if (drawable != nullptr)
{
hit = true;
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
index 45489fb35b..6550686a32 100644
--- a/indra/newview/llreflectionmapmanager.cpp
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -260,6 +260,10 @@ void LLReflectionMapManager::update()
if (probe != mDefaultProbe)
{
+ if (probe->mViewerObject) //make sure probes track the viewer objects they are attached to
+ {
+ probe->mOrigin.load3(probe->mViewerObject->getPositionAgent().mV);
+ }
d.setSub(camera_pos, probe->mOrigin);
probe->mDistance = d.getLength3().getF32() - probe->mRadius;
}
@@ -952,8 +956,9 @@ void LLReflectionMapManager::updateUniforms()
static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust);
- F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f;
- F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f;
+ bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass();
+ F32 ambscale = is_ambiance_pass ? 0.f : 1.f;
+ F32 radscale = is_ambiance_pass ? 0.5f : 1.f;
for (auto* refmap : mReflectionMaps)
{
diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp
index 140cbbedbe..3278bd3aa9 100644
--- a/indra/newview/llscripteditor.cpp
+++ b/indra/newview/llscripteditor.cpp
@@ -187,7 +187,7 @@ void LLScriptEditor::drawSelectionBackground()
// Draw selection even if we don't have keyboard focus for search/replace
if( hasSelection() && !mLineInfoList.empty())
{
- std::vector<LLRect> selection_rects = getSelctionRects();
+ std::vector<LLRect> selection_rects = getSelectionRects();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor;
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 19ce8f6a55..8cf44b4ede 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1821,7 +1821,7 @@ void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item)
// selectionSetImage()
//-----------------------------------------------------------------------------
// *TODO: re-arch texture applying out of lltooldraganddrop
-void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
+bool LLSelectMgr::selectionSetImage(const LLUUID& imageid)
{
// First for (no copy) textures and multiple object selection
LLViewerInventoryItem* item = gInventory.getItem(imageid);
@@ -1829,9 +1829,11 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
&& !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
&& (mSelectedObjects->getNumNodes() > 1) )
{
- LL_WARNS() << "Attempted to apply no-copy texture to multiple objects"
- << LL_ENDL;
- return;
+ LL_DEBUGS() << "Attempted to apply no-copy texture " << imageid
+ << " to multiple objects" << LL_ENDL;
+
+ LLNotificationsUtil::add("FailedToApplyTextureNoCopyToMultiple");
+ return false;
}
struct f : public LLSelectedTEFunctor
@@ -1896,12 +1898,14 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
}
} sendfunc(item);
getSelection()->applyToObjects(&sendfunc);
+
+ return true;
}
//-----------------------------------------------------------------------------
// selectionSetGLTFMaterial()
//-----------------------------------------------------------------------------
-void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
+bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
{
// First for (no copy) textures and multiple object selection
LLViewerInventoryItem* item = gInventory.getItem(mat_id);
@@ -1909,9 +1913,11 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
&& !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
&& (mSelectedObjects->getNumNodes() > 1))
{
- LL_WARNS() << "Attempted to apply no-copy material to multiple objects"
- << LL_ENDL;
- return;
+ LL_DEBUGS() << "Attempted to apply no-copy material " << mat_id
+ << "to multiple objects" << LL_ENDL;
+
+ LLNotificationsUtil::add("FailedToApplyGLTFNoCopyToMultiple");
+ return false;
}
struct f : public LLSelectedTEFunctor
@@ -1983,6 +1989,8 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
getSelection()->applyToObjects(&sendfunc);
LLGLTFMaterialList::flushUpdates();
+
+ return true;
}
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 93d750215b..8ce59c6654 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -634,8 +634,8 @@ public:
void selectionSetDensity(F32 density);
void selectionSetRestitution(F32 restitution);
void selectionSetMaterial(U8 material);
- void selectionSetImage(const LLUUID& imageid); // could be item or asset id
- void selectionSetGLTFMaterial(const LLUUID& mat_id); // could be item or asset id
+ bool selectionSetImage(const LLUUID& imageid); // could be item or asset id
+ bool selectionSetGLTFMaterial(const LLUUID& mat_id); // could be item or asset id
void selectionSetColor(const LLColor4 &color);
void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels
void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index 258cc1c7b2..264359a3a9 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -719,6 +719,8 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
F32 g = getGamma();
static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ static LLCachedControl<F32> auto_adjust_ambient_scale(gSavedSettings, "RenderSkyAutoAdjustAmbientScale", 0.75f);
+ static LLCachedControl<F32> auto_adjust_hdr_scale(gSavedSettings, "RenderSkyAutoAdjustHDRScale", 2.f);
static LLCachedControl<F32> cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f);
F32 probe_ambiance = getTotalReflectionProbeAmbiance(cloud_shadow_scale);
@@ -736,9 +738,9 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
}
else if (psky->canAutoAdjust() && should_auto_adjust)
{ // auto-adjust legacy sky to take advantage of probe ambiance
- shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * 0.5f).mV);
- shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, 2.f);
- probe_ambiance = 1.f;
+ shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * auto_adjust_ambient_scale).mV);
+ shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, auto_adjust_hdr_scale);
+ probe_ambiance = 1.f; // NOTE -- must match LLSettingsSky::getReflectionProbeAmbiance value for "auto_adjust" true
}
else
{
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 978cb78083..f52f1a925d 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -777,7 +777,8 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c
assert_states_valid(this);
}
-void LLSpatialGroup::destroyGL(bool keep_occlusion)
+
+void LLSpatialGroup::destroyGLState(bool keep_occlusion)
{
setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
@@ -1290,45 +1291,11 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size)
drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size));
}
-class LLOctreeDirty : public OctreeTraveler
-{
-public:
- virtual void visit(const OctreeNode* state)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
- group->destroyGL();
-
- for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
- {
- LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable)
- {
- continue;
- }
- if (drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup)
- {
- gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL);
- }
- }
-
- for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
- {
- LLSpatialBridge* bridge = *i;
- traverse(bridge->mOctree);
- }
- }
-};
void LLSpatialPartition::restoreGL()
{
}
-void LLSpatialPartition::resetVertexBuffers()
-{
- LLOctreeDirty dirty;
- dirty.traverse(mOctree);
-}
-
BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL;
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 053ce9e60b..88584f535a 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -295,7 +295,9 @@ public:
BOOL removeObject(LLDrawable *drawablep, BOOL from_octree = FALSE);
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
void shift(const LLVector4a &offset);
- void destroyGL(bool keep_occlusion = false);
+
+ // TODO: this no longer appears to be called, figure out if it's important and if not remove it
+ void destroyGLState(bool keep_occlusion = false);
void updateDistance(LLCamera& camera);
F32 getUpdateUrgency() const;
@@ -419,7 +421,6 @@ public:
void renderDebug();
void renderIntersectingBBoxes(LLCamera* camera);
void restoreGL();
- void resetVertexBuffers();
BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 39d640e85f..73234552e5 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -1396,8 +1396,16 @@ bool idle_startup()
}
else if (regionp->capabilitiesError())
{
- // Try to connect despite capabilities' error state
- LLStartUp::setStartupState(STATE_SEED_CAP_GRANTED);
+ LL_WARNS("AppInit") << "Failed to get capabilities. Backing up to login screen!" << LL_ENDL;
+ if (gRememberPassword)
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
+ }
+ else
+ {
+ LLNotificationsUtil::add("LoginPacketNeverReceivedNoTP", LLSD(), LLSD(), login_alert_status);
+ }
+ reset_login();
}
else
{
@@ -1901,6 +1909,7 @@ bool idle_startup()
LLNotificationsUtil::add("InventoryUnusable");
}
+ LLInventoryModelBackgroundFetch::instance().start();
gInventory.createCommonSystemCategories();
// It's debatable whether this flag is a good idea - sets all
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 6633951db3..1918d11964 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -40,6 +40,7 @@
#include "llfloatertools.h"
#include "llgesturemgr.h"
#include "llgiveinventory.h"
+#include "llgltfmateriallist.h"
#include "llhudmanager.h"
#include "llhudeffecttrail.h"
#include "llimview.h"
@@ -1095,6 +1096,9 @@ void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj,
LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL;
return;
}
+
+ // SL-20013 must save asset_id before handleDropMaterialProtections since our item instance
+ // may be deleted if it is moved into task inventory
LLUUID asset_id = item->getAssetUUID();
BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if (!success)
@@ -1102,6 +1106,12 @@ void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj,
return;
}
+ if (asset_id.isNull())
+ {
+ // use blank material
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+
hit_obj->setRenderMaterialID(hit_face, asset_id);
dialog_refresh_all();
@@ -1121,13 +1131,23 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL;
return;
}
+
+ // SL-20013 must save asset_id before handleDropMaterialProtections since our item instance
+ // may be deleted if it is moved into task inventory
LLUUID asset_id = item->getAssetUUID();
BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
+
if (!success)
{
return;
}
+ if (asset_id.isNull())
+ {
+ // use blank material
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+
hit_obj->setRenderMaterialIDs(asset_id);
dialog_refresh_all();
// send the update to the simulator
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index 34d3ed8bb1..c37c955e8d 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -41,8 +41,8 @@
#include "llurlregistry.h"
-static const std::string BING_NOTRANSLATE_OPENING_TAG("<div class=\"notranslate\">");
-static const std::string BING_NOTRANSLATE_CLOSING_TAG("</div>");
+static const std::string AZURE_NOTRANSLATE_OPENING_TAG("<div translate=\"no\">");
+static const std::string AZURE_NOTRANSLATE_CLOSING_TAG("</div>");
/**
* Handler of an HTTP machine translation service.
@@ -80,7 +80,18 @@ public:
* @param[in] key Key to verify.
*/
virtual std::string getKeyVerificationURL(
- const std::string &key) const = 0;
+ const LLSD &key) const = 0;
+
+ /**
+ * Check API verification response.
+ *
+ * @param[out] bool true if valid.
+ * @param[in] response
+ * @param[in] status
+ */
+ virtual bool checkVerificationResponse(
+ const LLSD &response,
+ int status) const = 0;
/**
* Parse translation response.
@@ -92,6 +103,7 @@ public:
* @param[out] err_msg Error message (in case of error).
*/
virtual bool parseResponse(
+ const LLSD& http_response,
int& status,
const std::string& body,
std::string& translation,
@@ -105,14 +117,30 @@ public:
virtual LLTranslate::EService getCurrentService() = 0;
- virtual void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc) = 0;
+ virtual void verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc) = 0;
virtual void translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure);
virtual ~LLTranslationAPIHandler() {}
- void verifyKeyCoro(LLTranslate::EService service, std::string key, LLTranslate::KeyVerificationResult_fn fnc);
+ void verifyKeyCoro(LLTranslate::EService service, LLSD key, LLTranslate::KeyVerificationResult_fn fnc);
void translateMessageCoro(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure);
+
+ virtual void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const = 0;
+ virtual void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent, const LLSD &key) const = 0;
+ virtual LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url,
+ const std::string & msg,
+ const std::string& from_lang,
+ const std::string& to_lang) const = 0;
+ virtual LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url) const = 0;
};
void LLTranslationAPIHandler::translateMessage(LanguagePair_t fromTo, std::string msg, LLTranslate::TranslationSuccess_fn success, LLTranslate::TranslationFailure_fn failure)
@@ -122,8 +150,7 @@ void LLTranslationAPIHandler::translateMessage(LanguagePair_t fromTo, std::strin
}
-
-void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::string key, LLTranslate::KeyVerificationResult_fn fnc)
+void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, LLSD key, LLTranslate::KeyVerificationResult_fn fnc)
{
LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
@@ -140,8 +167,7 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::
LLVersionInfo::instance().getPatch(),
LLVersionInfo::instance().getBuild());
- httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
- httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+ initHttpHeader(httpHeaders, user_agent, key);
httpOpts->setFollowRedirects(true);
httpOpts->setSSLVerifyPeer(false);
@@ -153,17 +179,29 @@ void LLTranslationAPIHandler::verifyKeyCoro(LLTranslate::EService service, std::
return;
}
- LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts, httpHeaders);
+ std::string::size_type delim_pos = url.find("://");
+ if (delim_pos == std::string::npos)
+ {
+ LL_INFOS("Translate") << "URL is missing a scheme" << LL_ENDL;
+ return;
+ }
+
+ LLSD result = verifyAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url);
LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
bool bOk = true;
- if (!status)
+ int parseResult = status.getType();
+ if (!checkVerificationResponse(httpResults, parseResult))
+ {
bOk = false;
+ }
if (!fnc.empty())
- fnc(service, bOk);
+ {
+ fnc(service, bOk, parseResult);
+ }
}
void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::string msg,
@@ -184,8 +222,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
LLVersionInfo::instance().getPatch(),
LLVersionInfo::instance().getBuild());
- httpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
- httpHeaders->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+ initHttpHeader(httpHeaders, user_agent);
httpOpts->setSSLVerifyPeer(false);
std::string url = this->getTranslateURL(fromTo.first, fromTo.second, msg);
@@ -195,7 +232,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
return;
}
- LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts, httpHeaders);
+ LLSD result = sendMessageAndSuspend(httpAdapter, httpRequest, httpOpts, httpHeaders, url, msg, fromTo.first, fromTo.second);
if (LLApp::isQuitting())
{
@@ -216,7 +253,7 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
try
{
- res = this->parseResponse(parseResult, body, translation, detected_lang, err_msg);
+ res = this->parseResponse(httpResults, parseResult, body, translation, detected_lang, err_msg);
}
catch (std::out_of_range&)
{
@@ -242,6 +279,11 @@ void LLTranslationAPIHandler::translateMessageCoro(LanguagePair_t fromTo, std::s
}
else
{
+ if (err_msg.empty() && httpResults.has("error_body"))
+ {
+ err_msg = httpResults["error_body"].asString();
+ }
+
if (err_msg.empty())
{
err_msg = LLTrans::getString("TranslationResponseParseError");
@@ -262,23 +304,44 @@ class LLGoogleTranslationHandler : public LLTranslationAPIHandler
LOG_CLASS(LLGoogleTranslationHandler);
public:
- /*virtual*/ std::string getTranslateURL(
+ std::string getTranslateURL(
const std::string &from_lang,
const std::string &to_lang,
- const std::string &text) const;
- /*virtual*/ std::string getKeyVerificationURL(
- const std::string &key) const;
- /*virtual*/ bool parseResponse(
+ const std::string &text) const override;
+ std::string getKeyVerificationURL(
+ const LLSD &key) const override;
+ bool checkVerificationResponse(
+ const LLSD &response,
+ int status) const override;
+ bool parseResponse(
+ const LLSD& http_response,
int& status,
const std::string& body,
std::string& translation,
std::string& detected_lang,
- std::string& err_msg) const;
- /*virtual*/ bool isConfigured() const;
-
- /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_GOOGLE; }
-
- /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc);
+ std::string& err_msg) const override;
+ bool isConfigured() const override;
+
+ LLTranslate::EService getCurrentService() override { return LLTranslate::EService::SERVICE_GOOGLE; }
+
+ void verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc) override;
+
+ void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const override;
+ void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent, const LLSD &key) const override;
+ LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url,
+ const std::string & msg,
+ const std::string& from_lang,
+ const std::string& to_lang) const override;
+
+ LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url) const override;
private:
static void parseErrorResponse(
@@ -311,15 +374,24 @@ std::string LLGoogleTranslationHandler::getTranslateURL(
// virtual
std::string LLGoogleTranslationHandler::getKeyVerificationURL(
- const std::string& key) const
+ const LLSD& key) const
{
- std::string url = std::string("https://www.googleapis.com/language/translate/v2/languages?key=")
- + key + "&target=en";
+ std::string url = std::string("https://www.googleapis.com/language/translate/v2/languages?key=")
+ + key.asString() +"&target=en";
return url;
}
+//virtual
+bool LLGoogleTranslationHandler::checkVerificationResponse(
+ const LLSD &response,
+ int status) const
+{
+ return status == HTTP_OK;
+}
+
// virtual
bool LLGoogleTranslationHandler::parseResponse(
+ const LLSD& http_response,
int& status,
const std::string& body,
std::string& translation,
@@ -407,75 +479,196 @@ bool LLGoogleTranslationHandler::parseTranslation(
// static
std::string LLGoogleTranslationHandler::getAPIKey()
{
- return gSavedSettings.getString("GoogleTranslateAPIKey");
+ static LLCachedControl<std::string> google_key(gSavedSettings, "GoogleTranslateAPIKey");
+ return google_key;
}
/*virtual*/
-void LLGoogleTranslationHandler::verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc)
+void LLGoogleTranslationHandler::verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc)
{
LLCoros::instance().launch("Google /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro,
this, LLTranslate::SERVICE_GOOGLE, key, fnc));
}
+/*virtual*/
+void LLGoogleTranslationHandler::initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const
+{
+ headers->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
+ headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+}
+
+/*virtual*/
+void LLGoogleTranslationHandler::initHttpHeader(
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& user_agent,
+ const LLSD &key) const
+{
+ headers->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_TEXT_PLAIN);
+ headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+}
+
+LLSD LLGoogleTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url,
+ const std::string & msg,
+ const std::string& from_lang,
+ const std::string& to_lang) const
+{
+ return adapter->getRawAndSuspend(request, url, options, headers);
+}
+
+LLSD LLGoogleTranslationHandler::verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url) const
+{
+ return adapter->getAndSuspend(request, url, options, headers);
+}
//=========================================================================
/// Microsoft Translator v2 API handler.
-class LLBingTranslationHandler : public LLTranslationAPIHandler
+class LLAzureTranslationHandler : public LLTranslationAPIHandler
{
- LOG_CLASS(LLBingTranslationHandler);
+ LOG_CLASS(LLAzureTranslationHandler);
public:
- /*virtual*/ std::string getTranslateURL(
+ std::string getTranslateURL(
const std::string &from_lang,
const std::string &to_lang,
- const std::string &text) const;
- /*virtual*/ std::string getKeyVerificationURL(
- const std::string &key) const;
- /*virtual*/ bool parseResponse(
+ const std::string &text) const override;
+ std::string getKeyVerificationURL(
+ const LLSD &key) const override;
+ bool checkVerificationResponse(
+ const LLSD &response,
+ int status) const override;
+ bool parseResponse(
+ const LLSD& http_response,
int& status,
const std::string& body,
std::string& translation,
std::string& detected_lang,
- std::string& err_msg) const;
- /*virtual*/ bool isConfigured() const;
-
- /*virtual*/ LLTranslate::EService getCurrentService() { return LLTranslate::EService::SERVICE_BING; }
-
- /*virtual*/ void verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc);
+ std::string& err_msg) const override;
+ bool isConfigured() const override;
+
+ LLTranslate::EService getCurrentService() override { return LLTranslate::EService::SERVICE_AZURE; }
+
+ void verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc) override;
+
+ void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const override;
+ void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent, const LLSD &key) const override;
+ LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url,
+ const std::string & msg,
+ const std::string& from_lang,
+ const std::string& to_lang) const override;
+
+ LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url) const override;
private:
- static std::string getAPIKey();
+ static std::string parseErrorResponse(
+ const std::string& body);
+ static LLSD getAPIKey();
static std::string getAPILanguageCode(const std::string& lang);
};
//-------------------------------------------------------------------------
// virtual
-std::string LLBingTranslationHandler::getTranslateURL(
+std::string LLAzureTranslationHandler::getTranslateURL(
const std::string &from_lang,
const std::string &to_lang,
const std::string &text) const
{
- std::string url = std::string("http://api.microsofttranslator.com/v2/Http.svc/Translate?appId=")
- + getAPIKey() + "&text=" + LLURI::escape(text) + "&to=" + getAPILanguageCode(to_lang);
- if (!from_lang.empty())
- {
- url += "&from=" + getAPILanguageCode(from_lang);
- }
+ std::string url;
+ LLSD key = getAPIKey();
+ if (key.isMap())
+ {
+ std::string endpoint = key["endpoint"].asString();
+
+ if (*endpoint.rbegin() != '/')
+ {
+ endpoint += "/";
+ }
+ url = endpoint + std::string("translate?api-version=3.0&to=")
+ + getAPILanguageCode(to_lang);
+ }
return url;
}
// virtual
-std::string LLBingTranslationHandler::getKeyVerificationURL(
- const std::string& key) const
+std::string LLAzureTranslationHandler::getKeyVerificationURL(
+ const LLSD& key) const
{
- std::string url = std::string("http://api.microsofttranslator.com/v2/Http.svc/GetLanguagesForTranslate?appId=")
- + key;
+ std::string url;
+ if (key.isMap())
+ {
+ std::string endpoint = key["endpoint"].asString();
+ if (*endpoint.rbegin() != '/')
+ {
+ endpoint += "/";
+ }
+ url = endpoint + std::string("translate?api-version=3.0&to=en");
+ }
return url;
}
+//virtual
+bool LLAzureTranslationHandler::checkVerificationResponse(
+ const LLSD &response,
+ int status) const
+{
+ if (status == HTTP_UNAUTHORIZED)
+ {
+ LL_DEBUGS("Translate") << "Key unathorised" << LL_ENDL;
+ return false;
+ }
+
+ if (status == HTTP_NOT_FOUND)
+ {
+ LL_DEBUGS("Translate") << "Either endpoint doesn't have requested resource" << LL_ENDL;
+ return false;
+ }
+
+ if (status != HTTP_BAD_REQUEST)
+ {
+ LL_DEBUGS("Translate") << "Unexpected error code" << LL_ENDL;
+ return false;
+ }
+
+ if (!response.has("error_body"))
+ {
+ LL_DEBUGS("Translate") << "Unexpected response, no error returned" << LL_ENDL;
+ return false;
+ }
+
+ // Expected: "{\"error\":{\"code\":400000,\"message\":\"One of the request inputs is not valid.\"}}"
+ // But for now just verify response is a valid json
+
+ Json::Value root;
+ Json::Reader reader;
+
+ if (!reader.parse(response["error_body"].asString(), root))
+ {
+ LL_DEBUGS("Translate") << "Failed to parse error_body:" << reader.getFormatedErrorMessages() << LL_ENDL;
+ return false;
+ }
+
+ return true;
+}
+
// virtual
-bool LLBingTranslationHandler::parseResponse(
+bool LLAzureTranslationHandler::parseResponse(
+ const LLSD& http_response,
int& status,
const std::string& body,
std::string& translation,
@@ -484,65 +677,443 @@ bool LLBingTranslationHandler::parseResponse(
{
if (status != HTTP_OK)
{
- static const std::string MSG_BEGIN_MARKER = "Message: ";
- size_t begin = body.find(MSG_BEGIN_MARKER);
- if (begin != std::string::npos)
- {
- begin += MSG_BEGIN_MARKER.size();
- }
- else
- {
- begin = 0;
- err_msg.clear();
- }
- size_t end = body.find("</p>", begin);
- err_msg = body.substr(begin, end-begin);
- LLStringUtil::replaceString(err_msg, "&#xD;", ""); // strip CR
+ if (http_response.has("error_body"))
+ err_msg = parseErrorResponse(http_response["error_body"].asString());
return false;
}
- // Sample response: <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Hola</string>
- size_t begin = body.find(">");
- if (begin == std::string::npos || begin >= (body.size() - 1))
- {
- begin = 0;
- }
- else
- {
- ++begin;
- }
+ //Example:
+ // "[{\"detectedLanguage\":{\"language\":\"en\",\"score\":1.0},\"translations\":[{\"text\":\"Hello, what is your name?\",\"to\":\"en\"}]}]"
- size_t end = body.find("</string>", begin);
+ Json::Value root;
+ Json::Reader reader;
- detected_lang = ""; // unsupported by this API
- translation = body.substr(begin, end-begin);
- LLStringUtil::replaceString(translation, "&#xD;", ""); // strip CR
- return true;
+ if (!reader.parse(body, root))
+ {
+ err_msg = reader.getFormatedErrorMessages();
+ return false;
+ }
+
+ if (!root.isArray()) // empty response? should not happen
+ {
+ return false;
+ }
+
+ // Request succeeded, extract translation from the response.
+
+ const Json::Value& data = root[0U];
+ if (!data.isObject()
+ || !data.isMember("detectedLanguage")
+ || !data.isMember("translations"))
+ {
+ return false;
+ }
+
+ const Json::Value& detectedLanguage = data["detectedLanguage"];
+ if (!detectedLanguage.isObject() || !detectedLanguage.isMember("language"))
+ {
+ return false;
+ }
+ detected_lang = detectedLanguage["language"].asString();
+
+ const Json::Value& translations = data["translations"];
+ if (!translations.isArray() || translations.size() == 0)
+ {
+ return false;
+ }
+
+ const Json::Value& first = translations[0U];
+ if (!first.isObject() || !first.isMember("text"))
+ {
+ return false;
+ }
+
+ translation = first["text"].asString();
+
+ return true;
}
// virtual
-bool LLBingTranslationHandler::isConfigured() const
+bool LLAzureTranslationHandler::isConfigured() const
{
- return !getAPIKey().empty();
+ return getAPIKey().isMap();
+}
+
+//static
+std::string LLAzureTranslationHandler::parseErrorResponse(
+ const std::string& body)
+{
+ // Expected: "{\"error\":{\"code\":400000,\"message\":\"One of the request inputs is not valid.\"}}"
+ // But for now just verify response is a valid json with an error
+
+ Json::Value root;
+ Json::Reader reader;
+
+ if (!reader.parse(body, root))
+ {
+ return std::string();
+ }
+
+ if (!root.isObject() || !root.isMember("error"))
+ {
+ return std::string();
+ }
+
+ const Json::Value& error_map = root["error"];
+
+ if (!error_map.isObject() || !error_map.isMember("message"))
+ {
+ return std::string();
+ }
+
+ return error_map["message"].asString();
}
// static
-std::string LLBingTranslationHandler::getAPIKey()
+LLSD LLAzureTranslationHandler::getAPIKey()
{
- return gSavedSettings.getString("BingTranslateAPIKey");
+ static LLCachedControl<LLSD> azure_key(gSavedSettings, "AzureTranslateAPIKey");
+ return azure_key;
}
// static
-std::string LLBingTranslationHandler::getAPILanguageCode(const std::string& lang)
+std::string LLAzureTranslationHandler::getAPILanguageCode(const std::string& lang)
{
return lang == "zh" ? "zh-CHT" : lang; // treat Chinese as Traditional Chinese
}
/*virtual*/
-void LLBingTranslationHandler::verifyKey(const std::string &key, LLTranslate::KeyVerificationResult_fn fnc)
+void LLAzureTranslationHandler::verifyKey(const LLSD &key, LLTranslate::KeyVerificationResult_fn fnc)
+{
+ LLCoros::instance().launch("Azure /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro,
+ this, LLTranslate::SERVICE_AZURE, key, fnc));
+}
+/*virtual*/
+void LLAzureTranslationHandler::initHttpHeader(
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& user_agent) const
+{
+ initHttpHeader(headers, user_agent, getAPIKey());
+}
+
+/*virtual*/
+void LLAzureTranslationHandler::initHttpHeader(
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& user_agent,
+ const LLSD &key) const
+{
+ headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_JSON);
+ headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+
+ if (key.has("id"))
+ {
+ // Token based autorization
+ headers->append("Ocp-Apim-Subscription-Key", key["id"].asString());
+ }
+ if (key.has("region"))
+ {
+ // ex: "westeurope"
+ headers->append("Ocp-Apim-Subscription-Region", key["region"].asString());
+ }
+}
+
+LLSD LLAzureTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url,
+ const std::string & msg,
+ const std::string& from_lang,
+ const std::string& to_lang) const
+{
+ LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray);
+ LLCore::BufferArrayStream outs(rawbody.get());
+ outs << "[{\"text\":\"";
+ outs << msg;
+ outs << "\"}]";
+
+ return adapter->postRawAndSuspend(request, url, rawbody, options, headers);
+}
+
+LLSD LLAzureTranslationHandler::verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string & url) const
+{
+ LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray);
+ LLCore::BufferArrayStream outs(rawbody.get());
+ outs << "[{\"intentionally_invalid_400\"}]";
+
+ return adapter->postRawAndSuspend(request, url, rawbody, options, headers);
+}
+
+//=========================================================================
+/// DeepL Translator API handler.
+class LLDeepLTranslationHandler: public LLTranslationAPIHandler
+{
+ LOG_CLASS(LLDeepLTranslationHandler);
+
+public:
+ std::string getTranslateURL(
+ const std::string& from_lang,
+ const std::string& to_lang,
+ const std::string& text) const override;
+ std::string getKeyVerificationURL(
+ const LLSD& key) const override;
+ bool checkVerificationResponse(
+ const LLSD& response,
+ int status) const override;
+ bool parseResponse(
+ const LLSD& http_response,
+ int& status,
+ const std::string& body,
+ std::string& translation,
+ std::string& detected_lang,
+ std::string& err_msg) const override;
+ bool isConfigured() const override;
+
+ LLTranslate::EService getCurrentService() override
+ {
+ return LLTranslate::EService::SERVICE_DEEPL;
+ }
+
+ void verifyKey(const LLSD& key, LLTranslate::KeyVerificationResult_fn fnc) override;
+
+ void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent) const override;
+ void initHttpHeader(LLCore::HttpHeaders::ptr_t headers, const std::string& user_agent, const LLSD& key) const override;
+ LLSD sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& url,
+ const std::string& msg,
+ const std::string& from_lang,
+ const std::string& to_lang) const override;
+
+ LLSD verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& url) const override;
+private:
+ static std::string parseErrorResponse(
+ const std::string& body);
+ static LLSD getAPIKey();
+ static std::string getAPILanguageCode(const std::string& lang);
+};
+
+//-------------------------------------------------------------------------
+// virtual
+std::string LLDeepLTranslationHandler::getTranslateURL(
+ const std::string& from_lang,
+ const std::string& to_lang,
+ const std::string& text) const
+{
+ std::string url;
+ LLSD key = getAPIKey();
+ if (key.isMap())
+ {
+ url = key["domain"].asString();
+
+ if (*url.rbegin() != '/')
+ {
+ url += "/";
+ }
+ url += std::string("v2/translate");
+ }
+ return url;
+}
+
+
+// virtual
+std::string LLDeepLTranslationHandler::getKeyVerificationURL(
+ const LLSD& key) const
+{
+ std::string url;
+ if (key.isMap())
+ {
+ url = key["domain"].asString();
+
+ if (*url.rbegin() != '/')
+ {
+ url += "/";
+ }
+ url += std::string("v2/translate");
+ }
+ return url;
+}
+
+//virtual
+bool LLDeepLTranslationHandler::checkVerificationResponse(
+ const LLSD& response,
+ int status) const
+{
+ // Might need to parse body to make sure we got
+ // a valid response and not a message
+ return status == HTTP_OK;
+}
+
+// virtual
+bool LLDeepLTranslationHandler::parseResponse(
+ const LLSD& http_response,
+ int& status,
+ const std::string& body,
+ std::string& translation,
+ std::string& detected_lang,
+ std::string& err_msg) const
+{
+ if (status != HTTP_OK)
+ {
+ if (http_response.has("error_body"))
+ err_msg = parseErrorResponse(http_response["error_body"].asString());
+ return false;
+ }
+
+ //Example:
+ // "{\"translations\":[{\"detected_source_language\":\"EN\",\"text\":\"test\"}]}"
+
+ Json::Value root;
+ Json::Reader reader;
+
+ if (!reader.parse(body, root))
+ {
+ err_msg = reader.getFormatedErrorMessages();
+ return false;
+ }
+
+ if (!root.isObject()
+ || !root.isMember("translations")) // empty response? should not happen
+ {
+ return false;
+ }
+
+ // Request succeeded, extract translation from the response.
+ const Json::Value& translations = root["translations"];
+ if (!translations.isArray() || translations.size() == 0)
+ {
+ return false;
+ }
+
+ const Json::Value& data= translations[0U];
+ if (!data.isObject()
+ || !data.isMember("detected_source_language")
+ || !data.isMember("text"))
+ {
+ return false;
+ }
+
+ detected_lang = data["detected_source_language"].asString();
+ LLStringUtil::toLower(detected_lang);
+ translation = data["text"].asString();
+
+ return true;
+}
+
+// virtual
+bool LLDeepLTranslationHandler::isConfigured() const
+{
+ return getAPIKey().isMap();
+}
+
+//static
+std::string LLDeepLTranslationHandler::parseErrorResponse(
+ const std::string& body)
+{
+ // Example: "{\"message\":\"One of the request inputs is not valid.\"}"
+
+ Json::Value root;
+ Json::Reader reader;
+
+ if (!reader.parse(body, root))
+ {
+ return std::string();
+ }
+
+ if (!root.isObject() || !root.isMember("message"))
+ {
+ return std::string();
+ }
+
+ return root["message"].asString();
+}
+
+// static
+LLSD LLDeepLTranslationHandler::getAPIKey()
+{
+ static LLCachedControl<LLSD> deepl_key(gSavedSettings, "DeepLTranslateAPIKey");
+ return deepl_key;
+}
+
+// static
+std::string LLDeepLTranslationHandler::getAPILanguageCode(const std::string& lang)
+{
+ return lang == "zh" ? "zh-CHT" : lang; // treat Chinese as Traditional Chinese
+}
+
+/*virtual*/
+void LLDeepLTranslationHandler::verifyKey(const LLSD& key, LLTranslate::KeyVerificationResult_fn fnc)
+{
+ LLCoros::instance().launch("DeepL /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro,
+ this, LLTranslate::SERVICE_DEEPL, key, fnc));
+}
+/*virtual*/
+void LLDeepLTranslationHandler::initHttpHeader(
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& user_agent) const
{
- LLCoros::instance().launch("Bing /Verify Key", boost::bind(&LLTranslationAPIHandler::verifyKeyCoro,
- this, LLTranslate::SERVICE_BING, key, fnc));
+ initHttpHeader(headers, user_agent, getAPIKey());
+}
+
+/*virtual*/
+void LLDeepLTranslationHandler::initHttpHeader(
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& user_agent,
+ const LLSD& key) const
+{
+ headers->append(HTTP_OUT_HEADER_CONTENT_TYPE, "application/x-www-form-urlencoded");
+ headers->append(HTTP_OUT_HEADER_USER_AGENT, user_agent);
+
+ if (key.has("id"))
+ {
+ std::string authkey = "DeepL-Auth-Key " + key["id"].asString();
+ headers->append(HTTP_OUT_HEADER_AUTHORIZATION, authkey);
+ }
+}
+
+LLSD LLDeepLTranslationHandler::sendMessageAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& url,
+ const std::string& msg,
+ const std::string& from_lang,
+ const std::string& to_lang) const
+{
+ LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray);
+ LLCore::BufferArrayStream outs(rawbody.get());
+ outs << "text=";
+ std::string escaped_string = LLURI::escape(msg);
+ outs << escaped_string;
+ outs << "&target_lang=";
+ std::string lang = to_lang;
+ LLStringUtil::toUpper(lang);
+ outs << lang;
+
+ return adapter->postRawAndSuspend(request, url, rawbody, options, headers);
+}
+
+LLSD LLDeepLTranslationHandler::verifyAndSuspend(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t adapter,
+ LLCore::HttpRequest::ptr_t request,
+ LLCore::HttpOptions::ptr_t options,
+ LLCore::HttpHeaders::ptr_t headers,
+ const std::string& url) const
+{
+ LLCore::BufferArray::ptr_t rawbody(new LLCore::BufferArray);
+ LLCore::BufferArrayStream outs(rawbody.get());
+ outs << "text=&target_lang=EN";
+
+ return adapter->postRawAndSuspend(request, url, rawbody, options, headers);
}
//=========================================================================
@@ -569,58 +1140,78 @@ void LLTranslate::translateMessage(const std::string &from_lang, const std::stri
std::string LLTranslate::addNoTranslateTags(std::string mesg)
{
- if (getPreferredHandler().getCurrentService() != SERVICE_BING)
+ if (getPreferredHandler().getCurrentService() == SERVICE_GOOGLE)
+ {
+ return mesg;
+ }
+
+ if (getPreferredHandler().getCurrentService() == SERVICE_DEEPL)
{
return mesg;
}
- std::string upd_msg(mesg);
- LLUrlMatch match;
- S32 dif = 0;
- //surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation
- while (LLUrlRegistry::instance().findUrl(mesg, match))
+ if (getPreferredHandler().getCurrentService() == SERVICE_AZURE)
{
- upd_msg.insert(dif + match.getStart(), BING_NOTRANSLATE_OPENING_TAG);
- upd_msg.insert(dif + BING_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, BING_NOTRANSLATE_CLOSING_TAG);
- mesg.erase(match.getStart(), match.getEnd() - match.getStart());
- dif += match.getEnd() - match.getStart() + BING_NOTRANSLATE_OPENING_TAG.size() + BING_NOTRANSLATE_CLOSING_TAG.size();
+ // https://learn.microsoft.com/en-us/azure/cognitive-services/translator/prevent-translation
+ std::string upd_msg(mesg);
+ LLUrlMatch match;
+ S32 dif = 0;
+ //surround all links (including SLURLs) with 'no-translate' tags to prevent unnecessary translation
+ while (LLUrlRegistry::instance().findUrl(mesg, match))
+ {
+ upd_msg.insert(dif + match.getStart(), AZURE_NOTRANSLATE_OPENING_TAG);
+ upd_msg.insert(dif + AZURE_NOTRANSLATE_OPENING_TAG.size() + match.getEnd() + 1, AZURE_NOTRANSLATE_CLOSING_TAG);
+ mesg.erase(match.getStart(), match.getEnd() - match.getStart());
+ dif += match.getEnd() - match.getStart() + AZURE_NOTRANSLATE_OPENING_TAG.size() + AZURE_NOTRANSLATE_CLOSING_TAG.size();
+ }
+ return upd_msg;
}
- return upd_msg;
+ return mesg;
}
std::string LLTranslate::removeNoTranslateTags(std::string mesg)
{
- if (getPreferredHandler().getCurrentService() != SERVICE_BING)
+ if (getPreferredHandler().getCurrentService() == SERVICE_GOOGLE)
{
return mesg;
}
- std::string upd_msg(mesg);
- LLUrlMatch match;
- S32 opening_tag_size = BING_NOTRANSLATE_OPENING_TAG.size();
- S32 closing_tag_size = BING_NOTRANSLATE_CLOSING_TAG.size();
- S32 dif = 0;
- //remove 'no-translate' tags we added to the links before
- while (LLUrlRegistry::instance().findUrl(mesg, match))
+ if (getPreferredHandler().getCurrentService() == SERVICE_DEEPL)
{
- if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == BING_NOTRANSLATE_OPENING_TAG)
- {
- upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size);
- dif -= opening_tag_size;
+ return mesg;
+ }
- if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == BING_NOTRANSLATE_CLOSING_TAG)
+ if (getPreferredHandler().getCurrentService() == SERVICE_AZURE)
+ {
+ std::string upd_msg(mesg);
+ LLUrlMatch match;
+ S32 opening_tag_size = AZURE_NOTRANSLATE_OPENING_TAG.size();
+ S32 closing_tag_size = AZURE_NOTRANSLATE_CLOSING_TAG.size();
+ S32 dif = 0;
+ //remove 'no-translate' tags we added to the links before
+ while (LLUrlRegistry::instance().findUrl(mesg, match))
+ {
+ if (upd_msg.substr(dif + match.getStart() - opening_tag_size, opening_tag_size) == AZURE_NOTRANSLATE_OPENING_TAG)
{
- upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " ");
- dif -= closing_tag_size - 1;
+ upd_msg.erase(dif + match.getStart() - opening_tag_size, opening_tag_size);
+ dif -= opening_tag_size;
+
+ if (upd_msg.substr(dif + match.getEnd() + 1, closing_tag_size) == AZURE_NOTRANSLATE_CLOSING_TAG)
+ {
+ upd_msg.replace(dif + match.getEnd() + 1, closing_tag_size, " ");
+ dif -= closing_tag_size - 1;
+ }
}
+ mesg.erase(match.getStart(), match.getUrl().size());
+ dif += match.getUrl().size();
}
- mesg.erase(match.getStart(), match.getUrl().size());
- dif += match.getUrl().size();
+ return upd_msg;
}
- return upd_msg;
+
+ return mesg;
}
/*static*/
-void LLTranslate::verifyKey(EService service, const std::string &key, KeyVerificationResult_fn fnc)
+void LLTranslate::verifyKey(EService service, const LLSD &key, KeyVerificationResult_fn fnc)
{
LLTranslationAPIHandler& handler = getHandler(service);
@@ -686,13 +1277,21 @@ LLSD LLTranslate::asLLSD() const
// static
LLTranslationAPIHandler& LLTranslate::getPreferredHandler()
{
- EService service = SERVICE_BING;
+ EService service = SERVICE_AZURE;
std::string service_str = gSavedSettings.getString("TranslationService");
if (service_str == "google")
{
service = SERVICE_GOOGLE;
}
+ if (service_str == "azure")
+ {
+ service = SERVICE_AZURE;
+ }
+ if (service_str == "deepl")
+ {
+ service = SERVICE_DEEPL;
+ }
return getHandler(service);
}
@@ -701,12 +1300,19 @@ LLTranslationAPIHandler& LLTranslate::getPreferredHandler()
LLTranslationAPIHandler& LLTranslate::getHandler(EService service)
{
static LLGoogleTranslationHandler google;
- static LLBingTranslationHandler bing;
+ static LLAzureTranslationHandler azure;
+ static LLDeepLTranslationHandler deepl;
- if (service == SERVICE_GOOGLE)
- {
- return google;
- }
+ switch (service)
+ {
+ case SERVICE_AZURE:
+ return azure;
+ case SERVICE_GOOGLE:
+ return google;
+ case SERVICE_DEEPL:
+ return deepl;
+ }
+
+ return azure;
- return bing;
}
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
index 58707e2d36..4a5d80737c 100644
--- a/indra/newview/lltranslate.h
+++ b/indra/newview/lltranslate.h
@@ -59,11 +59,12 @@ class LLTranslate: public LLSingleton<LLTranslate>
public :
typedef enum e_service {
- SERVICE_BING,
+ SERVICE_AZURE,
SERVICE_GOOGLE,
+ SERVICE_DEEPL,
} EService;
- typedef boost::function<void(EService, bool)> KeyVerificationResult_fn;
+ typedef boost::function<void(EService, bool, S32)> KeyVerificationResult_fn;
typedef boost::function<void(std::string , std::string )> TranslationSuccess_fn;
typedef boost::function<void(int, std::string)> TranslationFailure_fn;
@@ -78,12 +79,12 @@ public :
static void translateMessage(const std::string &from_lang, const std::string &to_lang, const std::string &mesg, TranslationSuccess_fn success, TranslationFailure_fn failure);
/**
- * Verify given API key of a translation service.
- *
- * @param receiver Object to pass verification result to.
- * @param key Key to verify.
- */
- static void verifyKey(EService service, const std::string &key, KeyVerificationResult_fn fnc);
+ * Verify given API key of a translation service.
+ *
+ * @param receiver Object to pass verification result to.
+ * @param key Key to verify.
+ */
+ static void verifyKey(EService service, const LLSD &key, KeyVerificationResult_fn fnc);
/**
* @return translation target language
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index aae4409167..9f4287c23d 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -700,6 +700,7 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPostProcessingHDR", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
@@ -708,6 +709,8 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlowHDR", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlowNoise", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
index 6bab2c2100..226e0a9a56 100644
--- a/indra/newview/llviewerinput.cpp
+++ b/indra/newview/llviewerinput.cpp
@@ -1597,7 +1597,8 @@ bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down)
{
- BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down);
+ bool is_toolmgr_action = false;
+ BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down, is_toolmgr_action);
if (clicktype != CLICK_NONE)
{
@@ -1616,7 +1617,7 @@ BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask,
// If the first LMB click is handled by the menu, skip the following double click
static bool skip_double_click = false;
- if (clicktype == CLICK_LEFT && down )
+ if (clicktype == CLICK_LEFT && down && !is_toolmgr_action)
{
skip_double_click = handled;
}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index b9042b3496..6e5c268c00 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7826,10 +7826,6 @@ class LLToggleShaderControl : public view_listener_t
BOOL checked = gSavedSettings.getBOOL( control_name );
gSavedSettings.setBOOL( control_name, !checked );
LLPipeline::refreshCachedSettings();
- //gPipeline.updateRenderDeferred();
- //gPipeline.releaseGLBuffers();
- //gPipeline.createGLBuffers();
- //gPipeline.resetVertexBuffers();
LLViewerShaderMgr::instance()->setShaders();
return !checked;
}
@@ -8560,6 +8556,9 @@ class LLViewHighlightTransparent : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha;
+
+ // invisible objects skip building their render batches unless sShowDebugAlpha is true, so rebuild batches whenever toggling this flag
+ gPipeline.rebuildDrawInfo();
return true;
}
};
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index f14e3ed737..b756d3d87f 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1532,7 +1532,7 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus);
break;
case LLAssetType::AT_MATERIAL:
- LLFloaterReg::showInstance("material editor", LLSD(obj_id), take_focus);
+ LLFloaterReg::showInstance("material_editor", LLSD(obj_id), take_focus);
break;
default:
LL_DEBUGS("Messaging") << "No preview method for previewable asset type : " << LLAssetType::lookupHumanReadable(asset_type) << LL_ENDL;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 8930b2453b..7871815fda 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -418,6 +418,7 @@ void LLViewerObject::markDead()
{
if (!mDead)
{
+ LL_PROFILE_ZONE_SCOPED;
//LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;
// Root object of this hierarchy unlinks itself.
@@ -1153,6 +1154,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
const EObjectUpdateType update_type,
LLDataPacker *dp)
{
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL;
LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL;
@@ -1269,7 +1271,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
LL_INFOS() << "Full:" << getID() << LL_ENDL;
#endif
//clear cost and linkset cost
- mCostStale = true;
+ setObjectCostStale();
if (isSelected())
{
gFloaterTools->dirty();
@@ -1825,7 +1827,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
#ifdef DEBUG_UPDATE_TYPE
LL_INFOS() << "CompFull:" << getID() << LL_ENDL;
#endif
- mCostStale = true;
+ setObjectCostStale();
if (isSelected())
{
@@ -3779,6 +3781,16 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped)
}
}
+void LLViewerObject::setObjectCostStale()
+{
+ mCostStale = true;
+ // *NOTE: This is harmlessly redundant for Blinn-Phong material updates, as
+ // the root prim currently gets set stale anyway due to other property
+ // updates. But it is needed for GLTF material ID updates.
+ // -Cosmic,2023-06-27
+ getRootEdit()->mCostStale = true;
+}
+
void LLViewerObject::setObjectCost(F32 cost)
{
mObjectCost = cost;
@@ -6818,7 +6830,7 @@ void LLViewerObject::setPhysicsShapeType(U8 type)
if (type != mPhysicsShapeType)
{
mPhysicsShapeType = type;
- mCostStale = true;
+ setObjectCostStale();
}
}
@@ -7325,6 +7337,12 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat
LLGLTFMaterialList::queueApply(this, te, id);
}
}
+
+ if (!update_server)
+ {
+ // Land impact may have changed
+ setObjectCostStale();
+ }
}
void LLViewerObject::setRenderMaterialIDs(const LLUUID& id)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index f4f596bfd0..4d49c61b23 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -638,6 +638,7 @@ public:
std::vector<LLVector3> mUnselectedChildrenPositions ;
private:
+ void setObjectCostStale();
bool isAssetInInventory(LLViewerInventoryItem* item);
ExtraParameter* createNewParameterEntry(U16 param_type);
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index e576784db8..ce4f9b7e64 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1353,6 +1353,7 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
{
+ LL_PROFILE_ZONE_SCOPED;
// Don't ever kill gAgentAvatarp, just force it to the agent's region
// unless region is NULL which is assumed to mean you are logging out.
if ((objectp == gAgentAvatarp) && gAgent.getRegion())
@@ -1379,6 +1380,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
void LLViewerObjectList::killObjects(LLViewerRegion *regionp)
{
+ LL_PROFILE_ZONE_SCOPED;
LLViewerObject *objectp;
@@ -1438,6 +1440,8 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
return;
}
+ LL_PROFILE_ZONE_SCOPED;
+
S32 num_removed = 0;
LLViewerObject *objectp;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index d60fae4bd6..6b92b16ef4 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -716,6 +716,7 @@ static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache");
LLViewerRegion::~LLViewerRegion()
{
+ LL_PROFILE_ZONE_SCOPED;
mDead = TRUE;
mImpl->mActiveSet.clear();
mImpl->mVisibleEntries.clear();
@@ -1590,6 +1591,7 @@ void LLViewerRegion::lightIdleUpdate()
void LLViewerRegion::idleUpdate(F32 max_update_time)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTimer update_timer;
F32 max_time;
@@ -1693,6 +1695,10 @@ BOOL LLViewerRegion::isViewerCameraStatic()
void LLViewerRegion::killInvisibleObjects(F32 max_time)
{
+#if 1 // TODO: kill this. This is ill-conceived, objects that aren't in the camera frustum should not be deleted from memory.
+ // because of this, every time you turn around the simulator sends a swarm of full object update messages from cache
+ // probe misses and objects have to be reloaded from scratch. From some reason, disabling this causes holes to
+ // appear in the scene when flying back and forth between regions
if(!sVOCacheCullingEnabled)
{
return;
@@ -1769,6 +1775,7 @@ void LLViewerRegion::killInvisibleObjects(F32 max_time)
}
return;
+#endif
}
void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list)
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index f6f1cf6854..6e5d85bc88 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -92,6 +92,7 @@ LLGLSLShader gCopyDepthProgram;
//object shaders
LLGLSLShader gObjectPreviewProgram;
+LLGLSLShader gSkinnedObjectPreviewProgram;
LLGLSLShader gPhysicsPreviewProgram;
LLGLSLShader gObjectFullbrightAlphaMaskProgram;
LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
@@ -251,7 +252,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderList.push_back(&gWaterProgram);
mShaderList.push_back(&gWaterEdgeProgram);
mShaderList.push_back(&gAvatarEyeballProgram);
- mShaderList.push_back(&gObjectPreviewProgram);
mShaderList.push_back(&gImpostorProgram);
mShaderList.push_back(&gObjectBumpProgram);
mShaderList.push_back(&gSkinnedObjectBumpProgram);
@@ -898,11 +898,20 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
if (success)
{
- gGlowExtractProgram.mName = "Glow Extract Shader (Post)";
+ const bool use_glow_noise = gSavedSettings.getBOOL("RenderGlowNoise");
+ const std::string glow_noise_label = use_glow_noise ? " (+Noise)" : "";
+
+ gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str());
gGlowExtractProgram.mShaderFiles.clear();
gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER));
gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER));
gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
+
+ if (use_glow_noise)
+ {
+ gGlowExtractProgram.addPermutation("HAS_NOISE", "1");
+ }
+
success = gGlowExtractProgram.createShader(NULL, NULL);
if (!success)
{
@@ -2878,20 +2887,16 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gObjectPreviewProgram.mName = "Simple Shader";
- gObjectPreviewProgram.mFeatures.calculatesLighting = false;
- gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false;
- gObjectPreviewProgram.mFeatures.hasGamma = false;
- gObjectPreviewProgram.mFeatures.hasAtmospherics = false;
- gObjectPreviewProgram.mFeatures.hasLighting = false;
- gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
+ gObjectPreviewProgram.mName = "Object Preview Shader";
gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
gObjectPreviewProgram.mShaderFiles.clear();
gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER));
gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER));
gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectPreviewProgram, gSkinnedObjectPreviewProgram);
success = gObjectPreviewProgram.createShader(NULL, NULL);
gObjectPreviewProgram.mFeatures.hasLighting = true;
+ gSkinnedObjectPreviewProgram.mFeatures.hasLighting = true;
}
if (success)
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 37999e58ff..490cadee5c 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -171,7 +171,7 @@ SimMeasurement<> SIM_TIME_DILATION("simtimedilation", "Simulator time scale",
SIM_MAIN_AGENTS("simmainagents", "Number of avatars in current region", LL_SIM_STAT_NUMAGENTMAIN),
SIM_CHILD_AGENTS("simchildagents", "Number of avatars in neighboring regions", LL_SIM_STAT_NUMAGENTCHILD),
SIM_OBJECTS("simobjects", "", LL_SIM_STAT_NUMTASKS),
- SIM_ACTIVE_OBJECTS("simactiveobjects", "Number of scripted and/or mocing objects", LL_SIM_STAT_NUMTASKSACTIVE),
+ SIM_ACTIVE_OBJECTS("simactiveobjects", "Number of scripted and/or moving objects", LL_SIM_STAT_NUMTASKSACTIVE),
SIM_ACTIVE_SCRIPTS("simactivescripts", "Number of scripted objects", LL_SIM_STAT_NUMSCRIPTSACTIVE),
SIM_IN_PACKETS_PER_SEC("siminpps", "", LL_SIM_STAT_INPPS),
SIM_OUT_PACKETS_PER_SEC("simoutpps", "", LL_SIM_STAT_OUTPPS),
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 9c4474f1d3..d80d7f46fd 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -222,6 +222,8 @@ void LLViewerTextureList::doPrefetchImages()
LLViewerTextureManager::getFetchedTexture(IMG_SHOT);
LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF);
+ LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
+ LLViewerFetchedTexture::sSmokeImagep->setNoDelete();
LLStandardBumpmap::addstandard();
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 8516bbc7ec..c6ed6ffb7d 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -996,7 +996,7 @@ void LLViewerWindow::handlePieMenu(S32 x, S32 y, MASK mask)
}
}
-BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down)
+BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool& is_toolmgr_action)
{
const char* buttonname = "";
const char* buttonstatestr = "";
@@ -1145,6 +1145,7 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK m
if(!gDisconnected && LLToolMgr::getInstance()->getCurrentTool()->handleAnyMouseClick( x, y, mask, clicktype, down ) )
{
LLViewerEventRecorder::instance().clear_xui();
+ is_toolmgr_action = true;
return TRUE;
}
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 586ea2bee7..bbce9a25f6 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -181,7 +181,7 @@ public:
void reshapeStatusBarContainer();
- BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
+ BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down, bool &is_toolmgr_action);
//
// LLWindowCallback interface implementation
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index c7a2cea627..22cd9f71b3 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -7574,6 +7574,85 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
}
}
+bool LLVOAvatar::hasPendingAttachedMeshes()
+{
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment)
+ {
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* objectp = attachment_iter->get();
+ if (objectp)
+ {
+ LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
+ iter1 != child_list.end(); ++iter1)
+ {
+ LLViewerObject* objectchild = *iter1;
+ if (objectchild && objectchild->getVolume())
+ {
+ const LLUUID& mesh_id = objectchild->getVolume()->getParams().getSculptID();
+ if (mesh_id.isNull())
+ {
+ // No mesh nor skin info needed
+ continue;
+ }
+
+ if (objectchild->getVolume()->isMeshAssetUnavaliable())
+ {
+ // Mesh failed to load, do not expect it
+ continue;
+ }
+
+ if (objectchild->mDrawable)
+ {
+ LLVOVolume* pvobj = objectchild->mDrawable->getVOVolume();
+ if (pvobj)
+ {
+ if (!pvobj->isMesh())
+ {
+ // Not a mesh
+ continue;
+ }
+
+ if (!objectchild->getVolume()->isMeshAssetLoaded())
+ {
+ // Waiting for mesh
+ return true;
+ }
+
+ const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo();
+ if (skin_data)
+ {
+ // Skin info present, done
+ continue;
+ }
+
+ if (pvobj->isSkinInfoUnavaliable())
+ {
+ // Load failed or info not present, don't expect it
+ continue;
+ }
+ }
+
+ // objectchild is not ready
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
//-----------------------------------------------------------------------------
// detachObject()
//-----------------------------------------------------------------------------
@@ -8150,6 +8229,7 @@ BOOL LLVOAvatar::updateIsFullyLoaded()
|| (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC)
|| !mPendingAttachment.empty()
|| (rez_status < 3 && !isFullyBaked())
+ || hasPendingAttachedMeshes()
);
}
updateRezzedStatusTimers(rez_status);
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index f1dc503c9e..48bfd5293a 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -917,6 +917,7 @@ public:
virtual BOOL detachObject(LLViewerObject *viewer_object);
static bool getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id );
void cleanupAttachedMesh( LLViewerObject* pVO );
+ bool hasPendingAttachedMeshes();
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;
LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const;
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 7081ecaa4b..a92057d010 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -105,7 +105,7 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data)
std::string error, warn;
if (override_mat->fromJSON(gltf_json_str, warn, error))
{
- mGLTFMaterial[i] = override_mat;
+ mGLTFMaterial[side_idx] = override_mat;
}
else
{
@@ -126,6 +126,16 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data)
LL_WARNS_IF(sides.size() != 0, "GLTF") << "broken override cache entry" << LL_ENDL;
}
}
+
+ llassert(mSides.size() == mGLTFMaterial.size());
+#ifdef SHOW_ASSERT
+ for (auto const & side : mSides)
+ {
+ // check that mSides and mGLTFMaterial have exactly the same keys present
+ llassert(mGLTFMaterial.count(side.first) == 1);
+ }
+#endif
+
return true;
}
@@ -141,8 +151,11 @@ LLSD LLGLTFOverrideCacheEntry::toLLSD() const
data["object_id"] = mObjectId;
data["local_id"] = (LLSD::Integer) mLocalId;
+ llassert(mSides.size() == mGLTFMaterial.size());
for (auto const & side : mSides)
{
+ // check that mSides and mGLTFMaterial have exactly the same keys present
+ llassert(mGLTFMaterial.count(side.first) == 1);
data["sides"].append(LLSD::Integer(side.first));
data["gltf_json"].append(side.second);
}
@@ -1186,6 +1199,8 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)
readCacheHeader();
+ LL_INFOS() << "Viewer Object Cache Versions - expected: " << cache_version << " found: " << mMetaInfo.mVersion << LL_ENDL;
+
if( mMetaInfo.mVersion != cache_version
|| mMetaInfo.mAddressSize != expected_address)
{
@@ -1196,7 +1211,8 @@ void LLVOCache::initCache(ELLPath location, U32 size, U32 cache_version)
clearCacheInMemory();
}
else //delete the current cache if the format does not match.
- {
+ {
+ LL_INFOS() << "Viewer Object Cache Versions unmatched. clearing cache." << LL_ENDL;
removeCache();
}
}
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index c73f96da2d..3725510b6a 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -276,13 +276,13 @@ static void killGateway()
///////////////////////////////////////////////////////////////////////////////////////////////
bool LLVivoxVoiceClient::sShuttingDown = false;
+bool LLVivoxVoiceClient::sConnected = false;
+LLPumpIO *LLVivoxVoiceClient::sPump = nullptr;
LLVivoxVoiceClient::LLVivoxVoiceClient() :
mSessionTerminateRequested(false),
mRelogRequested(false),
- mConnected(false),
mTerminateDaemon(false),
- mPump(NULL),
mSpatialJoiningNum(0),
mTuningMode(false),
@@ -350,7 +350,11 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
mIsProcessingChannels(false),
mIsCoroutineActive(false),
mVivoxPump("vivoxClientPump")
-{
+{
+ sShuttingDown = false;
+ sConnected = false;
+ sPump = nullptr;
+
mSpeakerVolume = scale_speaker_volume(0);
mVoiceVersion.serverVersion = "";
@@ -392,7 +396,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient()
void LLVivoxVoiceClient::init(LLPumpIO *pump)
{
// constructor will set up LLVoiceClient::getInstance()
- mPump = pump;
+ sPump = pump;
// LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",
// boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
@@ -413,10 +417,10 @@ void LLVivoxVoiceClient::terminate()
logoutOfVivox(false);
}
- if(mConnected)
+ if(sConnected)
{
breakVoiceConnection(false);
- mConnected = false;
+ sConnected = false;
}
else
{
@@ -425,7 +429,7 @@ void LLVivoxVoiceClient::terminate()
}
sShuttingDown = true;
- mPump = NULL;
+ sPump = NULL;
}
//---------------------------------------------------
@@ -471,7 +475,7 @@ bool LLVivoxVoiceClient::writeString(const std::string &str)
bool result = false;
LL_DEBUGS("LowVoice") << "sending:\n" << str << LL_ENDL;
- if(mConnected)
+ if(sConnected)
{
apr_status_t err;
apr_size_t size = (apr_size_t)str.size();
@@ -1051,7 +1055,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
int retryCount(0);
LLVoiceVivoxStats::getInstance()->reset();
- while (!mConnected && !sShuttingDown && retryCount++ <= DAEMON_CONNECT_RETRY_MAX)
+ while (!sConnected && !sShuttingDown && retryCount++ <= DAEMON_CONNECT_RETRY_MAX)
{
LLVoiceVivoxStats::getInstance()->connectionAttemptStart();
LL_DEBUGS("Voice") << "Attempting to connect to vivox daemon: " << mDaemonHost << LL_ENDL;
@@ -1061,23 +1065,23 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
mSocket = LLSocket::create(gAPRPoolp, LLSocket::STREAM_TCP);
}
- mConnected = mSocket->blockingConnect(mDaemonHost);
- LLVoiceVivoxStats::getInstance()->connectionAttemptEnd(mConnected);
- if (!mConnected)
+ sConnected = mSocket->blockingConnect(mDaemonHost);
+ LLVoiceVivoxStats::getInstance()->connectionAttemptEnd(sConnected);
+ if (!sConnected)
{
llcoro::suspendUntilTimeout(DAEMON_CONNECT_THROTTLE_SECONDS);
}
}
//---------------------------------------------------------------------
- if (sShuttingDown && !mConnected)
+ if (sShuttingDown && !sConnected)
{
return false;
}
llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
- while (!mPump && !sShuttingDown)
+ while (!sPump && !sShuttingDown)
{ // Can't use the pump until we have it available.
llcoro::suspend();
}
@@ -1099,7 +1103,7 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser()));
- mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS);
+ sPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS);
//---------------------------------------------------------------------
@@ -1321,9 +1325,9 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
// the message, yet we need to receive "connector shutdown response".
// Either wait a bit and emulate it or check gMessageSystem for specific message
_sleep(1000);
- if (mConnected)
+ if (sConnected)
{
- mConnected = false;
+ sConnected = false;
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
mVivoxPump.post(vivoxevent);
}
@@ -1335,7 +1339,7 @@ bool LLVivoxVoiceClient::breakVoiceConnection(bool corowait)
LL_DEBUGS("Voice") << "closing SLVoice socket" << LL_ENDL;
closeSocket(); // Need to do this now -- bad things happen if the destructor does it later.
cleanUp();
- mConnected = false;
+ sConnected = false;
return retval;
}
@@ -2516,7 +2520,7 @@ bool LLVivoxVoiceClient::performMicTuning()
void LLVivoxVoiceClient::closeSocket(void)
{
mSocket.reset();
- mConnected = false;
+ sConnected = false;
mConnectorEstablished = false;
mAccountLoggedIn = false;
}
@@ -3017,7 +3021,7 @@ bool LLVivoxVoiceClient::deviceSettingsAvailable()
{
bool result = true;
- if(!mConnected)
+ if(!sConnected)
result = false;
if(mRenderDevices.empty())
@@ -3816,7 +3820,7 @@ void LLVivoxVoiceClient::connectorShutdownResponse(int statusCode, std::string &
// Should this ever fail? do we care if it does?
}
- mConnected = false;
+ sConnected = false;
mShutdownComplete = true;
LLSD vivoxevent(LLSDMap("connector", LLSD::Boolean(false)));
@@ -7389,7 +7393,7 @@ LLIOPipe::EStatus LLVivoxProtocolParser::process_impl(
LL_DEBUGS("VivoxProtocolParser") << "at end, mInput is: " << mInput << LL_ENDL;
- if(!LLVivoxVoiceClient::getInstance()->mConnected)
+ if(!LLVivoxVoiceClient::sConnected)
{
// If voice has been disabled, we just want to close the socket. This does so.
LL_INFOS("Voice") << "returning STATUS_STOP" << LL_ENDL;
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 0a785401c1..e3ab99c675 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -666,12 +666,10 @@ private:
LLHost mDaemonHost;
LLSocket::ptr_t mSocket;
- bool mConnected;
// We should kill the voice daemon in case of connection alert
bool mTerminateDaemon;
- LLPumpIO *mPump;
friend class LLVivoxProtocolParser;
std::string mAccountName;
@@ -916,7 +914,10 @@ private:
bool mIsProcessingChannels;
bool mIsCoroutineActive;
- static bool sShuttingDown; // corutines can last longer than vivox so we need a static variable as a shutdown flag
+ // This variables can last longer than vivox in coroutines so we need them as static
+ static bool sShuttingDown;
+ static bool sConnected;
+ static LLPumpIO* sPump;
LLEventMailDrop mVivoxPump;
};
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 8eacdd2162..5acf2c198f 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -230,7 +230,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mColorChanged = FALSE;
mSpotLightPriority = 0.f;
- mSkinInfoFailed = false;
+ mSkinInfoUnavaliable = false;
mSkinInfo = NULL;
mMediaImplList.resize(getNumTEs());
@@ -244,6 +244,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
LLVOVolume::~LLVOVolume()
{
+ LL_PROFILE_ZONE_SCOPED;
delete mTextureAnimp;
mTextureAnimp = NULL;
delete mVolumeImpl;
@@ -267,6 +268,7 @@ void LLVOVolume::markDead()
{
if (!mDead)
{
+ LL_PROFILE_ZONE_SCOPED;
if (getVolume())
{
LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID());
@@ -1132,7 +1134,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID())
{
mSkinInfo = NULL;
- mSkinInfoFailed = false;
+ mSkinInfoUnavaliable = false;
}
if (!getVolume()->isMeshAssetLoaded())
@@ -1145,13 +1147,24 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
- if (!mSkinInfo && !mSkinInfoFailed)
+ if (!mSkinInfo && !mSkinInfoUnavaliable)
{
- const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this);
- if (skin_info)
- {
- notifySkinInfoLoaded(skin_info);
- }
+ LLUUID mesh_id = volume_params.getSculptID();
+ if (gMeshRepo.hasHeader(mesh_id) && !gMeshRepo.hasSkinInfo(mesh_id))
+ {
+ // If header is present but has no data about skin,
+ // no point fetching
+ mSkinInfoUnavaliable = true;
+ }
+
+ if (!mSkinInfoUnavaliable)
+ {
+ const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(mesh_id, this);
+ if (skin_info)
+ {
+ notifySkinInfoLoaded(skin_info);
+ }
+ }
}
}
else // otherwise is sculptie
@@ -1186,7 +1199,7 @@ void LLVOVolume::updateSculptTexture()
mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
}
- mSkinInfoFailed = false;
+ mSkinInfoUnavaliable = false;
mSkinInfo = NULL;
}
else
@@ -1227,6 +1240,16 @@ void LLVOVolume::notifyMeshLoaded()
mSculptChanged = TRUE;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
+ if (!mSkinInfo && !mSkinInfoUnavaliable)
+ {
+ // Header was loaded, update skin info state from header
+ LLUUID mesh_id = getVolume()->getParams().getSculptID();
+ if (!gMeshRepo.hasSkinInfo(mesh_id))
+ {
+ mSkinInfoUnavaliable = true;
+ }
+ }
+
LLVOAvatar *av = getAvatar();
if (av && !isAnimatedObject())
{
@@ -1244,7 +1267,7 @@ void LLVOVolume::notifyMeshLoaded()
void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin)
{
- mSkinInfoFailed = false;
+ mSkinInfoUnavaliable = false;
mSkinInfo = skin;
notifyMeshLoaded();
@@ -1252,7 +1275,7 @@ void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin)
void LLVOVolume::notifySkinInfoUnavailable()
{
- mSkinInfoFailed = true;
+ mSkinInfoUnavaliable = true;
mSkinInfo = nullptr;
}
@@ -4686,7 +4709,12 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
end_face = face+1;
}
pick_transparent |= isHiglightedOrBeacon();
- bool special_cursor = specialHoverCursor();
+
+ // we *probably* shouldn't care about special cursor at all, but we *definitely*
+ // don't care about special cursor for reflection probes -- makes alt-zoom
+ // go through reflection probes on vehicles
+ bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor();
+
for (S32 i = start_face; i < end_face; ++i)
{
if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f)
@@ -5304,13 +5332,14 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
if (mat)
{
+ BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) || (facep->getTextureEntry()->getColor().mV[3] < 0.999f) ? TRUE : FALSE;
if (type == LLRenderPass::PASS_ALPHA)
{
- shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND);
+ shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_BLEND, is_alpha);
}
else
{
- shader_mask = mat->getShaderMask();
+ shader_mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha);
}
}
@@ -5599,11 +5628,21 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
std::string vobj_name = llformat("Vol%p", vobj);
bool is_mesh = vobj->isMesh();
- if (is_mesh &&
- ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
- {
- continue;
- }
+ if (is_mesh)
+ {
+ if ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded())
+ || !gMeshRepo.meshRezEnabled())
+ {
+ // Waiting for asset to fetch
+ continue;
+ }
+
+ if (!vobj->getSkinInfo() && !vobj->isSkinInfoUnavaliable())
+ {
+ // Waiting for skin info to fetch
+ continue;
+ }
+ }
LLVolume* volume = vobj->getVolume();
if (volume)
@@ -5803,15 +5842,20 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
else
{
- if (te->getColor().mV[3] > 0.f || te->getGlow() > 0.f)
- { //only treat as alpha in the pipeline if < 100% transparent
- drawablep->setState(LLDrawable::HAS_ALPHA);
- add_face(sAlphaFaces, alpha_count, facep);
- }
- else if (LLDrawPoolAlpha::sShowDebugAlpha)
- {
- add_face(sAlphaFaces, alpha_count, facep);
- }
+ if (te->getColor().mV[3] > 0.f || te->getGlow() > 0.f)
+ { //only treat as alpha in the pipeline if < 100% transparent
+ drawablep->setState(LLDrawable::HAS_ALPHA);
+ add_face(sAlphaFaces, alpha_count, facep);
+ }
+ else if (LLDrawPoolAlpha::sShowDebugAlpha ||
+ (gPipeline.sRenderHighlight && !drawablep->getParent() &&
+ //only root objects are highlighted with red color in this case
+ drawablep->getVObj() && drawablep->getVObj()->flagScripted() &&
+ (LLPipeline::getRenderScriptedBeacons() ||
+ (LLPipeline::getRenderScriptedTouchBeacons() && drawablep->getVObj()->flagHandleTouch()))))
+ { //draw the transparent face for debugging purposes using a custom texture
+ add_face(sAlphaFaces, alpha_count, facep);
+ }
}
}
else
@@ -6565,7 +6609,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{ // HACK - this should never happen, but sometimes we get a material that thinks it has alpha blending when it ought not
alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
}
- U32 mask = mat->getShaderMask(alpha_mode);
+ U32 mask = mat->getShaderMask(alpha_mode, is_alpha);
U32 vb_mask = facep->getVertexBuffer()->getTypeMask();
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index f2162ef244..93aba9b8cb 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -331,6 +331,7 @@ public:
BOOL setIsFlexible(BOOL is_flexible);
const LLMeshSkinInfo* getSkinInfo() const;
+ const bool isSkinInfoUnavaliable() const { return mSkinInfoUnavaliable; }
//convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons)
const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); }
@@ -481,7 +482,7 @@ private:
LLPointer<LLRiggedVolume> mRiggedVolume;
- bool mSkinInfoFailed;
+ bool mSkinInfoUnavaliable;
LLConstPointer<LLMeshSkinInfo> mSkinInfo;
// statics
public:
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 608d2cb799..77ad967cef 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -142,9 +142,14 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
static const unsigned int vertices_per_quad = 4;
static const unsigned int indices_per_quad = 6;
- const S32 size = LLPipeline::sRenderTransparentWater ? 16 : 1;
+ S32 size_x = LLPipeline::sRenderTransparentWater ? 8 : 1;
+ S32 size_y = LLPipeline::sRenderTransparentWater ? 8 : 1;
- const S32 num_quads = size * size;
+ const LLVector3& scale = getScale();
+ size_x *= llmin(llround(scale.mV[0] / 256.f), 8);
+ size_y *= llmin(llround(scale.mV[1] / 256.f), 8);
+
+ const S32 num_quads = size_x * size_y;
face->setSize(vertices_per_quad * num_quads,
indices_per_quad * num_quads);
@@ -175,41 +180,37 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
face->mCenterLocal = position_agent;
S32 x, y;
- F32 step_x = getScale().mV[0] / size;
- F32 step_y = getScale().mV[1] / size;
+ F32 step_x = getScale().mV[0] / size_x;
+ F32 step_y = getScale().mV[1] / size_y;
const LLVector3 up(0.f, step_y * 0.5f, 0.f);
const LLVector3 right(step_x * 0.5f, 0.f, 0.f);
const LLVector3 normal(0.f, 0.f, 1.f);
- F32 size_inv = 1.f / size;
-
- F32 z_fudge = 0.f;
+ F32 size_inv_x = 1.f / size_x;
+ F32 size_inv_y = 1.f / size_y;
- if (getIsEdgePatch())
- { //bump edge patches down 10 cm to prevent aliasing along edges
- z_fudge = -0.1f;
- }
-
- for (y = 0; y < size; y++)
+ for (y = 0; y < size_y; y++)
{
- for (x = 0; x < size; x++)
+ for (x = 0; x < size_x; x++)
{
- S32 toffset = index_offset + 4*(y*size + x);
+ S32 toffset = index_offset + 4*(y*size_x + x);
position_agent = getPositionAgent() - getScale() * 0.5f;
position_agent.mV[VX] += (x + 0.5f) * step_x;
position_agent.mV[VY] += (y + 0.5f) * step_y;
- position_agent.mV[VZ] += z_fudge;
+
+ position_agent.mV[VX] = llround(position_agent.mV[VX]);
+ position_agent.mV[VY] = llround(position_agent.mV[VY]);
*verticesp++ = position_agent - right + up;
*verticesp++ = position_agent - right - up;
*verticesp++ = position_agent + right + up;
*verticesp++ = position_agent + right - up;
- *texCoordsp++ = LLVector2(x*size_inv, (y+1)*size_inv);
- *texCoordsp++ = LLVector2(x*size_inv, y*size_inv);
- *texCoordsp++ = LLVector2((x+1)*size_inv, (y+1)*size_inv);
- *texCoordsp++ = LLVector2((x+1)*size_inv, y*size_inv);
+ *texCoordsp++ = LLVector2(x*size_inv_x, (y+1)*size_inv_y);
+ *texCoordsp++ = LLVector2(x*size_inv_x, y*size_inv_y);
+ *texCoordsp++ = LLVector2((x+1)*size_inv_x, (y+1)*size_inv_y);
+ *texCoordsp++ = LLVector2((x+1)*size_inv_x, y*size_inv_y);
*normalsp++ = normal;
*normalsp++ = normal;
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 0e0dbdc071..709a457862 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -111,7 +111,7 @@ LLWorld::LLWorld() :
gGL.getTexUnit(0)->bind(mDefaultWaterTexturep);
mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("RequestFullRegionCache") && gSavedSettings.getBOOL("ObjectCacheEnabled");
+ LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("RequestFullRegionCache") && gSavedSettings.getBOOL("ObjectCacheEnabled");
}
@@ -681,6 +681,7 @@ static LLTrace::SampleStatHandle<> sNumActiveCachedObjects("numactivecachedobjec
void LLWorld::updateRegions(F32 max_update_time)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTimer update_timer;
mNumOfActiveCachedObjects = 0;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index d6e0bf1b09..d7188c0fe7 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -157,6 +157,7 @@ S32 LLPipeline::RenderGlowResolutionPow;
S32 LLPipeline::RenderGlowIterations;
F32 LLPipeline::RenderGlowWidth;
F32 LLPipeline::RenderGlowStrength;
+bool LLPipeline::RenderGlowNoise;
bool LLPipeline::RenderDepthOfField;
bool LLPipeline::RenderDepthOfFieldInEditMode;
F32 LLPipeline::CameraFocusTransitionTime;
@@ -517,6 +518,7 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderGlowIterations");
connectRefreshCachedSettingsSafe("RenderGlowWidth");
connectRefreshCachedSettingsSafe("RenderGlowStrength");
+ connectRefreshCachedSettingsSafe("RenderGlowNoise");
connectRefreshCachedSettingsSafe("RenderDepthOfField");
connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode");
connectRefreshCachedSettingsSafe("CameraFocusTransitionTime");
@@ -840,7 +842,9 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
mSceneMap.allocate(resX, resY, GL_RGB, true);
}
- mPostMap.allocate(resX, resY, GL_RGBA);
+ const bool post_hdr = gSavedSettings.getBOOL("RenderPostProcessingHDR");
+ const U32 post_color_fmt = post_hdr ? GL_RGBA16F : GL_RGBA;
+ mPostMap.allocate(resX, resY, post_color_fmt);
//HACK make screenbuffer allocations start failing after 30 seconds
if (gSavedSettings.getBOOL("SimulateFBOFailure"))
@@ -1005,6 +1009,7 @@ void LLPipeline::refreshCachedSettings()
RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations");
RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth");
RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength");
+ RenderGlowNoise = gSavedSettings.getBOOL("RenderGlowNoise");
RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField");
RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode");
CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime");
@@ -1163,9 +1168,11 @@ void LLPipeline::createGLBuffers()
// allocate screen space glow buffers
const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
+ const bool glow_hdr = gSavedSettings.getBOOL("RenderGlowHDR");
+ const U32 glow_color_fmt = glow_hdr ? GL_RGBA16F : GL_RGBA;
for (U32 i = 0; i < 3; i++)
{
- mGlow[i].allocate(512, glow_res, GL_RGBA);
+ mGlow[i].allocate(512, glow_res, glow_color_fmt);
}
allocateScreenBuffer(resX, resY);
@@ -6882,6 +6889,19 @@ void LLPipeline::generateGlow(LLRenderTarget* src)
warmthWeights.mV[2]);
gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
+ if (RenderGlowNoise)
+ {
+ S32 channel = gGlowExtractProgram.enableTexture(LLShaderMgr::GLOW_NOISE_MAP);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+ gGlowExtractProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES,
+ mGlow[2].getWidth(),
+ mGlow[2].getHeight());
+ }
+
{
LLGLEnable blend_on(GL_BLEND);
@@ -10600,8 +10620,42 @@ void LLPipeline::handleShadowDetailChanged()
}
}
-void LLPipeline::overrideEnvironmentMap()
+class LLOctreeDirty : public OctreeTraveler
{
- //mReflectionMapManager.mProbes.clear();
- //mReflectionMapManager.addProbe(LLViewerCamera::instance().getOrigin());
+public:
+ virtual void visit(const OctreeNode* state)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*)state->getListener(0);
+
+ if (group->getSpatialPartition()->mRenderByGroup)
+ {
+ group->setState(LLSpatialGroup::GEOM_DIRTY);
+ gPipeline.markRebuild(group);
+ }
+
+ for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
+ {
+ LLSpatialBridge* bridge = *i;
+ traverse(bridge->mOctree);
+ }
+ }
+};
+
+
+void LLPipeline::rebuildDrawInfo()
+{
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ LLOctreeDirty dirty;
+
+ LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME);
+ dirty.traverse(part->mOctree);
+
+ part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
+ dirty.traverse(part->mOctree);
+ }
}
+
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 19c8b06a46..c0559ce83b 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -131,6 +131,10 @@ public:
bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples);
bool allocateShadowBuffer(U32 resX, U32 resY);
+ // rebuild all LLVOVolume render batches
+ void rebuildDrawInfo();
+
+ // Clear LLFace mVertexBuffer pointers
void resetVertexBuffers(LLDrawable* drawable);
// perform a profile of the given avatar
@@ -449,7 +453,6 @@ public:
void handleShadowDetailChanged();
LLReflectionMapManager mReflectionMapManager;
- void overrideEnvironmentMap();
private:
void unloadShaders();
@@ -998,6 +1001,7 @@ public:
static S32 RenderGlowIterations;
static F32 RenderGlowWidth;
static F32 RenderGlowStrength;
+ static bool RenderGlowNoise;
static bool RenderDepthOfField;
static bool RenderDepthOfFieldInEditMode;
static F32 CameraFocusTransitionTime;
diff --git a/indra/newview/skins/default/textures/icons/profile_badge_beta.png b/indra/newview/skins/default/textures/icons/profile_badge_beta.png
new file mode 100644
index 0000000000..7c8a723c47
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_badge_beta.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png
new file mode 100644
index 0000000000..7c38e9e2ae
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png
new file mode 100644
index 0000000000..475edd080e
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_badge_linden.png b/indra/newview/skins/default/textures/icons/profile_badge_linden.png
new file mode 100644
index 0000000000..1b6ac03e86
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_badge_linden.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png
new file mode 100644
index 0000000000..4286995202
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png
new file mode 100644
index 0000000000..47e93c4fac
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 61257466aa..f6f3a984f5 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -512,7 +512,13 @@ with the same filename but different name
<texture name="Play_Off" file_name="icons/Play_Off.png" preload="false" />
<texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
<texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
-
+
+ <texture name="Profile_Badge_Beta" file_name="icons/profile_badge_beta.png" preload="true"/>
+ <texture name="Profile_Badge_Beta_Lifetime" file_name="icons/profile_badge_beta_lifetime.png" preload="true"/>
+ <texture name="Profile_Badge_Lifetime" file_name="icons/profile_badge_lifetime.png" preload="true"/>
+ <texture name="Profile_Badge_Linden" file_name="icons/profile_badge_linden.png" preload="true"/>
+ <texture name="Profile_Badge_Pplus_Lifetime" file_name="icons/profile_badge_pplus_lifetime.png" preload="true"/>
+ <texture name="Profile_Badge_Premium_Lifetime" file_name="icons/profile_badge_premium_lifetime.png" preload="true"/>
<texture name="Profile_Group_Visibility_Off" file_name="icons/profile_group_visibility_eye_off.png" preload="true"/>
<texture name="Profile_Group_Visibility_Off_Pressed" file_name="icons/profile_group_visibility_eye_off_pressed.png" preload="true"/>
<texture name="Profile_Group_Visibility_On" file_name="icons/profile_group_visibility_eye_on.png" preload="true"/>
diff --git a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
index 37efbe654e..b757f4eab8 100644
--- a/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_scene_load_stats.xml
@@ -414,7 +414,7 @@
name="frame_stats"
label="Frame breakdown"
show_label="true">
- <stat_bar name="packet_loss"
+ <stat_bar name="scenery_frame_pct"
label="Scenery"
orientation="horizontal"
unit_label=" %"
@@ -422,7 +422,7 @@
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
- <stat_bar name="packet_loss"
+ <stat_bar name="avatar_frame_pct"
label="Avatar"
orientation="horizontal"
unit_label=" %"
@@ -430,7 +430,7 @@
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
- <stat_bar name="packet_loss"
+ <stat_bar name="ui_frame_pct"
label="UI"
orientation="horizontal"
unit_label=" %"
@@ -438,7 +438,7 @@
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
- <stat_bar name="packet_loss"
+ <stat_bar name="huds_frame_pct"
label="HUDs"
orientation="horizontal"
unit_label=" %"
@@ -446,7 +446,7 @@
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
- <stat_bar name="packet_loss"
+ <stat_bar name="swap_frame_pct"
label="Swap"
orientation="horizontal"
unit_label=" %"
@@ -454,7 +454,7 @@
bar_max="100"
tick_spacing="0.5"
show_bar="false"/>
- <stat_bar name="packet_loss"
+ <stat_bar name="idle_frame_pct"
label="Tasks"
orientation="horizontal"
unit_label=" %"
diff --git a/indra/newview/skins/default/xui/en/floater_translation_settings.xml b/indra/newview/skins/default/xui/en/floater_translation_settings.xml
index a212ce7889..3f3331b468 100644
--- a/indra/newview/skins/default/xui/en/floater_translation_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_translation_settings.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="310"
+ height="470"
layout="topleft"
name="floater_translation_settings"
help_topic="translation_settings"
@@ -9,11 +9,13 @@
title="CHAT TRANSLATION SETTINGS"
width="485">
- <string name="bing_api_key_not_verified">Bing appID not verified. Please try again.</string>
- <string name="google_api_key_not_verified">Google API key not verified. Please try again.</string>
+ <string name="azure_api_key_not_verified">Azure service identifier not verified. Status: [STATUS]. Please check your settings and try again.</string>
+ <string name="google_api_key_not_verified">Google API key not verified. Status: [STATUS]. Please check your key and try again.</string>
+ <string name="deepl_api_key_not_verified">DeepL Auth Key key not verified. Status: [STATUS]. Please check your key and try again.</string>
- <string name="bing_api_key_verified">Bing appID verified.</string>
+ <string name="azure_api_key_verified">Azure service identifier verified.</string>
<string name="google_api_key_verified">Google API key verified.</string>
+ <string name="deepl_api_key_verified">DeepL API key verified.</string>
<check_box
height="16"
@@ -128,25 +130,86 @@
<radio_group
follows="top|left"
- height="80"
+ height="260"
layout="topleft"
left_delta="10"
name="translation_service_rg"
top_pad="20"
width="320">
<radio_item
- initial_value="bing"
- label="Bing Translator"
+ initial_value="azure"
+ label="Azure Translator"
layout="topleft"
- name="bing" />
+ name="azure" />
<radio_item
initial_value="google"
label="Google Translate"
layout="topleft"
name="google"
- top_pad="55" />
+ top_pad="115" />
+ <radio_item
+ initial_value="deepl"
+ label="DeepL Translator"
+ layout="topleft"
+ name="deepl"
+ top_pad="61" />
</radio_group>
+ <text
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ left="185"
+ length="1"
+ name="google_links_text"
+ top_pad="-262"
+ type="string"
+ width="100">
+ [https://learn.microsoft.com/en-us/azure/cognitive-services/translator/create-translator-resource Setup]
+ </text>
+
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ left="70"
+ name="azure_api_endoint_label"
+ top_pad="8"
+ width="85">
+ Endpoint:
+ </text>
+
+ <combo_box
+ allow_text_entry="true"
+ follows="left|top"
+ name="azure_api_endpoint_combo"
+ height="23"
+ left_pad="10"
+ right="-10"
+ top_delta="-4"
+ max_chars="512"
+ value="https://api.cognitive.microsofttranslator.com"
+ combo_button.scale_image="true">
+ <combo_box.item
+ label="https://api.cognitive.microsofttranslator.com"
+ name="global"
+ value="https://api.cognitive.microsofttranslator.com" />
+ <combo_box.item
+ label="https://api-apc.cognitive.microsofttranslator.com"
+ name="api-apc"
+ value="https://api-apc.cognitive.microsofttranslator.com" />
+ <combo_box.item
+ label="https://api-eur.cognitive.microsofttranslator.com"
+ name="api-eur"
+ value="https://api-eur.cognitive.microsofttranslator.com" />
+ <combo_box.item
+ label="https://api-nam.cognitive.microsofttranslator.com"
+ name="api-nam"
+ value="https://api-nam.cognitive.microsofttranslator.com" />
+ </combo_box>
+
<text
type="string"
length="1"
@@ -154,30 +217,52 @@
height="20"
layout="topleft"
left="70"
- name="bing_api_key_label"
- top_pad="-55"
+ name="azure_api_key_label"
+ top_pad="10"
width="85">
- Bing [http://www.bing.com/developers/createapp.aspx AppID]:
+ Azure Key:
</text>
<line_editor
- default_text="Enter Bing AppID and click &quot;Verify&quot;"
+ default_text="Enter Translator Key and click &quot;Verify&quot;"
follows="top|left"
height="20"
layout="topleft"
left_pad="10"
max_length_chars="50"
top_delta="-4"
- name="bing_api_key"
+ name="azure_api_key"
width="210" />
- <button
- follows="left|top"
- height="23"
- label="Verify"
- layout="topleft"
- left_pad="10"
- name="verify_bing_api_key_btn"
- top_delta="-2"
- width="90" />
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ left="70"
+ name="azure_api_region_label"
+ top_pad="11"
+ width="85">
+ Region:
+ </text>
+ <line_editor
+ default_text="Can be left empty for global services"
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ max_length_chars="50"
+ top_delta="-4"
+ name="azure_api_region"
+ width="210" />
+ <button
+ follows="left|top"
+ height="23"
+ label="Verify"
+ layout="topleft"
+ left_pad="10"
+ name="verify_azure_api_key_btn"
+ top_delta="-2"
+ width="90" />
<text
follows="top|right"
@@ -186,7 +271,7 @@
left="70"
length="1"
name="google_api_key_label"
- top_pad="50"
+ top_pad="53"
type="string"
width="85">
Google [http://code.google.com/apis/language/translate/v2/getting_started.html#auth API key]:
@@ -209,7 +294,7 @@
left_pad="10"
name="verify_google_api_key_btn"
top_delta="-2"
- width="90" />
+ width="90" />
<text
follows="top|right"
@@ -224,6 +309,87 @@
[http://code.google.com/apis/language/translate/v2/pricing.html Pricing] | [https://code.google.com/apis/console Stats]
</text>
+ <text
+ type="string"
+ length="1"
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ left="70"
+ name="deepl_api_domain_label"
+ top_pad="80"
+ width="85">
+ Endpoint:
+ </text>
+
+ <combo_box
+ allow_text_entry="false"
+ follows="left|top"
+ name="deepl_api_domain_combo"
+ height="23"
+ left_pad="10"
+ width="140"
+ top_delta="-4"
+ max_chars="512"
+ value="https://api-free.deepl.com"
+ combo_button.scale_image="true">
+ <combo_box.item
+ label="DeepL Free"
+ name="global"
+ value="https://api-free.deepl.com" />
+ <combo_box.item
+ label="DeepL Pro"
+ name="api-apc"
+ value="https://api.deepl.com" />
+ </combo_box>
+
+ <text
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ left="70"
+ length="1"
+ name="deepl_api_key_label"
+ top_pad="11"
+ type="string"
+ width="85">
+ DeepL API key:
+ </text>
+
+ <line_editor
+ default_text="Enter DeepL API key and click &quot;Verify&quot;"
+ follows="top|left"
+ height="20"
+ layout="topleft"
+ left_pad="10"
+ max_length_chars="50"
+ top_delta="-4"
+ name="deepl_api_key"
+ width="210" />
+
+ <button
+ follows="left|top"
+ height="23"
+ label="Verify"
+ layout="topleft"
+ left_pad="10"
+ name="verify_deepl_api_key_btn"
+ top_delta="-2"
+ width="90" />
+
+ <text
+ follows="top|right"
+ height="20"
+ layout="topleft"
+ left="185"
+ length="1"
+ name="deepl_links_text"
+ top_delta="-53"
+ type="string"
+ width="100">
+ [https://www.deepl.com/pro/select-country?cta=header-prices Pricing]
+ </text>
+
<button
follows="left|top"
height="23"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 4949075f2d..d3a31f16ec 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6370,6 +6370,14 @@ Your trash is overflowing. This may cause problems logging in.
</notification>
<notification
+ icon="notifytip.tga"
+ name="InventoryLimitReachedAIS"
+ type="notifytip">
+Your inventory is experiencing issues. Please, contact support.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
icon="alertmodal.tga"
name="ConfirmClearBrowserCache"
type="alertmodal">
@@ -9213,6 +9221,26 @@ Paste failed. [REASON]
<notification
icon="alertmodal.tga"
+ name="FailedToApplyTextureNoCopyToMultiple"
+ type="alertmodal">
+Failed to apply texture. You can not apply a no-copy texture to multiple objects.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FailedToApplyGLTFNoCopyToMultiple"
+ type="alertmodal">
+Failed to apply GLTF material. You can not apply a no-copy material to multiple objects.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="FacePasteTexturePermissions"
type="alertmodal">
You applied a texture with limited permissions, object will inherit permissions from texture.
@@ -12078,13 +12106,6 @@ Would you like to save them first?
yestext="Yes"/>
</notification>
-<notification
- icon="notifytip.tga"
- name="MaterialCreated"
- type="notifytip">
-Material successfully created. Asset ID: [ASSET_ID]
-</notification>
-
<notification
icon="notifytip.tga"
name="ReflectionProbeApplied"
@@ -12097,5 +12118,17 @@ Material successfully created. Asset ID: [ASSET_ID]
notext="Cancel"
yestext="OK"/>
</notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="AutoAdjustHDRSky"
+ persist="true"
+ type="alertmodal">
+ You are editing a non-HDR sky that has been automatically converted to HDR. To remove HDR and tone mapping, set Reflection Probe Ambiance to zero.
+ <usetemplate
+ ignoretext="HDR Sky adjustment warning"
+ name="okignore"
+ yestext="OK"/>
+ </notification>
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
index 777b37d666..07cdd6d71e 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_secondlife.xml
@@ -27,6 +27,26 @@
Account: [ACCTTYPE]
[PAYMENTINFO]
</string>
+
+ <!--Badges-->
+ <string
+ name="BadgeBeta"
+ value="Original Beta Tester" />
+ <string
+ name="BadgeBetaLifetime"
+ value="Beta Lifetime member" />
+ <string
+ name="BadgeLifetime"
+ value="Lifetime member" />
+ <string
+ name="BadgeLinden"
+ value="Linden Lab employee" />
+ <string
+ name="BadgePremiumLifetime"
+ value="Premium lifetime" />
+ <string
+ name="BadgePremiumPlusLifetime"
+ value="Premium Plus lifetime" />
<layout_stack
name="image_stack"
@@ -156,9 +176,39 @@ Account: [ACCTTYPE]
user_resize="false"
visible="true">
</layout_panel>
-
+
+ <layout_panel
+ name="badge_layout"
+ follows="all"
+ layout="topleft"
+ height="40"
+ auto_resize="false"
+ user_resize="false"
+ visible="false">
+ <icon
+ name="badge_icon"
+ image_name="Beta_Tester"
+ layout="topleft"
+ follows="left|top"
+ top="10"
+ left="5"
+ height="18"
+ width="18"/>
+ <text
+ name="badge_text"
+ value="Badge Tester"
+ top="13"
+ left_pad="3"
+ right="-1"
+ height="16"
+ follows="left|top|right"
+ layout="topleft"
+ translate="false"
+ visible="true"/>
+ </layout_panel>
+
<layout_panel
- name="frind_layout"
+ name="friend_layout"
follows="all"
layout="topleft"
height="16"
@@ -166,7 +216,7 @@ Account: [ACCTTYPE]
user_resize="false"
visible="false">
<text
- name="frind_text"
+ name="friend_text"
value="You are friends"
text_color="ConversationFriendColor"
top="0"
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_hair.xml b/indra/newview/skins/default/xui/pt/panel_edit_hair.xml
index 13f1f892f9..e9750a1c2e 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_hair.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_hair.xml
@@ -7,7 +7,7 @@
<accordion name="wearable_accordion">
<accordion_tab name="hair_color_tab" title="Cor"/>
<accordion_tab name="hair_style_tab" title="Estilo"/>
- <accordion_tab name="hair_eyebrows_tab" title="Sombrancelhas"/>
+ <accordion_tab name="hair_eyebrows_tab" title="Sobrancelhas"/>
<accordion_tab name="hair_facial_tab" title="Faciais"/>
</accordion>
</panel>