diff options
| author | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2023-07-17 15:06:23 -0700 | 
|---|---|---|
| committer | Jonathan "Geenz" Goodman <geenz@geenzo.com> | 2023-07-17 15:06:23 -0700 | 
| commit | 040050af19ff7b5b2f5dc5ce5c4b68cfbb7e492a (patch) | |
| tree | fcde4fb3af978615315f83204e6d7351f3b5f02c | |
| parent | f7f9601567ce089f3335407f1d3c7d32dbb18c60 (diff) | |
| parent | f975cfd7361729195f2bb14d874e5eacc6140759 (diff) | |
Merge branch 'DRTVWR-559' into DRTVWR-583
128 files changed, 2414 insertions, 1078 deletions
| diff --git a/doc/contributions.txt b/doc/contributions.txt index c335628391..bebe715e87 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -1188,6 +1188,7 @@ PanteraPolnocy  	SL-18891  	SL-18904  	SL-18937 +	SL-19681  Parvati Silverweb  Patric Mills  	VWR-2645 @@ -1413,6 +1414,7 @@ Sovereign Engineer      SL-18525      SL-18534      SL-19690 +    SL-19336  SpacedOut Frye  	VWR-34  	VWR-45 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 ¶ms, 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, "
", ""); // 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, "
", ""); // 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 ¶ms_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 ¶ms_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.pngBinary files differ new file mode 100644 index 0000000000..7c8a723c47 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_badge_beta.png 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.pngBinary files differ new file mode 100644 index 0000000000..7c38e9e2ae --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_badge_beta_lifetime.png diff --git a/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png b/indra/newview/skins/default/textures/icons/profile_badge_lifetime.pngBinary files differ new file mode 100644 index 0000000000..475edd080e --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_badge_lifetime.png diff --git a/indra/newview/skins/default/textures/icons/profile_badge_linden.png b/indra/newview/skins/default/textures/icons/profile_badge_linden.pngBinary files differ new file mode 100644 index 0000000000..1b6ac03e86 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_badge_linden.png 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.pngBinary files differ new file mode 100644 index 0000000000..4286995202 --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_badge_pplus_lifetime.png 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.pngBinary files differ new file mode 100644 index 0000000000..47e93c4fac --- /dev/null +++ b/indra/newview/skins/default/textures/icons/profile_badge_premium_lifetime.png 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 "Verify"" +  default_text="Enter Translator Key and click "Verify""    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 "Verify"" +     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> | 
