diff --git a/.hgtags b/.hgtags index 4cc1302aac..d32bea3d9f 100755 --- a/.hgtags +++ b/.hgtags @@ -588,3 +588,4 @@ ac3b1332ad4f55b7182a8cbcc1254535a0069f75 5.1.7-release a3143db58a0f6b005232bf9018e7fef17ff9ec90 6.1.0-release 50f0ece62ddb5a244ecb6d00ef5a89d80ad50efa 6.1.1-release 82a89165e5929a6c3073d6cd60a543cb395f147b 6.2.0-release +706bdc7e25c6e6b8fb56f4a13fcce2936e70a79c 6.2.1-release diff --git a/autobuild.xml b/autobuild.xml index d91bd02b7d..1963daeb53 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -52,9 +52,9 @@ archive hash - 08358023ceab8b055af5c3594b3dcc2c + 68f6096e055e7a0e46913e1c2613b9db url - http://downloads.phoenixviewer.com/dullahan_gcc5-1.1.1320_3.3626.1895.g7001d56-linux64-190811112.tar.bz2 + http://downloads.phoenixviewer.com/dullahan_gcc5-1.1.1320_3.3626.1895.g7001d56-linux64-191221945.tar.bz2 name linux64 @@ -838,9 +838,9 @@ archive hash - 607f824220ac11cdc7ae9b5297f5f57a + 48d316c0ceb898f7577015df75b6d303 url - http://downloads.phoenixviewer.com/dullahan-1.1.1320_3.3626.1895.g7001d56-linux64-190811046.tar.bz2 + http://downloads.phoenixviewer.com/dullahan-1.1.1320_3.3626.1895.g7001d56-linux64-191221910.tar.bz2 name linux64 diff --git a/doc/contributions.txt b/doc/contributions.txt index 170e3a6205..cb5726b680 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -260,6 +260,8 @@ Benja Kepler VWR-746 Benjamin Bigdipper Beth Walcher +Beq Janus + SL-10288 Bezilon Kasei Biancaluce Robbiani CT-225 @@ -378,6 +380,7 @@ Cinder Roxley STORM-2127 STORM-2136 STORM-2144 + SL-3404 Clara Young Coaldust Numbers VWR-1095 @@ -793,6 +796,7 @@ Jonathan Yap STORM-2100 STORM-2104 STORM-2142 + SL-10089 Kadah Coba STORM-1060 STORM-1843 @@ -1083,7 +1087,9 @@ Nicky Dasmijn STORM-2010 STORM-2082 MAINT-6665 - SL-11072 + SL-10291 + SL-10293 + SL-11072 Nicky Perian OPEN-1 STORM-1087 diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index fd2ae8df2b..c8c13d291e 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -35,6 +35,7 @@ set(llcommon_SOURCE_FILES llapp.cpp llapr.cpp llassettype.cpp + llatomic.cpp llbase32.cpp llbase64.cpp llbitpack.cpp @@ -135,6 +136,7 @@ set(llcommon_HEADER_FILES llapp.h llapr.h llassettype.h + llatomic.h llbase32.h llbase64.h llbitpack.h diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h index 1fbc536be2..6d446743f5 100644 --- a/indra/llcommon/indra_constants.h +++ b/indra/llcommon/indra_constants.h @@ -157,7 +157,6 @@ const U8 SIM_ACCESS_DOWN = 254; const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT; // attachment constants -const S32 MAX_AGENT_ATTACHMENTS = 38; const U8 ATTACHMENT_ADD = 0x80; // god levels diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 94f07c7e78..be0550b0a9 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -78,9 +78,7 @@ void setup_signals(); void default_unix_signal_handler(int signum, siginfo_t *info, void *); #if LL_LINUX - #include "google_breakpad/minidump_descriptor.h" - static bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded); diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h index c3c1785841..3aa6934c44 100644 --- a/indra/llcommon/llapp.h +++ b/indra/llcommon/llapp.h @@ -32,7 +32,6 @@ #include "llsd.h" #include // Forward declarations - class LLErrorThread; class LLLiveFile; #if LL_LINUX diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index 0426453b69..f78e031f97 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -28,6 +28,7 @@ #include "linden_common.h" #include "llapr.h" +#include "llmutex.h" #include "apr_dso.h" #include "llthreadlocalstorage.h" @@ -44,10 +45,14 @@ void ll_init_apr() apr_initialize(); if (!gAPRPoolp) + { apr_pool_create(&gAPRPoolp, NULL); + } if(!LLAPRFile::sAPRFilePoolp) + { LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; + } LLThreadLocalPointerBase::initAllThreadLocalStorage(); gAPRInitialized = true; @@ -65,9 +70,6 @@ void ll_cleanup_apr() LL_INFOS("APR") << "Cleaning up APR" << LL_ENDL; - // Clean up the logging mutex - // All other threads NEED to be done before we clean up APR, so this is okay. - LLThreadLocalPointerBase::destroyAllThreadLocalStorage(); if (gAPRPoolp) @@ -144,9 +146,7 @@ apr_pool_t* LLAPRPool::getAPRPool() LLVolatileAPRPool::LLVolatileAPRPool(BOOL is_local, apr_pool_t *parent, apr_size_t size, BOOL releasePoolFlag) : LLAPRPool(parent, size, releasePoolFlag), mNumActiveRef(0), - mNumTotalRef(0), - mMutexPool(NULL), - mMutexp(NULL) + mNumTotalRef(0) { //create mutex @@ -161,15 +161,14 @@ LLVolatileAPRPool::LLVolatileAPRPool(BOOL is_local, apr_pool_t *parent, apr_size // { - apr_pool_create(&mMutexPool, NULL); // Create a pool for mutex - mMutexp = new std::mutex(); + mMutexp.reset(new std::mutex()); } } LLVolatileAPRPool::~LLVolatileAPRPool() { - delete mMutexp; - mMutexp = nullptr; + //delete mutex + mMutexp.reset(); } // @@ -183,7 +182,7 @@ apr_pool_t* LLVolatileAPRPool::getAPRPool() apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool() { - LLScopedLock lock(mMutexp) ; + LLScopedLock lock(mMutexp.get()) ; mNumTotalRef++ ; mNumActiveRef++ ; @@ -198,7 +197,7 @@ apr_pool_t* LLVolatileAPRPool::getVolatileAPRPool() void LLVolatileAPRPool::clearVolatileAPRPool() { - LLScopedLock lock(mMutexp) ; + LLScopedLock lock(mMutexp.get()); if(mNumActiveRef > 0) { @@ -232,36 +231,6 @@ BOOL LLVolatileAPRPool::isFull() { return mNumTotalRef > FULL_VOLATILE_APR_POOL ; } -//--------------------------------------------------------------------- -// -// LLScopedLock -// -LLScopedLock::LLScopedLock(std::mutex* mutex) : mMutex(mutex) -{ - if(mutex) - { - mutex->lock(); - mLocked = true; - } - else - { - mLocked = false; - } -} - -LLScopedLock::~LLScopedLock() -{ - unlock(); -} - -void LLScopedLock::unlock() -{ - if(mLocked) - { - mMutex->unlock(); - mLocked = false; - } -} //--------------------------------------------------------------------- diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h index fcff88d5a8..da92b36212 100644 --- a/indra/llcommon/llapr.h +++ b/indra/llcommon/llapr.h @@ -36,23 +36,23 @@ #include #include "llwin32headerslean.h" #include "apr_thread_proc.h" - #include "apr_getopt.h" #include "apr_signal.h" -#include + +#include "llstring.h" #if LL_WINDOWS -#pragma warning(disable:4265) +#pragma warning (push) +#pragma warning (disable:4265) #endif +// warning C4265: 'std::_Pad' : class has virtual functions, but destructor is not virtual #include #if LL_WINDOWS -#pragma warning(default:4265) +#pragma warning (pop) #endif -#include "llstring.h" - struct apr_dso_handle_t; /** * @brief Function which appropriately logs error or remains quiet on @@ -127,85 +127,9 @@ private: S32 mNumActiveRef ; //number of active pointers pointing to the apr_pool. S32 mNumTotalRef ; //number of total pointers pointing to the apr_pool since last creating. - std::mutex *mMutexp; - apr_pool_t *mMutexPool; + std::unique_ptr mMutexp; } ; -/** - * @class LLScopedLock - * @brief Small class to help lock and unlock mutexes. - * - * This class is used to have a stack level lock once you already have - * an apr mutex handy. The constructor handles the lock, and the - * destructor handles the unlock. Instances of this class are - * not thread safe. - */ -class LL_COMMON_API LLScopedLock : private boost::noncopyable -{ -public: - /** - * @brief Constructor which accepts a mutex, and locks it. - * - * @param mutex An allocated APR mutex. If you pass in NULL, - * this wrapper will not lock. - */ - LLScopedLock( std::mutex* mutex ); - - /** - * @brief Destructor which unlocks the mutex if still locked. - */ - ~LLScopedLock(); - - /** - * @brief Check lock. - */ - bool isLocked() const { return mLocked; } - - /** - * @brief This method unlocks the mutex. - */ - void unlock(); - -protected: - bool mLocked; - std::mutex* mMutex; -}; - -template > class LLAtomicBase -{ -public: - LLAtomicBase() {}; - LLAtomicBase( Type x ) { mData.store( x ); }; - ~LLAtomicBase() {}; - - operator const Type() { return mData; } - - Type CurrentValue() const { return mData; } - - Type operator =( Type x) { mData.store( x ); return mData; } - void operator -=(Type x) { mData -= x; } - void operator +=(Type x) { mData += x; } - Type operator ++(int) { return mData++; } - Type operator --(int) { return mData--; } - - Type operator ++() { return ++mData; } - Type operator --() { return --mData; } - -private: - AtomicType mData; -}; - -// ND: Typedefs for specialized versions. Using std::atomic_(u)int32_t to get the optimzed implementation. -#ifdef LL_WINDOWS -typedef LLAtomicBase LLAtomicU32; -typedef LLAtomicBase LLAtomicS32; -#else -typedef LLAtomicBase LLAtomicU32; -typedef LLAtomicBase LLAtomicS32; -#endif - -typedef LLAtomicBase LLAtomicBool; - // File IO convenience functions. // Returns NULL if the file fails to open, sets *sizep to file size if not NULL // abbreviated flags diff --git a/indra/llcommon/llatomic.cpp b/indra/llcommon/llatomic.cpp new file mode 100644 index 0000000000..1b344df400 --- /dev/null +++ b/indra/llcommon/llatomic.cpp @@ -0,0 +1,29 @@ +/** + * @file llatomic.cpp + * + * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2018, 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$ + */ + +// Fix LNK4221 compiler warning +//#include "llatomic.h" + +//============================================================================ diff --git a/indra/llcommon/llatomic.h b/indra/llcommon/llatomic.h new file mode 100644 index 0000000000..8de773846c --- /dev/null +++ b/indra/llcommon/llatomic.h @@ -0,0 +1,69 @@ +/** + * @file llatomic.h + * @brief Base classes for atomic. + * + * $LicenseInfo:firstyear=2018&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2018, 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_LLATOMIC_H +#define LL_LLATOMIC_H + +#include "stdtypes.h" + +#include + +template > class LLAtomicBase +{ +public: + LLAtomicBase() {}; + LLAtomicBase(Type x) { mData.store(x); } + ~LLAtomicBase() {}; + + operator const Type() { return mData; } + + Type CurrentValue() const { return mData; } + + Type operator =(const Type& x) { mData.store(x); return mData; } + void operator -=(Type x) { mData -= x; } + void operator +=(Type x) { mData += x; } + Type operator ++(int) { return mData++; } + Type operator --(int) { return mData--; } + + Type operator ++() { return ++mData; } + Type operator --() { return --mData; } + +private: + AtomicType mData; +}; + +// Typedefs for specialized versions. Using std::atomic_(u)int32_t to get the optimzed implementation. +#ifdef LL_WINDOWS +typedef LLAtomicBase LLAtomicU32; +typedef LLAtomicBase LLAtomicS32; +#else +typedef LLAtomicBase LLAtomicU32; +typedef LLAtomicBase LLAtomicS32; +#endif + +typedef LLAtomicBase LLAtomicBool; + +#endif // LL_LLATOMIC_H diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 487ab7fc4f..8b747791c4 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -56,9 +56,6 @@ #include "nd/ndlogthrottle.h" namespace { - LLMutex gLogMutex; - LLMutex gCallStacksLogMutex ; - #if LL_WINDOWS void debugger_print(const std::string& s) { @@ -1190,6 +1187,9 @@ namespace } namespace { + LLMutex gLogMutex; + LLMutex gCallStacksLogMutex; + bool checkLevelMap(const LevelMap& map, const std::string& key, LLError::ELevel& level) { @@ -1241,8 +1241,8 @@ namespace LLError bool Log::shouldLog(CallSite& site) { - LLMutexTrylock lock( &gLogMutex,5); - if (!lock.isLocked() ) + LLMutexTrylock lock(&gLogMutex, 5); + if (!lock.isLocked()) { return false; } @@ -1527,69 +1527,6 @@ namespace LLError char** LLCallStacks::sBuffer = NULL ; S32 LLCallStacks::sIndex = 0 ; -#define SINGLE_THREADED 1 - - class CallStacksLogLock - { - public: - CallStacksLogLock(); - ~CallStacksLogLock(); - -#if SINGLE_THREADED - bool ok() const { return true; } -#else - bool ok() const { return mOK; } - private: - bool mLocked; - bool mOK; -#endif - }; - -#if SINGLE_THREADED - CallStacksLogLock::CallStacksLogLock() - { - } - CallStacksLogLock::~CallStacksLogLock() - { - } -#else - CallStacksLogLock::CallStacksLogLock() - : mLocked(false), mOK(false) - { - if (!gCallStacksLogMutexp) - { - mOK = true; - return; - } - - const int MAX_RETRIES = 5; - for (int attempts = 0; attempts < MAX_RETRIES; ++attempts) - { - apr_status_t s = apr_thread_mutex_trylock(gCallStacksLogMutexp); - if (!APR_STATUS_IS_EBUSY(s)) - { - mLocked = true; - mOK = true; - return; - } - - ms_sleep(1); - } - - // We're hosed, we can't get the mutex. Blah. - std::cerr << "CallStacksLogLock::CallStacksLogLock: failed to get mutex for log" - << std::endl; - } - - CallStacksLogLock::~CallStacksLogLock() - { - if (mLocked) - { - apr_thread_mutex_unlock(gCallStacksLogMutexp); - } - } -#endif - //static void LLCallStacks::allocateStackBuffer() { @@ -1618,8 +1555,8 @@ namespace LLError //static void LLCallStacks::push(const char* function, const int line) { - CallStacksLogLock lock; - if (!lock.ok()) + LLMutexTrylock lock(&gCallStacksLogMutex, 5); + if (!lock.isLocked()) { return; } @@ -1653,8 +1590,8 @@ namespace LLError //static void LLCallStacks::end(std::ostringstream* _out) { - CallStacksLogLock lock; - if (!lock.ok()) + LLMutexTrylock lock(&gCallStacksLogMutex, 5); + if (!lock.isLocked()) { return; } @@ -1675,8 +1612,8 @@ namespace LLError //static void LLCallStacks::print() { - CallStacksLogLock lock; - if (!lock.ok()) + LLMutexTrylock lock(&gCallStacksLogMutex, 5); + if (!lock.isLocked()) { return; } @@ -1713,7 +1650,7 @@ namespace LLError bool debugLoggingEnabled(const std::string& tag) { - LLMutexTrylock lock(&gLogMutex,5); + LLMutexTrylock lock(&gLogMutex, 5); if (!lock.isLocked()) { return false; diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp index b65348d273..c60ffac5b9 100644 --- a/indra/llcommon/llfasttimer.cpp +++ b/indra/llcommon/llfasttimer.cpp @@ -72,7 +72,6 @@ bool BlockTimer::sMetricLog = false; #endif #if LL_LINUX || LL_SOLARIS || LL_DARWIN // AO: Add LL_DARWIN to this list now U64 BlockTimer::sClockResolution = 1000000000; // Nanosecond resolution - #else U64 BlockTimer::sClockResolution = 1000000; // Microsecond resolution #endif diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h index e821a60d8f..1a7a3fdb5a 100644 --- a/indra/llcommon/llfasttimer.h +++ b/indra/llcommon/llfasttimer.h @@ -35,6 +35,7 @@ #define LL_FASTTIMER_USE_RDTSC 1 #define LL_RECORD_BLOCK_TIME(timer_stat) const LLTrace::BlockTimer& LL_GLUE_TOKENS(block_time_recorder, __LINE__)(LLTrace::timeThisBlock(timer_stat)); (void)LL_GLUE_TOKENS(block_time_recorder, __LINE__); + namespace LLTrace { // use to create blocktimer rvalue to be captured in a reference so that the BlockTimer lives to the end of the block. diff --git a/indra/llcommon/llfixedbuffer.cpp b/indra/llcommon/llfixedbuffer.cpp index 4b5cdbe288..bd4db8be84 100644 --- a/indra/llcommon/llfixedbuffer.cpp +++ b/indra/llcommon/llfixedbuffer.cpp @@ -30,7 +30,8 @@ LLFixedBuffer::LLFixedBuffer(const U32 max_lines) : LLLineBuffer(), - mMaxLines(max_lines) + mMaxLines(max_lines), + mMutex() { mTimer.reset(); } diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 00c559a166..11e5b804f7 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -28,6 +28,7 @@ #ifndef LL_LLINSTANCETRACKER_H #define LL_LLINSTANCETRACKER_H +#include #include #include @@ -120,12 +121,12 @@ protected: void decrementDepth(); U32 getDepth(); private: - #ifdef LL_WINDOWS +#ifdef LL_WINDOWS std::atomic_uint32_t sIterationNestDepth; - #else +#else std::atomic_uint sIterationNestDepth; - #endif - }; +#endif + }; }; LL_COMMON_API void assert_main_thread(); diff --git a/indra/llcommon/llmutex.cpp b/indra/llcommon/llmutex.cpp index 7457204aa3..75f43a4704 100644 --- a/indra/llcommon/llmutex.cpp +++ b/indra/llcommon/llmutex.cpp @@ -24,27 +24,22 @@ */ #include "linden_common.h" -#include "llapr.h" - -#include "apr_portable.h" #include "llmutex.h" #include "llthread.h" +#include "lltimer.h" //============================================================================ LLMutex::LLMutex() : - mCount(0), mLockingThread(NO_THREAD) + mCount(0), + mLockingThread(NO_THREAD) { } LLMutex::~LLMutex() { -#if MUTEX_DEBUG - //bad assertion, the subclass LLSignal might be "locked", and that's OK - //llassert_always(!isLocked()); // better not be locked! -#endif } @@ -92,7 +87,9 @@ void LLMutex::unlock() bool LLMutex::isLocked() { if (!mMutex.try_lock()) + { return true; + } else { mMutex.unlock(); @@ -119,8 +116,10 @@ bool LLMutex::trylock() } if (!mMutex.try_lock()) + { return false; - + } + #if MUTEX_DEBUG // Have to have the lock before we can access the debug info U32 id = LLThread::currentID(); @@ -135,23 +134,26 @@ bool LLMutex::trylock() //============================================================================ -LLCondition::LLCondition() +LLCondition::LLCondition() : + LLMutex() { } + LLCondition::~LLCondition() { } + void LLCondition::wait() { - std::unique_lock< std::mutex > lock( mMutex ); - mCond.wait( lock ); + std::unique_lock< std::mutex > lock(mMutex); + mCond.wait(lock); } void LLCondition::signal() { - mCond.notify_one() ; + mCond.notify_one(); } void LLCondition::broadcast() @@ -160,4 +162,67 @@ void LLCondition::broadcast() } + +LLMutexTrylock::LLMutexTrylock(LLMutex* mutex) + : mMutex(mutex), + mLocked(false) +{ + if (mMutex) + mLocked = mMutex->trylock(); +} + +LLMutexTrylock::LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms) + : mMutex(mutex), + mLocked(false) +{ + if (!mMutex) + return; + + for (U32 i = 0; i < aTries; ++i) + { + mLocked = mMutex->trylock(); + if (mLocked) + break; + ms_sleep(delay_ms); + } +} + +LLMutexTrylock::~LLMutexTrylock() +{ + if (mMutex && mLocked) + mMutex->unlock(); +} + + +//--------------------------------------------------------------------- +// +// LLScopedLock +// +LLScopedLock::LLScopedLock(std::mutex* mutex) : mMutex(mutex) +{ + if(mutex) + { + mutex->lock(); + mLocked = true; + } + else + { + mLocked = false; + } +} + +LLScopedLock::~LLScopedLock() +{ + unlock(); +} + +void LLScopedLock::unlock() +{ + if(mLocked) + { + mMutex->unlock(); + mLocked = false; + } +} + //============================================================================ diff --git a/indra/llcommon/llmutex.h b/indra/llcommon/llmutex.h index 0cdf33e62f..f841d7f950 100644 --- a/indra/llcommon/llmutex.h +++ b/indra/llcommon/llmutex.h @@ -28,18 +28,20 @@ #define LL_LLMUTEX_H #include "stdtypes.h" -#include "lltimer.h" +#include #if LL_WINDOWS -#pragma warning(disable:4265) +#pragma warning (push) +#pragma warning (disable:4265) #endif - +// 'std::_Pad' : class has virtual functions, but destructor is not virtual #include #include #if LL_WINDOWS -#pragma warning(default:4265) +#pragma warning (pop) #endif + //============================================================================ #define MUTEX_DEBUG (LL_DEBUG || LL_RELEASE_WITH_DEBUG_INFO) @@ -48,7 +50,6 @@ #include #endif - class LL_COMMON_API LLMutex { public: @@ -57,7 +58,7 @@ public: NO_THREAD = 0xFFFFFFFF } e_locking_thread; - LLMutex(); // NULL pool constructs a new pool for the mutex + LLMutex(); virtual ~LLMutex(); void lock(); // blocks @@ -68,12 +69,10 @@ public: U32 lockingThread() const; //get ID of locking thread protected: - std::mutex mMutex; + std::mutex mMutex; mutable U32 mCount; mutable U32 mLockingThread; - bool mIsLocalPool; - #if MUTEX_DEBUG std::map mIsLocked; #endif @@ -83,7 +82,7 @@ protected: class LL_COMMON_API LLCondition : public LLMutex { public: - LLCondition(); // Defaults to global pool, could use the thread pool as well. + LLCondition(); ~LLCondition(); void wait(); // blocks @@ -126,36 +125,9 @@ private: class LLMutexTrylock { public: - LLMutexTrylock(LLMutex* mutex) - : mMutex(mutex), - mLocked(false) - { - if (mMutex) - mLocked = mMutex->trylock(); - } - LLMutexTrylock( LLMutex* mutex, U32 aTries ) - : mMutex( mutex ), - mLocked( false ) - { - if( !mMutex ) - return; - - U32 i = 0; - while( i < aTries ) - { - mLocked = mMutex->trylock(); - if( mLocked ) - break; - ++i; - ms_sleep( 10 ); - } - } - - ~LLMutexTrylock() - { - if (mMutex && mLocked) - mMutex->unlock(); - } + LLMutexTrylock(LLMutex* mutex); + LLMutexTrylock(LLMutex* mutex, U32 aTries, U32 delay_ms = 10); + ~LLMutexTrylock(); bool isLocked() const { @@ -166,4 +138,43 @@ private: LLMutex* mMutex; bool mLocked; }; -#endif // LL_LLTHREAD_H + +/** +* @class LLScopedLock +* @brief Small class to help lock and unlock mutexes. +* +* The constructor handles the lock, and the destructor handles +* the unlock. Instances of this class are not thread safe. +*/ +class LL_COMMON_API LLScopedLock : private boost::noncopyable +{ +public: + /** + * @brief Constructor which accepts a mutex, and locks it. + * + * @param mutex An allocated mutex. If you pass in NULL, + * this wrapper will not lock. + */ + LLScopedLock(std::mutex* mutex); + + /** + * @brief Destructor which unlocks the mutex if still locked. + */ + ~LLScopedLock(); + + /** + * @brief Check lock. + */ + bool isLocked() const { return mLocked; } + + /** + * @brief This method unlocks the mutex. + */ + void unlock(); + +protected: + bool mLocked; + std::mutex* mMutex; +}; + +#endif // LL_LLMUTEX_H diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 8684ff4a87..e953451d49 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -36,10 +36,10 @@ LLQueuedThread::LLQueuedThread(const std::string& name, bool threaded, bool should_pause) : LLThread(name), mThreaded(threaded), + mIdleThread(true), mNextHandle(0), mStarted(FALSE) { - mIdleThread = true; if (mThreaded) { if(should_pause) diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index 3235265e69..5d3f873646 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -32,7 +32,7 @@ #include #include -#include "llapr.h" +#include "llatomic.h" #include "llthread.h" #include "llsimplehash.h" diff --git a/indra/llcommon/llrefcount.cpp b/indra/llcommon/llrefcount.cpp index a638df2c7c..29a5ca6f24 100644 --- a/indra/llcommon/llrefcount.cpp +++ b/indra/llcommon/llrefcount.cpp @@ -29,25 +29,9 @@ #include "llerror.h" -#if LL_REF_COUNT_DEBUG -#include "llthread.h" -#include "llapr.h" -#endif - LLRefCount::LLRefCount(const LLRefCount& other) : mRef(0) { -#if LL_REF_COUNT_DEBUG - if(gAPRPoolp) - { - mMutexp = new LLMutex(gAPRPoolp) ; - } - else - { - mMutexp = NULL ; - } - mCrashAtUnlock = FALSE ; -#endif } LLRefCount& LLRefCount::operator=(const LLRefCount&) @@ -59,17 +43,6 @@ LLRefCount& LLRefCount::operator=(const LLRefCount&) LLRefCount::LLRefCount() : mRef(0) { -#if LL_REF_COUNT_DEBUG - if(gAPRPoolp) - { - mMutexp = new LLMutex(gAPRPoolp) ; - } - else - { - mMutexp = NULL ; - } - mCrashAtUnlock = FALSE ; -#endif } LLRefCount::~LLRefCount() @@ -78,87 +51,5 @@ LLRefCount::~LLRefCount() { LL_ERRS() << "deleting non-zero reference" << LL_ENDL; } - -#if LL_REF_COUNT_DEBUG - if(gAPRPoolp) - { - delete mMutexp ; - } -#endif } -#if LL_REF_COUNT_DEBUG -void LLRefCount::ref() const -{ - if(mMutexp) - { - if(mMutexp->isLocked()) - { - mCrashAtUnlock = TRUE ; - LL_ERRS() << "the mutex is locked by the thread: " << mLockedThreadID - << " Current thread: " << LLThread::currentID() << LL_ENDL ; - } - - mMutexp->lock() ; - mLockedThreadID = LLThread::currentID() ; - - mRef++; - - if(mCrashAtUnlock) - { - while(1); //crash here. - } - mMutexp->unlock() ; - } - else - { - mRef++; - } -} - -S32 LLRefCount::unref() const -{ - if(mMutexp) - { - if(mMutexp->isLocked()) - { - mCrashAtUnlock = TRUE ; - LL_ERRS() << "the mutex is locked by the thread: " << mLockedThreadID - << " Current thread: " << LLThread::currentID() << LL_ENDL ; - } - - mMutexp->lock() ; - mLockedThreadID = LLThread::currentID() ; - - llassert(mRef >= 1); - if (0 == --mRef) - { - if(mCrashAtUnlock) - { - while(1); //crash here. - } - mMutexp->unlock() ; - - delete this; - return 0; - } - - if(mCrashAtUnlock) - { - while(1); //crash here. - } - mMutexp->unlock() ; - return mRef; - } - else - { - llassert(mRef >= 1); - if (0 == --mRef) - { - delete this; - return 0; - } - return mRef; - } -} -#endif diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h index 15f397ecdd..fb0411d27b 100644 --- a/indra/llcommon/llrefcount.h +++ b/indra/llcommon/llrefcount.h @@ -29,12 +29,7 @@ #include #include #include "llmutex.h" -#include "llapr.h" - -#define LL_REF_COUNT_DEBUG 0 -#if LL_REF_COUNT_DEBUG -class LLMutex ; -#endif +#include "llatomic.h" //---------------------------------------------------------------------------- // RefCount objects should generally only be accessed by way of LLPointer<>'s @@ -51,10 +46,6 @@ protected: public: LLRefCount(); -#if LL_REF_COUNT_DEBUG - void ref() const ; - S32 unref() const ; -#else inline void ref() const { mRef++; @@ -69,8 +60,7 @@ public: return 0; } return mRef; - } -#endif + } //NOTE: when passing around a const LLRefCount object, this can return different results // at different types, since mRef is mutable @@ -81,12 +71,6 @@ public: private: mutable S32 mRef; - -#if LL_REF_COUNT_DEBUG - LLMutex* mMutexp ; - mutable uintptr_t mLockedThreadID ; - mutable BOOL mCrashAtUnlock ; -#endif }; @@ -123,8 +107,8 @@ public: void unref() { llassert(mRef >= 1); - if ((--mRef) == 0) // See note in llapr.h on atomic decrement operator return value. - { + if ((--mRef) == 0) + { // If we hit zero, the caller should be the only smart pointer owning the object and we can delete it. // It is technically possible for a vanilla pointer to mess this up, or another thread to // jump in, find this object, create another smart pointer and end up dangling, but if @@ -140,7 +124,7 @@ public: } private: - LLAtomicS32 mRef; + LLAtomicS32 mRef; }; /** diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp index ed799c3ecb..a4171729db 100644 --- a/indra/llcommon/llthread.cpp +++ b/indra/llcommon/llthread.cpp @@ -116,27 +116,27 @@ void LLThread::registerThreadID() // // Handed to the APR thread creation function // -void LLThread::threadRun() +void LLThread::threadRun() { #ifdef LL_WINDOWS - set_thread_name( -1, mName.c_str() ); + set_thread_name(-1, mName.c_str()); #endif // for now, hard code all LLThreads to report to single master thread recorder, which is known to be running on main thread - mRecorder = new LLTrace::ThreadRecorder( *LLTrace::get_master_thread_recorder() ); + mRecorder = new LLTrace::ThreadRecorder(*LLTrace::get_master_thread_recorder()); - sThreadID = mID; + sThreadID = mID; // Run the user supplied function do { try { - run(); + run(); } catch (const LLContinueError &e) { - LL_WARNS( "THREAD" ) << "ContinueException on thread '" << mName << + LL_WARNS("THREAD") << "ContinueException on thread '" << mName << "' reentering run(). Error what is: '" << e.what() << "'" << LL_ENDL; //output possible call stacks to log file. LLError::LLCallStacks::print(); @@ -152,15 +152,13 @@ void LLThread::threadRun() delete mRecorder; - mRecorder = nullptr; + mRecorder = NULL; // We're done with the run function, this thread is done executing now. //NB: we are using this flag to sync across threads...we really need memory barriers here // Todo: add LLMutex per thread instead of flag? // We are using "while (mStatus != STOPPED) {ms_sleep();}" everywhere. mStatus = STOPPED; - - return; } LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : @@ -172,7 +170,6 @@ LLThread::LLThread(const std::string& name, apr_pool_t *poolp) : { mID = ++sIDIter; - mRunCondition = new LLCondition(); mDataLock = new LLMutex(); mLocalAPRFilePoolp = NULL ; @@ -204,7 +201,7 @@ void LLThread::shutdown() // Warning! If you somehow call the thread destructor from itself, // the thread will die in an unclean fashion! - if( mThreadp ) + if (mThreadp) { if (!isStopped()) { @@ -235,16 +232,19 @@ void LLThread::shutdown() { // This thread just wouldn't stop, even though we gave it time //LL_WARNS() << "LLThread::~LLThread() exiting thread before clean exit!" << LL_ENDL; - // Put a stake in its heart. - // ND: There is no such thing as to terminate a std::thread, we detach it so no wait will happen. - // Otherwise craft something platform specific with std::thread::native_handle - mThreadp->detach(); + // Put a stake in its heart. (A very hostile method to force a thread to quit) +#if LL_WINDOWS + TerminateThread(mNativeHandle, 0); +#else + pthread_cancel(mNativeHandle); +#endif + delete mRecorder; mRecorder = NULL; mStatus = STOPPED; return; } - mThreadp = NULL; + mThreadp = NULL; } delete mRunCondition; @@ -252,7 +252,7 @@ void LLThread::shutdown() delete mDataLock; mDataLock = NULL; - + if (mRecorder) { // missed chance to properly shut down recorder (needs to be done in thread context) @@ -270,16 +270,17 @@ void LLThread::start() // Set thread state to running mStatus = RUNNING; - try - { - mThreadp = new std::thread( std::bind( &LLThread::threadRun, this ) ); - //mThreadp->detach(); - } - catch( std::system_error& ex ) - { - mStatus = STOPPED; - LL_WARNS() << "failed to start thread " << mName << " " << ex.what() << LL_ENDL; + try + { + mThreadp = new std::thread(std::bind(&LLThread::threadRun, this)); + mNativeHandle = mThreadp->native_handle(); } + catch (std::system_error& ex) + { + mStatus = STOPPED; + LL_WARNS() << "failed to start thread " << mName << " " << ex.what() << LL_ENDL; + } + } //============================================================================ @@ -354,7 +355,7 @@ U32 LLThread::currentID() // static void LLThread::yield() { - std::this_thread::yield(); + std::this_thread::yield(); } void LLThread::wake() @@ -395,7 +396,7 @@ void LLThreadSafeRefCount::initThreadSafeRefCount() void LLThreadSafeRefCount::cleanupThreadSafeRefCount() { delete sMutex; - sMutex = nullptr; + sMutex = NULL; } diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h index 818b53e4a4..863c9051f3 100644 --- a/indra/llcommon/llthread.h +++ b/indra/llcommon/llthread.h @@ -29,11 +29,9 @@ #include "llapp.h" #include "llapr.h" -#include "apr_thread_cond.h" #include "boost/intrusive_ptr.hpp" #include "llmutex.h" #include "llrefcount.h" - #include LL_COMMON_API void assert_main_thread(); @@ -99,15 +97,17 @@ public: private: bool mPaused; + std::thread::native_handle_type mNativeHandle; // for termination in case of issues - void threadRun( ); + // static function passed to APR thread creation routine + void threadRun(); protected: std::string mName; class LLCondition* mRunCondition; LLMutex* mDataLock; - std::thread *mThreadp; + std::thread *mThreadp; EThreadStatus mStatus; U32 mID; LLTrace::ThreadRecorder* mRecorder; diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp index d0076f2a9a..37f6bbe97e 100644 --- a/indra/llcommon/llthreadsafequeue.cpp +++ b/indra/llcommon/llthreadsafequeue.cpp @@ -26,3 +26,4 @@ //#include "linden_common.h" //#include "llthreadsafequeue.h" + diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index c59a29e3b4..b0bddac8e5 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -28,10 +28,20 @@ #define LL_LLTHREADSAFEQUEUE_H #include "llexception.h" -#include "llmutex.h" -#include "lltimer.h" -#include #include +#include + +#if LL_WINDOWS +#pragma warning (push) +#pragma warning (disable:4265) +#endif +// 'std::_Pad' : class has virtual functions, but destructor is not virtual +#include +#include + +#if LL_WINDOWS +#pragma warning (pop) +#endif // // A general queue exception. @@ -62,8 +72,6 @@ public: } }; - - // // Implements a thread safe FIFO. // @@ -75,7 +83,7 @@ public: // If the pool is set to NULL one will be allocated and managed by this // queue. - LLThreadSafeQueue( U32 capacity = 1024); + LLThreadSafeQueue(U32 capacity = 1024); // Add an element to the front of queue (will block if the queue has // reached capacity). @@ -104,99 +112,102 @@ public: private: std::deque< ElementT > mStorage; - LLCondition mLock;; - U32 mCapacity; // Really needed? + U32 mCapacity; + + std::mutex mLock; + std::condition_variable mCapacityCond; + std::condition_variable mEmptyCond; }; - - // LLThreadSafeQueue //----------------------------------------------------------------------------- - template -LLThreadSafeQueue::LLThreadSafeQueue( U32 capacity): - mCapacity( capacity ) +LLThreadSafeQueue::LLThreadSafeQueue(U32 capacity) : +mCapacity(capacity) { - ; // No op. } template void LLThreadSafeQueue::pushFront(ElementT const & element) { - while( true ) - { - { - LLMutexLock lck( &mLock ); - if( mStorage.size() < mCapacity ) - { - mStorage.push_front( element ); - mLock.signal(); - return; - } - } - ms_sleep( 100 ); - } + while (true) + { + std::unique_lock lock1(mLock); + + if (mStorage.size() < mCapacity) + { + mStorage.push_front(element); + mEmptyCond.notify_one(); + return; + } + + // Storage Full. Wait for signal. + mCapacityCond.wait(lock1); + } } template bool LLThreadSafeQueue::tryPushFront(ElementT const & element) { - LLMutexTrylock lck( &mLock ); - if( !lck.isLocked() ) - return false; + std::unique_lock lock1(mLock, std::defer_lock); + if (!lock1.try_lock()) + return false; - if( mStorage.size() >= mCapacity ) - return false; + if (mStorage.size() >= mCapacity) + return false; - mStorage.push_front( element ); - mLock.signal(); - return true; + mStorage.push_front(element); + mEmptyCond.notify_one(); + return true; } template ElementT LLThreadSafeQueue::popBack(void) { - while( true ) - { - mLock.wait(); - if( !mStorage.empty() ) - { - ElementT value = mStorage.back(); - mStorage.pop_back(); - return value; - } - } + while (true) + { + std::unique_lock lock1(mLock); + + if (!mStorage.empty()) + { + ElementT value = mStorage.back(); + mStorage.pop_back(); + mCapacityCond.notify_one(); + return value; + } + + // Storage empty. Wait for signal. + mEmptyCond.wait(lock1); + } } template bool LLThreadSafeQueue::tryPopBack(ElementT & element) { - LLMutexTrylock lck( &mLock ); + std::unique_lock lock1(mLock, std::defer_lock); + if (!lock1.try_lock()) + return false; - if( !lck.isLocked() ) - return false; - if( mStorage.empty() ) - return false; + if (mStorage.empty()) + return false; - element = mStorage.back(); - mStorage.pop_back(); - return true; + element = mStorage.back(); + mStorage.pop_back(); + mCapacityCond.notify_one(); + return true; } template size_t LLThreadSafeQueue::size(void) { - // Nicky: apr_queue_size is/was NOT threadsafe. I still play it safe here and rather lock the storage - - LLMutexLock lck( &mLock ); - return mStorage.size(); + std::lock_guard lock(mLock); + return mStorage.size(); } - #endif diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index ca37fa14e4..4b91b2caca 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -204,6 +204,7 @@ LLWorkerClass::LLWorkerClass(LLWorkerThread* workerthread, const std::string& na mWorkerClassName(name), mRequestHandle(LLWorkerThread::nullHandle()), mRequestPriority(LLWorkerThread::PRIORITY_NORMAL), + mMutex(), mWorkFlags(0) { if (!mWorkerThread) diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index 09776816a8..b1a6f61360 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -33,7 +33,7 @@ #include #include "llqueuedthread.h" -#include "llapr.h" +#include "llatomic.h" #define USE_FRAME_CALLBACK_MANAGER 0 diff --git a/indra/llcorehttp/_httpoprequest.cpp b/indra/llcorehttp/_httpoprequest.cpp index 557ae1156a..4c0948a90e 100644 --- a/indra/llcorehttp/_httpoprequest.cpp +++ b/indra/llcorehttp/_httpoprequest.cpp @@ -565,6 +565,11 @@ HttpStatus HttpOpRequest::prepareRequest(HttpService * service) // about 700 or so requests and starts issuing TCP RSTs to // new connections. Reuse the DNS lookups for even a few // seconds and no RSTs. + // + // -1 stores forever + // 0 never stores + // any other positive number specifies seconds + // supposedly curl 7.62.0 can use TTL by default, otherwise default is 60 seconds check_curl_easy_setopt(mCurlHandle, CURLOPT_DNS_CACHE_TIMEOUT, dnsCacheTimeout); if (gpolicy.mUseLLProxy) diff --git a/indra/llcorehttp/_httpservice.h b/indra/llcorehttp/_httpservice.h index ac518a5de7..d0c37ac195 100644 --- a/indra/llcorehttp/_httpservice.h +++ b/indra/llcorehttp/_httpservice.h @@ -31,7 +31,7 @@ #include #include "linden_common.h" -#include "llapr.h" +#include "llatomic.h" #include "httpcommon.h" #include "httprequest.h" #include "_httppolicyglobal.h" diff --git a/indra/llcorehttp/_refcounted.h b/indra/llcorehttp/_refcounted.h index 7f713f2298..5cc8914395 100644 --- a/indra/llcorehttp/_refcounted.h +++ b/indra/llcorehttp/_refcounted.h @@ -34,7 +34,7 @@ #include #include -#include "llapr.h" +#include "llatomic.h" namespace LLCoreInt diff --git a/indra/llcorehttp/_thread.h b/indra/llcorehttp/_thread.h index e058d660e5..22b7750bad 100644 --- a/indra/llcorehttp/_thread.h +++ b/indra/llcorehttp/_thread.h @@ -33,6 +33,7 @@ #include #include +#include "apr.h" // thread-related functions #include "_refcounted.h" namespace LLCoreInt diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp index b450f3502e..e65588e48f 100644 --- a/indra/llcorehttp/tests/test_httprequest.hpp +++ b/indra/llcorehttp/tests/test_httprequest.hpp @@ -2903,6 +2903,13 @@ void HttpRequestTestObjectType::test<22>() set_test_name("BUG-2295"); +#if LL_WINDOWS && ADDRESS_SIZE == 64 + // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it + if (getenv("TEAMCITY_PROJECT_NAME")) + { + skip("BUG-2295 - partial load on W64 causes freeze"); + } +#endif // Handler can be stack-allocated *if* there are no dangling // references to it after completion of this method. // Create before memory record as the string copy will bump numbers. @@ -2921,6 +2928,7 @@ void HttpRequestTestObjectType::test<22>() // options set options = HttpOptions::ptr_t(new HttpOptions()); options->setRetries(1); // Partial_File is retryable and can timeout in here + options->setDNSCacheTimeout(30); // Get singletons created HttpRequest::createService(); @@ -3091,7 +3099,11 @@ void HttpRequestTestObjectType::test<23>() set_test_name("HttpRequest GET 503s with 'Retry-After'"); #if LL_WINDOWS && ADDRESS_SIZE == 64 - skip("llcorehttp 503-with-retry test hangs on Windows 64"); + // teamcity win64 builds freeze on this test, if you figure out the cause, please fix it + if (getenv("TEAMCITY_PROJECT_NAME")) + { + skip("llcorehttp 503-with-retry test hangs on Windows 64"); + } #endif // This tests mainly that the code doesn't fall over if diff --git a/indra/llcrashlogger/llcrashlock.cpp b/indra/llcrashlogger/llcrashlock.cpp index 77abfbcf0f..18d164abde 100644 --- a/indra/llcrashlogger/llcrashlock.cpp +++ b/indra/llcrashlogger/llcrashlock.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" +#include "llapr.h" // thread-related functions #include "llcrashlock.h" #include "lldir.h" #include "llsd.h" diff --git a/indra/llmath/llvolumemgr.cpp b/indra/llmath/llvolumemgr.cpp index 0ae7123a6c..89cdb1c6b9 100644 --- a/indra/llmath/llvolumemgr.cpp +++ b/indra/llmath/llvolumemgr.cpp @@ -48,7 +48,7 @@ LLVolumeMgr::LLVolumeMgr() { // the LLMutex magic interferes with easy unit testing, // so you now must manually call useMutex() to use it - //mDataMutex = new LLMutex(gAPRPoolp); + //mDataMutex = new LLMutex(); } LLVolumeMgr::~LLVolumeMgr() diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index d164289c49..5730a36267 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -48,6 +48,7 @@ static void tcp_close_channel(LLSocket::ptr_t* handle_ptr); // Close an open TCP LLProxy::LLProxy(): mHTTPProxyEnabled(false), + mProxyMutex(), mUDPProxy(), mTCPProxy(), mHTTPProxy(), diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 506ccc98a4..a2524e9804 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -54,11 +54,7 @@ // constants for poll timeout. if we are threading, we want to have a // longer poll timeout. -#if LL_THREADS_APR -static const S32 DEFAULT_POLL_TIMEOUT = 1000; -#else static const S32 DEFAULT_POLL_TIMEOUT = 0; -#endif // The default (and fallback) expiration time for chains const F32 DEFAULT_CHAIN_EXPIRY_SECS = 30.0f; @@ -169,8 +165,6 @@ LLPumpIO::LLPumpIO(apr_pool_t* pool) : mPool(NULL), mCurrentPool(NULL), mCurrentPoolReallocCount(0), - mChainsMutex(NULL), - mCallbackMutex(NULL), mCurrentChain(mRunningChains.end()) { mCurrentChain = mRunningChains.end(); @@ -194,9 +188,6 @@ bool LLPumpIO::addChain(const chain_t& chain, F32 timeout, bool has_curl_request { if(chain.empty()) return false; -#if LL_THREADS_APR - LLScopedLock lock(mChainsMutex); -#endif LLChainInfo info; info.mHasCurlRequest = has_curl_request; info.setTimeoutSeconds(timeout); @@ -234,9 +225,6 @@ bool LLPumpIO::addChain( if(!data) return false; if(links.empty()) return false; -#if LL_THREADS_APR - LLScopedLock lock(mChainsMutex); -#endif #if LL_DEBUG_PIPE_TYPE_IN_PUMP LL_DEBUGS() << "LLPumpIO::addChain() " << links[0].mPipe << " '" << typeid(*(links[0].mPipe)).name() << "'" << LL_ENDL; @@ -391,9 +379,6 @@ void LLPumpIO::clearLock(S32 key) // therefore won't be treading into deleted memory. I think we can // also clear the lock on the chain safely since the pump only // reads that value. -#if LL_THREADS_APR - LLScopedLock lock(mChainsMutex); -#endif mClearLocks.insert(key); } @@ -457,9 +442,6 @@ void LLPumpIO::pump(const S32& poll_timeout) PUMP_DEBUG; if(true) { -#if LL_THREADS_APR - LLScopedLock lock(mChainsMutex); -#endif // bail if this pump is paused. if(PAUSING == mState) { @@ -724,25 +706,10 @@ void LLPumpIO::pump(const S32& poll_timeout) END_PUMP_DEBUG; } -//bool LLPumpIO::respond(const chain_t& pipes) -//{ -//#if LL_THREADS_APR -// LLScopedLock lock(mCallbackMutex); -//#endif -// LLChainInfo info; -// links_t links; -// -// mPendingCallbacks.push_back(info); -// return true; -//} - bool LLPumpIO::respond(LLIOPipe* pipe) { if(NULL == pipe) return false; -#if LL_THREADS_APR - LLScopedLock lock(mCallbackMutex); -#endif LLChainInfo info; LLLinkInfo link; link.mPipe = pipe; @@ -761,10 +728,6 @@ bool LLPumpIO::respond( if(!data) return false; if(links.empty()) return false; -#if LL_THREADS_APR - LLScopedLock lock(mCallbackMutex); -#endif - // Add the callback response LLChainInfo info; info.mChainLinks = links; @@ -781,9 +744,6 @@ void LLPumpIO::callback() //LL_INFOS() << "LLPumpIO::callback()" << LL_ENDL; if(true) { -#if LL_THREADS_APR - LLScopedLock lock(mCallbackMutex); -#endif std::copy( mPendingCallbacks.begin(), mPendingCallbacks.end(), @@ -809,9 +769,6 @@ void LLPumpIO::callback() void LLPumpIO::control(LLPumpIO::EControl op) { -#if LL_THREADS_APR - LLScopedLock lock(mChainsMutex); -#endif switch(op) { case PAUSE: @@ -829,22 +786,11 @@ void LLPumpIO::control(LLPumpIO::EControl op) void LLPumpIO::initialize(apr_pool_t* pool) { if(!pool) return; -#if LL_THREADS_APR - // SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly. - apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool); - apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool); -#endif mPool = pool; } void LLPumpIO::cleanup() { -#if LL_THREADS_APR - if(mChainsMutex) apr_thread_mutex_destroy(mChainsMutex); - if(mCallbackMutex) apr_thread_mutex_destroy(mCallbackMutex); -#endif - mChainsMutex = NULL; - mCallbackMutex = NULL; if(mPollset) { // LL_DEBUGS() << "cleaning up pollset" << LL_ENDL; diff --git a/indra/llmessage/llpumpio.h b/indra/llmessage/llpumpio.h index 3166f80b5b..b9eabee710 100644 --- a/indra/llmessage/llpumpio.h +++ b/indra/llmessage/llpumpio.h @@ -40,9 +40,6 @@ #include "lliopipe.h" #include "llrun.h" -// Define this to enable use with the APR thread library. -//#define LL_THREADS_APR 1 - // some simple constants to help with timeouts extern const F32 DEFAULT_CHAIN_EXPIRY_SECS; extern const F32 SHORT_CHAIN_EXPIRY_SECS; @@ -393,14 +390,6 @@ protected: apr_pool_t* mCurrentPool; S32 mCurrentPoolReallocCount; -#if LL_THREADS_APR - std::mutex* mChainsMutex; - std::mutex* mCallbackMutex; -#else - int* mChainsMutex; - int* mCallbackMutex; -#endif - protected: void initialize(apr_pool_t* pool); void cleanup(); diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp index b78e7d6f66..9766e1bfed 100644 --- a/indra/llplugin/llpluginmessagepipe.cpp +++ b/indra/llplugin/llpluginmessagepipe.cpp @@ -92,6 +92,8 @@ void LLPluginMessagePipeOwner::killMessagePipe(void) } LLPluginMessagePipe::LLPluginMessagePipe(LLPluginMessagePipeOwner *owner, LLSocket::ptr_t socket): + mInputMutex(), + mOutputMutex(), mOutputStartIndex(0), mOwner(owner), mSocket(socket) diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp index 90e35fc798..bf7c7ddba2 100644 --- a/indra/llplugin/llpluginprocessparent.cpp +++ b/indra/llplugin/llpluginprocessparent.cpp @@ -81,7 +81,8 @@ protected: }; -LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner) +LLPluginProcessParent::LLPluginProcessParent(LLPluginProcessParentOwner *owner): + mIncomingQueueMutex() { if(!sInstancesMutex) { diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 472ae2037d..c2a5389b6c 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -160,7 +160,6 @@ public: void ClearFacesAndMaterials() { mVolumeFaces.clear(); mMaterialList.clear(); } std::string getName() const; - std::string getMetric() const {return mMetric;} EModelStatus getStatus() const {return mStatus;} static std::string getStatusString(U32 status) ; @@ -266,8 +265,6 @@ public: std::string mRequestedLabel; // name requested in UI, if any. std::string mLabel; // name computed from dae. - std::string mMetric; // user-supplied metric data for upload - LLVector3 mNormalizedScale; LLVector3 mNormalizedTranslation; diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp index 5967ff5ff0..081e85f638 100644 --- a/indra/llrender/llfontfreetype.cpp +++ b/indra/llrender/llfontfreetype.cpp @@ -48,6 +48,7 @@ //#include "imdebug.h" #include "llfontbitmapcache.h" #include "llgl.h" +#include "llapr.h" FT_Render_Mode gFontRenderMode = FT_RENDER_MODE_NORMAL; diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt index a0bd64e0d1..0778b460ee 100644 --- a/indra/llui/CMakeLists.txt +++ b/indra/llui/CMakeLists.txt @@ -145,7 +145,6 @@ set(llui_HEADER_FILES CMakeLists.txt fsregistrarutils.h - fssearchablecontrol.h llaccordionctrl.h llaccordionctrltab.h @@ -207,6 +206,7 @@ set(llui_HEADER_FILES llresizehandle.h llresmgr.h llrngwriter.h + llsearchablecontrol.h llsearcheditor.h llscrollbar.h llscrollcontainer.h diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp index bc47fcbf38..f8eba596b9 100644 --- a/indra/llui/llbutton.cpp +++ b/indra/llui/llbutton.cpp @@ -805,10 +805,9 @@ void LLButton::draw() } } - // Highlight if needed - if( nd::ui::SearchableControl::getHighlighted() ) - label_color = nd::ui::SearchableControl::getHighlightColor(); - // + // Highlight if needed + if( ll::ui::SearchableControl::getHighlighted() ) + label_color = ll::ui::SearchableControl::getHighlightColor(); // Unselected label assignments LLWString label = getCurrentLabel(); diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h index fde59f5d9f..e4420bb1dc 100644 --- a/indra/llui/llbutton.h +++ b/indra/llui/llbutton.h @@ -62,7 +62,7 @@ class LLUICtrlFactory; class LLButton : public LLUICtrl, public LLBadgeOwner -, public nd::ui::SearchableControl +, public ll::ui::SearchableControl { public: struct Params @@ -396,13 +396,11 @@ protected: LLPanel* mCheckboxControlPanel; // -// Searchable text for UI filter protected: virtual std::string _getSearchText() const { return getLabelUnselected() + getToolTip(); } -// }; // Build time optimization, generate once in .cpp file diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h index 5f33df9d69..41110b9ae0 100644 --- a/indra/llui/llcheckboxctrl.h +++ b/indra/llui/llcheckboxctrl.h @@ -47,7 +47,7 @@ class LLViewBorder; class LLCheckBoxCtrl : public LLUICtrl -, public nd::ui::SearchableControl +, public ll::ui::SearchableControl { public: struct Params @@ -97,6 +97,8 @@ public: // LLCheckBoxCtrl interface virtual BOOL toggle() { return mButton->toggleState(); } // returns new state + void setBtnFocus() { mButton->setFocus(TRUE); } + void setEnabledColor( const LLColor4 &color ) { mTextEnabledColor = color; } void setDisabledColor( const LLColor4 &color ) { mTextDisabledColor = color; } @@ -123,6 +125,18 @@ private: enable_signal_t mCheckSignal; // +protected: + virtual std::string _getSearchText() const + { + return getLabel() + getToolTip(); + } + + virtual void onSetHighlight() const // When highlight, really do highlight the label + { + if( mLabel ) + mLabel->ll::ui::SearchableControl::setHighlighted( ll::ui::SearchableControl::getHighlighted() ); + } + protected: // note: value is stored in toggle state of button LLButton* mButton; @@ -131,20 +145,6 @@ protected: LLUIColor mTextEnabledColor; LLUIColor mTextDisabledColor; - -// Searchable text for UI filter -protected: - virtual std::string _getSearchText() const - { - return getLabel() + getToolTip(); - } - - virtual void onSetHighlight( ) const // When highlight, really do highlight the label - { - if( mLabel ) - mLabel-> nd::ui::SearchableControl::setHighlighted( nd::ui::SearchableControl::getHighlighted() ); - } -// }; // Build time optimization, generate once in .cpp file diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp index b03ddd6c64..fcde9a32b5 100644 --- a/indra/llui/llcombobox.cpp +++ b/indra/llui/llcombobox.cpp @@ -246,7 +246,14 @@ LLScrollListItem* LLComboBox::add(const std::string& name, EAddPosition pos, BOO item->setEnabled(enabled); if (!mAllowTextEntry && mLabel.empty()) { - selectFirstItem(); + if (mControlVariable) + { + setValue(mControlVariable->getValue()); // selects the appropriate item + } + else + { + selectFirstItem(); + } } return item; } @@ -258,7 +265,14 @@ LLScrollListItem* LLComboBox::add(const std::string& name, const LLUUID& id, EAd item->setEnabled(enabled); if (!mAllowTextEntry && mLabel.empty()) { - selectFirstItem(); + if (mControlVariable) + { + setValue(mControlVariable->getValue()); // selects the appropriate item + } + else + { + selectFirstItem(); + } } return item; } @@ -271,7 +285,14 @@ LLScrollListItem* LLComboBox::add(const std::string& name, void* userdata, EAddP item->setUserdata( userdata ); if (!mAllowTextEntry && mLabel.empty()) { - selectFirstItem(); + if (mControlVariable) + { + setValue(mControlVariable->getValue()); // selects the appropriate item + } + else + { + selectFirstItem(); + } } return item; } @@ -283,7 +304,14 @@ LLScrollListItem* LLComboBox::add(const std::string& name, LLSD value, EAddPosit item->setEnabled(enabled); if (!mAllowTextEntry && mLabel.empty()) { - selectFirstItem(); + if (mControlVariable) + { + setValue(mControlVariable->getValue()); // selects the appropriate item + } + else + { + selectFirstItem(); + } } return item; } diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp index 81cbc532e2..7dab275292 100644 --- a/indra/llui/lllayoutstack.cpp +++ b/indra/llui/lllayoutstack.cpp @@ -289,8 +289,14 @@ void LLLayoutStack::draw() // always clip to stack itself LLLocalClipRect clip(getLocalRect()); - BOOST_FOREACH(LLLayoutPanel* panelp, mPanels) + for (LLLayoutPanel* panelp : mPanels) { + if ((!panelp->getVisible() || panelp->mCollapsed) + && (panelp->mVisibleAmt < 0.001f || !mAnimate)) + { + // essentially invisible + continue; + } // clip to layout rectangle, not bounding rectangle LLRect clip_rect = panelp->getRect(); // scale clipping rectangle by visible amount diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp index 1ad8f9dbb3..ca4b49478c 100644 --- a/indra/llui/llmenugl.cpp +++ b/indra/llui/llmenugl.cpp @@ -525,10 +525,9 @@ void LLMenuItemGL::draw( void ) color = mDisabledColor.get(); } - // Highlight if needed - if( nd::ui::SearchableControl::getHighlighted() ) - color = nd::ui::SearchableControl::getHighlightColor(); - // + // Highlight if needed + if( ll::ui::SearchableControl::getHighlighted() ) + color = ll::ui::SearchableControl::getHighlightColor(); // Draw the text on top. if (mBriefItem) diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h index e7a80126d2..e86aea1ebf 100644 --- a/indra/llui/llmenugl.h +++ b/indra/llui/llmenugl.h @@ -48,8 +48,7 @@ extern S32 MENU_BAR_WIDTH; // The LLMenuItemGL represents a single menu item in a menu. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -class LLMenuItemGL : public LLUICtrl - , public nd::ui::SearchableControl +class LLMenuItemGL: public LLUICtrl, public ll::ui::SearchableControl { public: struct Params : public LLInitParam::Block @@ -177,7 +176,12 @@ protected: // This function appends the character string representation of // the current accelerator key and mask to the provided string. void appendAcceleratorString( std::string& st ) const; - + + virtual std::string _getSearchText() const + { + return mLabel.getString(); + } + protected: KEY mAcceleratorKey; MASK mAcceleratorMask; @@ -211,9 +215,6 @@ private: BOOL mDrawTextDisabled; KEY mJumpKey; -protected: - virtual std::string _getSearchText() const - { return mLabel.getString(); } }; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/indra/llui/llsearchablecontrol.h b/indra/llui/llsearchablecontrol.h new file mode 100644 index 0000000000..f7f1ffa0a5 --- /dev/null +++ b/indra/llui/llsearchablecontrol.h @@ -0,0 +1,71 @@ +/** +* @file llsearchablecontrol.h +* +* $LicenseInfo:firstyear=2019&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2019, 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_SEARCHABLE_CONTROL_H +#define LL_SEARCHABLE_CONTROL_H + +#include "lluicolortable.h" +#include "lluicolor.h" + +namespace ll +{ + namespace ui + { + class SearchableControl + { + mutable bool mIsHighlighed; + public: + SearchableControl() + : mIsHighlighed( false ) + { } + virtual ~SearchableControl() + { } + + LLColor4 getHighlightColor( ) const + { + static LLUIColor highlight_color = LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red); + return highlight_color.get(); + } + + void setHighlighted( bool aVal ) const + { + mIsHighlighed = aVal; + onSetHighlight( ); + } + bool getHighlighted( ) const + { return mIsHighlighed; } + + std::string getSearchText() const + { return _getSearchText(); } + protected: + virtual std::string _getSearchText() const = 0; + virtual void onSetHighlight( ) const + { } + }; + } +} + + +#endif diff --git a/indra/llui/llsliderctrl.h b/indra/llui/llsliderctrl.h index 6b004671c8..541c167717 100644 --- a/indra/llui/llsliderctrl.h +++ b/indra/llui/llsliderctrl.h @@ -35,8 +35,7 @@ #include "lllineeditor.h" -class LLSliderCtrl : public LLF32UICtrl - , public nd::ui::SearchableControl +class LLSliderCtrl: public LLF32UICtrl, public ll::ui::SearchableControl { public: struct Params : public LLInitParam::Block @@ -135,6 +134,19 @@ public: static void onEditorGainFocus(LLFocusableElement* caller, void *userdata); static void onEditorChangeFocus(LLUICtrl* caller, S32 direction, void *userdata); +protected: + virtual std::string _getSearchText() const + { + std::string strLabel; + if( mLabelBox ) + strLabel = mLabelBox->getLabel(); + return strLabel + getToolTip(); + } + virtual void onSetHighlight() const // When highlight, really do highlight the label + { + if( mLabelBox ) + mLabelBox->ll::ui::SearchableControl::setHighlighted( ll::ui::SearchableControl::getHighlighted() ); + } private: void updateText(); void updateSliderRect(); @@ -158,21 +170,6 @@ private: LLUIColor mTextDisabledColor; commit_signal_t* mEditorCommitSignal; - // Searchable text for UI filter -protected: - virtual std::string _getSearchText() const - { - std::string strLabel; - if( mLabelBox ) - strLabel = mLabelBox->getLabel(); - return strLabel + getToolTip(); - } - virtual void onSetHighlight( ) const // When highlight, really do highlight the label - { - if( mLabelBox ) - mLabelBox-> nd::ui::SearchableControl::setHighlighted( nd::ui::SearchableControl::getHighlighted() ); - } -// }; #endif // LL_LLSLIDERCTRL_H diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 5b5cfc9d70..d1b976b85f 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -77,8 +77,8 @@ public: mButton(b), mOldState(FALSE), mPlaceholderText(placeholder), - mPadding(0) - , mVisible( true ) + mPadding(0), + mVisible(true) {} LLTabContainer* mTabContainer; @@ -434,13 +434,10 @@ void LLTabContainer::draw() { break; } - //target_pixel_scroll += (*iter)->mButton->getRect().getWidth(); - // Only show button if tab is visible - if ((*iter)->mVisible) - { + + if( (*iter)->mVisible ) target_pixel_scroll += (*iter)->mButton->getRect().getWidth(); - } - // + cur_scroll_pos--; } @@ -518,13 +515,11 @@ void LLTabContainer::draw() { LLTabTuple* tuple = *iter; - // If the tab is hidden, do not take it into account. if( !tuple->mVisible ) { - tuple->mButton->setVisible(false); + tuple->mButton->setVisible( false ); continue; } - // tuple->mButton->translate( left ? left - tuple->mButton->getRect().mLeft : 0, top ? top - tuple->mButton->getRect().mTop : 0 ); @@ -831,15 +826,11 @@ BOOL LLTabContainer::handleToolTip( S32 x, S32 y, MASK mask) { for(tuple_list_t::iterator iter = mTabList.begin(); iter != mTabList.end(); ++iter) { - LLTabTuple* tuple = *iter; -// [SL:KB] - if (!tuple->mButton->getVisible()) - continue; -// [/SL/KB] -// tuple->mButton->setVisible( TRUE ); - S32 local_x = x - tuple->mButton->getRect().mLeft; - S32 local_y = y - tuple->mButton->getRect().mBottom; - handled = tuple->mButton->handleToolTip( local_x, local_y, mask); + LLButton* tab_button = (*iter)->mButton; + if (!tab_button->getVisible()) continue; + S32 local_x = x - tab_button->getRect().mLeft; + S32 local_y = y - tab_button->getRect().mBottom; + handled = tab_button->handleToolTip(local_x, local_y, mask); if( handled ) { break; @@ -1687,10 +1678,7 @@ BOOL LLTabContainer::setTab(S32 which) } BOOL is_visible = FALSE; - // Cannot switch to a hidden tab - // if (selected_tuple->mButton->getEnabled()) - if (selected_tuple->mButton->getEnabled() && selected_tuple->mVisible ) - // + if( selected_tuple->mButton->getEnabled() && selected_tuple->mVisible ) { setCurrentPanelIndex(which); @@ -2448,16 +2436,6 @@ S32 LLTabContainer::getTotalTabWidth() const return mTotalTabWidth; } -// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3) -boost::signals2::connection LLTabContainer::setRearrangeCallback(const tab_rearrange_signal_t::slot_type& cb) -{ - if (!mRearrangeSignal) - mRearrangeSignal = new tab_rearrange_signal_t(); - return mRearrangeSignal->connect(cb); -} -// [/SL:KB] - -// Hide one tab. Will switch to the first visible tab if one exists. Otherwise the Tabcontainer is hidden void LLTabContainer::setTabVisibility( LLPanel const *aPanel, bool aVisible ) { for( tuple_list_t::const_iterator itr = mTabList.begin(); itr != mTabList.end(); ++itr ) @@ -2476,7 +2454,7 @@ void LLTabContainer::setTabVisibility( LLPanel const *aPanel, bool aVisible ) LLTabTuple const *pTT = *itr; if( pTT->mVisible ) { - this->selectTab( itr-mTabList.begin() ); + this->selectTab( itr - mTabList.begin() ); foundTab = true; break; } @@ -2489,4 +2467,12 @@ void LLTabContainer::setTabVisibility( LLPanel const *aPanel, bool aVisible ) updateMaxScrollPos(); } -// + +// [SL:KB] - Patch: UI-TabRearrange | Checked: 2012-05-05 (Catznip-3.3) +boost::signals2::connection LLTabContainer::setRearrangeCallback(const tab_rearrange_signal_t::slot_type& cb) +{ + if (!mRearrangeSignal) + mRearrangeSignal = new tab_rearrange_signal_t(); + return mRearrangeSignal->connect(cb); +} +// [/SL:KB] diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index a783a9894c..1209ffd412 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -236,6 +236,8 @@ public: S32 getMinTabWidth() const { return mMinTabWidth; } S32 getMaxTabWidth() const { return mMaxTabWidth; } + void setTabVisibility( LLPanel const *aPanel, bool ); + void startDragAndDropDelayTimer() { mDragAndDropDelayTimer.start(); } void onTabBtn( const LLSD& data, LLPanel* panel ); @@ -343,9 +345,6 @@ private: bool mOpenTabsOnDragAndDrop; S32 mTabIconCtrlPad; bool mUseTabEllipses; - -public: - void setTabVisibility( LLPanel const *aPanel, bool ); }; #endif // LL_TABCONTAINER_H diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index f5b69cf015..f97f645219 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -1298,18 +1298,16 @@ void LLTextBase::draw() gl_rect_2d(text_rect, bg_color % alpha, TRUE); } - // Draw highlighted if needed - if( nd::ui::SearchableControl::getHighlighted() ) + // Draw highlighted if needed + if( ll::ui::SearchableControl::getHighlighted() ) { - LLColor4 bg_color = nd::ui::SearchableControl::getHighlightColor(); + LLColor4 bg_color = ll::ui::SearchableControl::getHighlightColor(); LLRect bg_rect = mVisibleTextRect; - if (mScroller) - bg_rect.intersectWith(text_rect); + if( mScroller ) + bg_rect.intersectWith( text_rect ); - gl_rect_2d(text_rect, bg_color, TRUE); + gl_rect_2d( text_rect, bg_color, TRUE ); } - // - bool should_clip = mClip || mScroller != NULL; // Fix text bleeding at top edge of scrolling text editors diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index aca45ca7dd..f85aaaba45 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -296,8 +296,8 @@ namespace LLInitParam class LLTextBase : public LLUICtrl, protected LLEditMenuHandler, - public LLSpellCheckMenuHandler - , public nd::ui::SearchableControl + public LLSpellCheckMenuHandler, + public ll::ui::SearchableControl { public: friend class LLTextSegment; @@ -671,6 +671,11 @@ protected: void appendAndHighlightTextImpl(const std::string &new_text, S32 highlight_part, const LLStyle::Params& style_params, bool underline_on_hover_only = false); S32 normalizeUri(std::string& uri); +protected: + virtual std::string _getSearchText() const + { + return mLabel.getString() + getToolTip(); + } protected: // text segmentation and flow @@ -770,14 +775,6 @@ protected: LLUIString mLabel; // text label that is visible when no user text provided // Optional icon position LLTextBaseEnums::EIconPositioning mIconPositioning; - -// Searchable text for UI filter -protected: - virtual std::string _getSearchText() const - { - return mLabel.getString() + getToolTip(); - } -// }; #endif diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp index f6261896f4..1b9dfec41c 100644 --- a/indra/llui/lltexteditor.cpp +++ b/indra/llui/lltexteditor.cpp @@ -786,14 +786,30 @@ BOOL LLTextEditor::handleRightMouseDown(S32 x, S32 y, MASK mask) // [SL:KB] - Patch: UI-Notecards | Checked: 2010-09-12 (Catznip-2.1.2d) | Added: Catznip-2.1.2d setCursorAtLocalPos(x, y, FALSE); // [/SL:KB] + + bool show_menu = false; + // Prefer editor menu if it has selection. See EXT-6806. - if (hasSelection() || !LLTextBase::handleRightMouseDown(x, y, mask)) + if (hasSelection()) { - if(getShowContextMenu()) + S32 click_pos = getDocIndexFromLocalCoord(x, y, FALSE); + if (click_pos > mSelectionStart && click_pos < mSelectionEnd) { - showContextMenu(x, y); + show_menu = true; } } + + // Let segments handle the click, if nothing does, show editor menu + if (!show_menu && !LLTextBase::handleRightMouseDown(x, y, mask)) + { + show_menu = true; + } + + if (show_menu && getShowContextMenu()) + { + showContextMenu(x, y); + } + return TRUE; } diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h index 8671d86cee..d734d57b3f 100644 --- a/indra/llui/lluictrl.h +++ b/indra/llui/lluictrl.h @@ -37,8 +37,7 @@ #include "llinitparam.h" #include "llview.h" #include "llviewmodel.h" // *TODO move dependency to .cpp file - -#include "fssearchablecontrol.h" +#include "llsearchablecontrol.h" const BOOL TAKE_FOCUS_YES = TRUE; const BOOL TAKE_FOCUS_NO = FALSE; diff --git a/indra/llvfs/lllfsthread.h b/indra/llvfs/lllfsthread.h index cdb5c75946..58f658f7ba 100644 --- a/indra/llvfs/lllfsthread.h +++ b/indra/llvfs/lllfsthread.h @@ -32,7 +32,6 @@ #include #include -#include "llapr.h" #include "llpointer.h" #include "llqueuedthread.h" diff --git a/indra/llvfs/llpidlock.cpp b/indra/llvfs/llpidlock.cpp index 6572edead3..f770e93d45 100644 --- a/indra/llvfs/llpidlock.cpp +++ b/indra/llvfs/llpidlock.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" +#include "llapr.h" // thread-related functions #include "llpidlock.h" #include "lldir.h" #include "llsd.h" diff --git a/indra/llvfs/llvfsthread.h b/indra/llvfs/llvfsthread.h index 95f3c857c6..7814de4a2d 100644 --- a/indra/llvfs/llvfsthread.h +++ b/indra/llvfs/llvfsthread.h @@ -32,8 +32,6 @@ #include #include -#include "llapr.h" - #include "llqueuedthread.h" #include "llvfs.h" diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index fdb0a2cb16..7956bf38c9 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -356,7 +356,7 @@ attributedStringInfo getSegments(NSAttributedString *str) NSPoint mPoint = gHiDPISupport ? [self convertPointToBacking:[theEvent locationInWindow]] : [theEvent locationInWindow]; mMousePos[0] = mPoint.x; mMousePos[1] = mPoint.y; - + // Apparently people still use this? if ([theEvent modifierFlags] & NSCommandKeyMask && !([theEvent modifierFlags] & NSControlKeyMask) && diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 805aff7e4c..72e3078a93 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -43,6 +43,9 @@ #include "llrect.h" #include "llxmltree.h" #include "llsdserialize.h" +#include "llfile.h" +#include "lltimer.h" +#include "lldir.h" #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG #define CONTROL_ERRS LL_ERRS("ControlErrors") @@ -92,6 +95,17 @@ template <> LLSD convert_from_llsd(const LLSD& sd, eControlType type, cons //this defines the current version of the settings file const S32 CURRENT_VERSION = 101; +// If you define the environment variable LL_SETTINGS_PROFILE to any value this will activate +// the gSavedSettings profiling code. This code tracks the calls to get a saved (debug) setting. +// When the viewer exits the results are written to the log directory to the file specified +// by SETTINGS_PROFILE below. Only settings with an average access rate >= 2/second are output. +typedef std::pair settings_pair_t; +typedef std::vector settings_vec_t; +LLSD getCount; +settings_vec_t getCount_v; +F64 start_time = 0; +std::string SETTINGS_PROFILE = "settings_profile.log"; + bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b) { bool result = false; @@ -398,6 +412,11 @@ LLSD LLControlVariable::getSaveValue() const LLPointer LLControlGroup::getControl(const std::string& name) { + if (mSettingsProfile) + { + incrCount(name); + } + ctrl_name_table_t::iterator iter = mNameTable.find(name); return iter == mNameTable.end() ? LLPointer() : iter->second; } @@ -431,8 +450,14 @@ const std::string LLControlGroup::mSanityTypeString[SANITY_TYPE_COUNT] = { "None }; LLControlGroup::LLControlGroup(const std::string& name) -: LLInstanceTracker(name) +: LLInstanceTracker(name), + mSettingsProfile(false) { + + if (NULL != getenv("LL_SETTINGS_PROFILE")) + { + mSettingsProfile = true; + } } LLControlGroup::~LLControlGroup() @@ -440,8 +465,66 @@ LLControlGroup::~LLControlGroup() cleanup(); } +static bool compareRoutine(settings_pair_t lhs, settings_pair_t rhs) +{ + return lhs.second > rhs.second; +}; + void LLControlGroup::cleanup() { + if(mSettingsProfile && getCount.size() != 0) + { + std::string file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, SETTINGS_PROFILE); + LLFILE* out = LLFile::fopen(file, "w"); /* Flawfinder: ignore */ + if(!out) + { + LL_WARNS("SettingsProfile") << "Error opening " << SETTINGS_PROFILE << LL_ENDL; + } + else + { + F64 end_time = LLTimer::getTotalSeconds(); + U32 total_seconds = (U32)(end_time - start_time); + + std::string msg = llformat("Runtime (seconds): %d\n\n No. accesses Avg. accesses/sec Name\n", total_seconds); + std::ostringstream data_msg; + + data_msg << msg; + size_t data_size = data_msg.str().size(); + if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) + { + LL_WARNS("SettingsProfile") << "Failed to write settings profile header" << LL_ENDL; + } + + for (LLSD::map_const_iterator iter = getCount.beginMap(); iter != getCount.endMap(); ++iter) + { + getCount_v.push_back(settings_pair_t(iter->first, iter->second.asInteger())); + } + sort(getCount_v.begin(), getCount_v.end(), compareRoutine); + + for (settings_vec_t::iterator iter = getCount_v.begin(); iter != getCount_v.end(); ++iter) + { + U32 access_rate = 0; + if (total_seconds != 0) + { + access_rate = iter->second / total_seconds; + } + if (access_rate >= 2) + { + std::ostringstream data_msg; + msg = llformat("%13d %7d %s", iter->second, access_rate, iter->first.c_str()); + data_msg << msg << "\n"; + size_t data_size = data_msg.str().size(); + if (fwrite(data_msg.str().c_str(), 1, data_size, out) != data_size) + { + LL_WARNS("SettingsProfile") << "Failed to write settings profile" << LL_ENDL; + } + } + } + getCount = LLSD::emptyMap(); + fclose(out); + } + } + mNameTable.clear(); } @@ -562,6 +645,15 @@ LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LL return declareControl(name, TYPE_LLSD, initial_val, comment, SANITY_TYPE_NONE, LLSD(), std::string(""), persist); } +void LLControlGroup::incrCount(const std::string& name) +{ + if (0.0 == start_time) + { + start_time = LLTimer::getTotalSeconds(); + } + getCount[name] = getCount[name].asInteger() + 1; +} + BOOL LLControlGroup::getBOOL(const std::string& name) { return (BOOL)get(name); diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 343588bb2f..d9b354ed76 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -345,6 +345,9 @@ public: U32 saveToFile(const std::string& filename, BOOL nondefault_only); U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true); void resetToDefaults(); + void incrCount(const std::string& name); + + bool mSettingsProfile; }; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index ca7befee1e..9c8f18539d 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -208,7 +208,6 @@ set(viewer_SOURCE_FILES fsradarmenu.cpp fsscriptlibrary.cpp fsscrolllistctrl.cpp - fssearchableui.cpp fsslurlcommand.cpp groupchatlistener.cpp lggbeamcolormapfloater.cpp @@ -385,6 +384,7 @@ set(viewer_SOURCE_FILES llfloatermemleak.cpp llfloatermodelpreview.cpp llfloatermodeluploadbase.cpp + llfloatermyscripts.cpp llfloatermyenvironment.cpp llfloaternamedesc.cpp llfloaternotificationsconsole.cpp @@ -660,6 +660,7 @@ set(viewer_SOURCE_FILES llscrollingpanelparam.cpp llscrollingpanelparambase.cpp llsculptidsize.cpp + llsearchableui.cpp llsearchcombobox.cpp llsearchhistory.cpp llsecapi.cpp @@ -963,7 +964,6 @@ set(viewer_HEADER_FILES fsradarmenu.h fsscriptlibrary.h fsscrolllistctrl.h - fssearchableui.h fsslurl.h fsslurlcommand.h groupchatlistener.h @@ -1145,6 +1145,7 @@ set(viewer_HEADER_FILES llfloatermemleak.h llfloatermodelpreview.h llfloatermodeluploadbase.h + llfloatermyscripts.h llfloatermyenvironment.h llfloaternamedesc.h llfloaternotificationsconsole.h @@ -1408,6 +1409,7 @@ set(viewer_HEADER_FILES llscrollingpanelparam.h llscrollingpanelparambase.h llsculptidsize.h + llsearchableui.h llsearchcombobox.h llsearchhistory.h llsecapi.h @@ -1954,6 +1956,7 @@ endif (WINDOWS) # from within the IDE. set(viewer_XUI_FILES skins/default/colors.xml + skins/default/default_languages.xml skins/default/textures/textures.xml ) file(GLOB DEFAULT_XUI_FILE_GLOB_LIST @@ -2271,22 +2274,14 @@ if (WINDOWS) windows-crash-logger ) - # No Teamcity -> allow unattended # sets the 'working directory' for debugging from visual studio. - if (NOT UNATTENDED) - add_custom_command( - TARGET ${VIEWER_BINARY_NAME} POST_BUILD - COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe - ARGS - --solution - ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln - --workingdir - ${VIEWER_BINARY_NAME} - "${CMAKE_CURRENT_SOURCE_DIR}" - COMMENT "Setting the ${VIEWER_BINARY_NAME} working directory for debugging." - ) - endif (NOT UNATTENDED) - # + # Condition for version can be moved to requirements once build agents will be updated (see TOOL-3865) + if ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2")) + set_property( + TARGET ${VIEWER_BINARY_NAME} + PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + endif ((NOT UNATTENDED) AND (${CMAKE_VERSION} VERSION_GREATER "3.7.2")) if (PACKAGE) add_custom_command( diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 96398df52f..47fb631e34 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -14365,6 +14365,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 0 + MenuSearch + + Comment + Show/hide 'Search menus' field + Persist + 1 + Type + Boolean + Value + 1 + GroupListShowIcons Comment @@ -17646,6 +17657,17 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1.0 + RegionCrossingInterpolationTime + + Comment + How long to extrapolate object motion after crossing regions + Persist + 1 + Type + F32 + Value + 1 + VertexShaderEnable Comment @@ -24041,17 +24063,6 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1023 - FSMenuSearch - - Comment - If enabled, the viewer will show a search box for top menu items. - Persist - 1 - Type - Boolean - Value - 1 - FSLogSnapshotsToLocal Comment diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl index 3424613e94..de2ea2a065 100644 --- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl +++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl @@ -91,9 +91,7 @@ void main() // Collect normal lights (need to be divided by two, as we later multiply by 2) col.rgb += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz); -// col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].z); col.rgb += light_diffuse[2].rgb * calcDirectionalLight(norm, light_position[2].xyz); -// col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].z); col.rgb += light_diffuse[3].rgb * calcDirectionalLight(norm, light_position[3].xyz); col /= 2.0; vertex_color = col*color; diff --git a/indra/newview/chatbar_as_cmdline.cpp b/indra/newview/chatbar_as_cmdline.cpp index 6b68f8e158..7aef1d1d50 100644 --- a/indra/newview/chatbar_as_cmdline.cpp +++ b/indra/newview/chatbar_as_cmdline.cpp @@ -898,19 +898,42 @@ bool cmd_line_chat(const std::string& revised_text, EChatType type, bool from_ge { if (revised_text.length() > command.length() + 1) //Typing this command with no argument was causing a crash. -Madgeek { - LLVector3d agentPos = gAgent.getPositionGlobal(); - S32 agent_x = ll_round( (F32)fmod( agentPos.mdV[VX], (F64)REGION_WIDTH_METERS ) ); - S32 agent_y = ll_round( (F32)fmod( agentPos.mdV[VY], (F64)REGION_WIDTH_METERS ) ); - S32 agent_z = ll_round( (F32)agentPos.mdV[VZ] ); - std::string region_name = LLWeb::escapeURL(revised_text.substr(command.length() + 1)); - std::string url; - - if (!sFSCmdLineMapToKeepPos) + size_t found = revised_text.find("|"); + std::string region_name; + std::string cords; + S32 agent_x, agent_y, agent_z; + if (found != std::string::npos) { - agent_x = 128; - agent_y = 128; - agent_z = 0; + region_name = revised_text.substr(command.length() + 1); + found = region_name.find("|"); + cords = region_name.substr(found+1); + LLStringUtil::trim(cords); + region_name = region_name.substr(0, found); + LLStringUtil::trim(region_name); + region_name = LLWeb::escapeURL(region_name); + i.str(cords); + if (!((i >> agent_x) && (i >> agent_y) && (i >> agent_z))) + { + agent_x = 128; + agent_y = 128; + agent_z = 0; + } } + else + { + region_name = LLWeb::escapeURL(revised_text.substr(command.length() + 1)); + LLVector3d agentPos = gAgent.getPositionGlobal(); + agent_x = ll_round((F32)fmod(agentPos.mdV[VX], (F64)REGION_WIDTH_METERS)); + agent_y = ll_round((F32)fmod(agentPos.mdV[VY], (F64)REGION_WIDTH_METERS)); + agent_z = ll_round((F32)agentPos.mdV[VZ]); + if (!sFSCmdLineMapToKeepPos) + { + agent_x = 128; + agent_y = 128; + agent_z = 0; + } + } + std::string url; url = llformat("secondlife:///app/teleport/%s/%d/%d/%d", region_name.c_str(), agent_x, agent_y, agent_z); LLURLDispatcher::dispatch(url, "clicked", NULL, true); diff --git a/indra/newview/fonts/fonts.xml b/indra/newview/fonts/fonts.xml index 2e52838d5c..dae429ac4f 100644 --- a/indra/newview/fonts/fonts.xml +++ b/indra/newview/fonts/fonts.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fonts/fonts_celestia_medium_redux.xml b/indra/newview/fonts/fonts_celestia_medium_redux.xml index 05455e394f..db9834f07c 100644 --- a/indra/newview/fonts/fonts_celestia_medium_redux.xml +++ b/indra/newview/fonts/fonts_celestia_medium_redux.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fonts/fonts_deja_vu_all_caps.xml b/indra/newview/fonts/fonts_deja_vu_all_caps.xml index 7d19177452..dad4caa77a 100644 --- a/indra/newview/fonts/fonts_deja_vu_all_caps.xml +++ b/indra/newview/fonts/fonts_deja_vu_all_caps.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fonts/fonts_droid.xml b/indra/newview/fonts/fonts_droid.xml index 87cc116fab..473c634bd5 100644 --- a/indra/newview/fonts/fonts_droid.xml +++ b/indra/newview/fonts/fonts_droid.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fonts/fonts_dyslexia.xml b/indra/newview/fonts/fonts_dyslexia.xml index 0dff811706..207dc35e40 100644 --- a/indra/newview/fonts/fonts_dyslexia.xml +++ b/indra/newview/fonts/fonts_dyslexia.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fonts/fonts_liberation.xml b/indra/newview/fonts/fonts_liberation.xml index c3fe115419..f418e75bf7 100644 --- a/indra/newview/fonts/fonts_liberation.xml +++ b/indra/newview/fonts/fonts_liberation.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fonts/fonts_mobi.xml b/indra/newview/fonts/fonts_mobi.xml index 9526ffa3fa..ef3cbf654c 100644 --- a/indra/newview/fonts/fonts_mobi.xml +++ b/indra/newview/fonts/fonts_mobi.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fonts/fonts_noto.xml b/indra/newview/fonts/fonts_noto.xml index 018726b229..c6c95a4ac9 100644 --- a/indra/newview/fonts/fonts_noto.xml +++ b/indra/newview/fonts/fonts_noto.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fonts/fonts_roboto.xml b/indra/newview/fonts/fonts_roboto.xml index efe3605985..77884fdb2b 100644 --- a/indra/newview/fonts/fonts_roboto.xml +++ b/indra/newview/fonts/fonts_roboto.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fonts/fonts_ubuntu.xml b/indra/newview/fonts/fonts_ubuntu.xml index a89898fcfd..69b009ad90 100644 --- a/indra/newview/fonts/fonts_ubuntu.xml +++ b/indra/newview/fonts/fonts_ubuntu.xml @@ -10,6 +10,7 @@ gulim.ttc simhei.ttf ArialUni.ttf + msyh.ttc seguisym.ttf nirmala.ttf tahoma.ttf @@ -26,6 +27,7 @@ AppleGothic.ttf AppleSDGothicNeo-Regular.otf 华文细黑.ttf + PingFang.ttc diff --git a/indra/newview/fsfloatervoicecontrols.cpp b/indra/newview/fsfloatervoicecontrols.cpp index 566d44f5b1..a75fe164b9 100644 --- a/indra/newview/fsfloatervoicecontrols.cpp +++ b/indra/newview/fsfloatervoicecontrols.cpp @@ -548,7 +548,7 @@ void FSFloaterVoiceControls::setModeratorMutedVoice(bool moderator_muted) { LLNotificationsUtil::add("VoiceIsMutedByModerator"); } - mSpeakingIndicator->setIsMuted(moderator_muted); + mSpeakingIndicator->setIsModeratorMuted(moderator_muted); } void FSFloaterVoiceControls::onModeratorNameCache(const LLAvatarName& av_name) diff --git a/indra/newview/fsparticipantlist.cpp b/indra/newview/fsparticipantlist.cpp index a136c558d2..f7960dca06 100644 --- a/indra/newview/fsparticipantlist.cpp +++ b/indra/newview/fsparticipantlist.cpp @@ -54,7 +54,7 @@ static void update_speaker_indicator(const LLAvatarList* const avatar_list, cons if (item) { LLOutputMonitorCtrl* indicator = item->getChild("speaking_indicator"); - indicator->setIsMuted(is_muted); + indicator->setIsModeratorMuted(is_muted); } } diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi index 9b9dd932a6..6e2d91e5d9 100644 --- a/indra/newview/installers/windows/installer_template.nsi +++ b/indra/newview/installers/windows/installer_template.nsi @@ -786,9 +786,7 @@ RMDir "$INSTDIR" IfFileExists "$INSTDIR" FOLDERFOUND NOFOLDER FOLDERFOUND: -# Silent uninstall always removes all files (/SD IDYES) - MessageBox MB_YESNO $(DeleteProgramFilesMB) /SD IDYES IDNO NOFOLDER - RMDir /r "$INSTDIR" + MessageBox MB_OK $(DeleteProgramFilesMB) /SD IDOK IDOK NOFOLDER NOFOLDER: diff --git a/indra/newview/installers/windows/lang_de.nsi b/indra/newview/installers/windows/lang_de.nsi index 8b4827ec09..fc3ef0e834 100755 Binary files a/indra/newview/installers/windows/lang_de.nsi and b/indra/newview/installers/windows/lang_de.nsi differ diff --git a/indra/newview/installers/windows/lang_en-us.nsi b/indra/newview/installers/windows/lang_en-us.nsi index d9fd222af7..83a6c68caa 100644 Binary files a/indra/newview/installers/windows/lang_en-us.nsi and b/indra/newview/installers/windows/lang_en-us.nsi differ diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 43881e8b5c..e23b9dd861 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -641,12 +641,12 @@ static void settings_to_globals() // LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); - LLVOVolume::sLODFactor = gSavedSettings.getF32("RenderVolumeLODFactor"); + LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR); LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; LLVolumeImplFlexible::sUpdateFactor = gSavedSettings.getF32("RenderFlexTimeFactor"); LLVOTree::sTreeFactor = gSavedSettings.getF32("RenderTreeLODFactor"); - LLVOAvatar::sLODFactor = gSavedSettings.getF32("RenderAvatarLODFactor"); - LLVOAvatar::sPhysicsLODFactor = gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"); + LLVOAvatar::sLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR); + LLVOAvatar::sPhysicsLODFactor = llclamp(gSavedSettings.getF32("RenderAvatarPhysicsLODFactor"), 0.f, MAX_AVATAR_LOD_FACTOR); LLVOAvatar::updateImpostorRendering(gSavedSettings.getU32("RenderAvatarMaxNonImpostors")); LLVOAvatar::sVisibleInFirstPerson = gSavedSettings.getBOOL("FirstPersonAvatarVisible"); // clamp auto-open time to some minimum usable value @@ -1366,15 +1366,19 @@ bool LLAppViewer::init() // updater.args.add(stringize(gSavedSettings.getBOOL("UpdaterWillingToTest"))); // // ForceAddressSize // updater.args.add(stringize(gSavedSettings.getU32("ForceAddressSize"))); -// -// // Run the updater. An exception from launching the updater should bother us. -// LLLeap::create(updater, true); -// } -// else -// { -// LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL; -// } - // +//#if LL_WINDOWS && !LL_RELEASE_FOR_DOWNLOAD && !LL_SEND_CRASH_REPORTS +// // This is neither a release package, nor crash-reporting enabled test build +// // try to run version updater, but don't bother if it fails (file might be missing) +// LLLeap *leap_p = LLLeap::create(updater, false); +// if (!leap_p) +// { +// LL_WARNS("LLLeap") << "Failed to run LLLeap" << LL_ENDL; +// } +//#else +// // Run the updater. An exception from launching the updater should bother us. +// LLLeap::create(updater, true); +//#endif + // // Iterate over --leap command-line options. But this is a bit tricky: if // there's only one, it won't be an array at all. @@ -6368,11 +6372,8 @@ void LLAppViewer::resumeMainloopTimeout( char const* state, F32 secs) { if(secs < 0.0f) { - // Gets called often in display loop - // secs = gSavedSettings.getF32("MainloopTimeoutDefault"); - static LLCachedControl< F32 > MainloopTimeoutDefault( gSavedSettings, "MainloopTimeoutDefault" ); - secs = MainloopTimeoutDefault; - // + static LLCachedControl mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60); + secs = mainloop_timeout; } mMainloopTimeout->setTimeout(secs); @@ -6402,11 +6403,8 @@ void LLAppViewer::pingMainloopTimeout( char const* state, F32 secs) { if(secs < 0.0f) { - // Gets called often in display loop - // secs = gSavedSettings.getF32("MainloopTimeoutDefault"); - static LLCachedControl< F32 > MainloopTimeoutDefault( gSavedSettings, "MainloopTimeoutDefault" ); - secs = MainloopTimeoutDefault; - // + static LLCachedControl mainloop_timeout(gSavedSettings, "MainloopTimeoutDefault", 60); + secs = mainloop_timeout; } mMainloopTimeout->setTimeout(secs); diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index d7f294f83b..eff6eada0e 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -43,6 +43,7 @@ #define LL_LLAPPVIEWER_H #include "llallocator.h" +#include "llapr.h" #include "llcontrol.h" #include "llsys.h" // for LLOSInfo #include "lltimer.h" diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp index 81f04744f8..3111540a13 100644 --- a/indra/newview/llappviewermacosx.cpp +++ b/indra/newview/llappviewermacosx.cpp @@ -411,68 +411,6 @@ std::string LLAppViewerMacOSX::generateSerialNumber() return serial_md5; } -static AudioDeviceID get_default_audio_output_device(void) -{ - AudioDeviceID device = 0; - UInt32 size = sizeof(device); - AudioObjectPropertyAddress device_address = { kAudioHardwarePropertyDefaultOutputDevice, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster }; - - OSStatus err = AudioObjectGetPropertyData(kAudioObjectSystemObject, &device_address, 0, NULL, &size, &device); - if(err != noErr) - { - LL_DEBUGS("SystemMute") << "Couldn't get default audio output device (0x" << std::hex << err << ")" << LL_ENDL; - } - - return device; -} - -//virtual -void LLAppViewerMacOSX::setMasterSystemAudioMute(bool new_mute) -{ - AudioDeviceID device = get_default_audio_output_device(); - - if(device != 0) - { - UInt32 mute = new_mute; - AudioObjectPropertyAddress device_address = { kAudioDevicePropertyMute, - kAudioDevicePropertyScopeOutput, - kAudioObjectPropertyElementMaster }; - - OSStatus err = AudioObjectSetPropertyData(device, &device_address, 0, NULL, sizeof(mute), &mute); - if(err != noErr) - { - LL_INFOS("SystemMute") << "Couldn't set audio mute property (0x" << std::hex << err << ")" << LL_ENDL; - } - } -} - -//virtual -bool LLAppViewerMacOSX::getMasterSystemAudioMute() -{ - // Assume the system isn't muted - UInt32 mute = 0; - - AudioDeviceID device = get_default_audio_output_device(); - - if(device != 0) - { - UInt32 size = sizeof(mute); - AudioObjectPropertyAddress device_address = { kAudioDevicePropertyMute, - kAudioDevicePropertyScopeOutput, - kAudioObjectPropertyElementMaster }; - - OSStatus err = AudioObjectGetPropertyData(device, &device_address, 0, NULL, &size, &mute); - if(err != noErr) - { - LL_DEBUGS("SystemMute") << "Couldn't get audio mute property (0x" << std::hex << err << ")" << LL_ENDL; - } - } - - return (mute != 0); -} - void handleUrl(const char* url_utf8) { if (url_utf8 && gViewerAppPtr) diff --git a/indra/newview/llappviewermacosx.h b/indra/newview/llappviewermacosx.h index ebb41a495c..d5a80864be 100644 --- a/indra/newview/llappviewermacosx.h +++ b/indra/newview/llappviewermacosx.h @@ -42,10 +42,6 @@ public: // virtual bool init(); // Override to do application initialization - // mute/unmute the system's master audio - virtual void setMasterSystemAudioMute(bool mute); - virtual bool getMasterSystemAudioMute(); - protected: virtual bool restoreErrorTrap(); virtual void initCrashReporting(bool reportFreeze); diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp index dd9354fe3a..0516520c56 100644 --- a/indra/newview/llautoreplace.cpp +++ b/indra/newview/llautoreplace.cpp @@ -68,8 +68,8 @@ void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement word_start--; // walk word_start back to the beginning of the word } LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL; - std::string str_text = std::string(input_text.begin(), input_text.end()); - std::string last_word = str_text.substr(word_start, word_end - word_start + 1); + LLWString old_string = input_text.substr(word_start, word_end - word_start + 1); + std::string last_word = wstring_to_utf8str(old_string); std::string replacement_word(mSettings.replaceWord(last_word)); if (replacement_word != last_word) @@ -79,9 +79,8 @@ void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement { // return the replacement string replacement_start = word_start; - replacement_length = last_word.length(); + replacement_length = word_end - word_start + 1; replacement_string = utf8str_to_wstring(replacement_word); - LLWString old_string = utf8str_to_wstring(last_word); S32 size_change = replacement_string.size() - old_string.size(); cursor_pos += size_change; } diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp index bc0813c34a..cb4617631d 100644 --- a/indra/newview/llavatarlistitem.cpp +++ b/indra/newview/llavatarlistitem.cpp @@ -159,6 +159,7 @@ BOOL LLAvatarListItem::postBuild() mIconPermissionEditTheirs->setVisible(false); mSpeakingIndicator = getChild("speaking_indicator"); + mSpeakingIndicator->setChannelState(LLOutputMonitorCtrl::UNDEFINED_CHANNEL); mInfoBtn = getChild("info_btn"); mProfileBtn = getChild("profile_btn"); diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp index aef4084a9f..a18e8938ea 100644 --- a/indra/newview/llchatitemscontainerctrl.cpp +++ b/indra/newview/llchatitemscontainerctrl.cpp @@ -29,6 +29,7 @@ #include "llchatitemscontainerctrl.h" #include "lltextbox.h" +#include "llavataractions.h" #include "llavatariconctrl.h" #include "llcommandhandler.h" #include "llfloaterreg.h" @@ -220,6 +221,7 @@ void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification) mMsgText = getChild("msg_text", false); mMsgText->setContentTrusted(false); + mMsgText->setIsFriendCallback(LLAvatarActions::isFriend); mMsgText->setText(std::string("")); diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp index 7afc4cc9d6..38a6ef6d7a 100644 --- a/indra/newview/llcofwearables.cpp +++ b/indra/newview/llcofwearables.cpp @@ -42,6 +42,7 @@ #include "llwearableitemslist.h" #include "llpaneloutfitedit.h" #include "lltrans.h" +#include "llvoavatarself.h" #include "lltabcontainer.h" static LLPanelInjector t_cof_wearables("cof_wearables"); @@ -341,7 +342,7 @@ void LLCOFWearables::setAttachmentsTitle() { if (mAttachmentsTab) { - U32 free_slots = MAX_AGENT_ATTACHMENTS - mAttachments->size(); + U32 free_slots = gAgentAvatarp->getMaxAttachments() - mAttachments->size(); LLStringUtil::format_map_t args_attachments; args_attachments["[COUNT]"] = llformat ("%d", free_slots); diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp index 6ccf62a6ca..80166f1a10 100644 --- a/indra/newview/llconversationmodel.cpp +++ b/indra/newview/llconversationmodel.cpp @@ -353,7 +353,7 @@ void LLConversationItemSession::setParticipantIsMuted(const LLUUID& participant_ LLConversationItemParticipant* participant = findParticipant(participant_id); if (participant) { - participant->muteVoice(is_muted); + participant->moderateVoice(is_muted); } } @@ -500,6 +500,7 @@ void LLConversationItemSession::onAvatarNameCache(const LLAvatarName& av_name) LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : LLConversationItem(display_name,uuid,root_view_model), + mIsModeratorMuted(false), mIsModerator(false), mDisplayModeratorLabel(false), mDistToAgent(-1.0) @@ -510,6 +511,7 @@ LLConversationItemParticipant::LLConversationItemParticipant(std::string display LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) : LLConversationItem(uuid,root_view_model), + mIsModeratorMuted(false), mIsModerator(false), mDisplayModeratorLabel(false), mDistToAgent(-1.0) @@ -599,25 +601,7 @@ void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole) bool LLConversationItemParticipant::isVoiceMuted() { - return LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat); -} - -void LLConversationItemParticipant::muteVoice(bool mute_voice) -{ - LLAvatarName av_name; - LLAvatarNameCache::get(mUUID, &av_name); - LLMuteList * mute_listp = LLMuteList::getInstance(); - bool voice_already_muted = mute_listp->isMuted(mUUID, av_name.getUserName()); - - LLMute mute(mUUID, av_name.getUserName(), LLMute::AGENT); - if (voice_already_muted && !mute_voice) - { - mute_listp->remove(mute); - } - else if (!voice_already_muted && mute_voice) - { - mute_listp->add(mute); - } + return mIsModeratorMuted || LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat); } // diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 0cd9e624b2..fbdffc4997 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -197,8 +197,9 @@ public: virtual const std::string& getDisplayName() const { return mDisplayName; } bool isVoiceMuted(); + bool isModeratorMuted() { return mIsModeratorMuted; } bool isModerator() const { return mIsModerator; } - void muteVoice(bool mute_voice); + void moderateVoice(bool mute_voice) { mIsModeratorMuted = mute_voice; } void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; } void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; } void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; } @@ -219,6 +220,7 @@ private: void onAvatarNameCache(const LLAvatarName& av_name); // callback used by fetchAvatarName void updateName(const LLAvatarName& av_name); + bool mIsModeratorMuted; // default is false bool mIsModerator; // default is false bool mDisplayModeratorLabel; // default is false std::string mDisplayName; diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp index 240a9d7702..0260b748de 100644 --- a/indra/newview/llconversationview.cpp +++ b/indra/newview/llconversationview.cpp @@ -236,6 +236,8 @@ void LLConversationViewSession::draw() // Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap. bool draw_children = getRoot() == static_cast(this) || isOpen(); + // Todo/fix this: arrange hides children 'out of bonds', session 'slowly' adjusts container size, unhides children + // this process repeats until children fit for (folders_t::iterator iter = mFolders.begin(); iter != mFolders.end();) { @@ -256,9 +258,6 @@ void LLConversationViewSession::draw() updateLabelRotation(); drawOpenFolderArrow(default_params, sFgColor); } - - refresh(); - LLView::draw(); } @@ -443,28 +442,23 @@ void LLConversationViewSession::refresh() LLSpeakingIndicatorManager::updateSpeakingIndicators(); // we should show indicator for specified voice session only if this is current channel. EXT-5562. - if (!mIsInActiveVoiceChannel) + if (mSpeakingIndicator) { - if (mSpeakingIndicator) + mSpeakingIndicator->setIsActiveChannel(mIsInActiveVoiceChannel); + mSpeakingIndicator->setShowParticipantsSpeaking(mIsInActiveVoiceChannel); + } + + LLConversationViewParticipant* participant = NULL; + items_t::const_iterator iter; + for (iter = getItemsBegin(); iter != getItemsEnd(); iter++) + { + participant = dynamic_cast(*iter); + if (participant) { - mSpeakingIndicator->setVisible(false); - } - LLConversationViewParticipant* participant = NULL; - items_t::const_iterator iter; - for (iter = getItemsBegin(); iter != getItemsEnd(); iter++) - { - participant = dynamic_cast(*iter); - if (participant) - { - participant->hideSpeakingIndicator(); - } + participant->allowSpeakingIndicator(mIsInActiveVoiceChannel); } } - - if (mSpeakingIndicator) - { - mSpeakingIndicator->setShowParticipantsSpeaking(mIsInActiveVoiceChannel); - } + requestArrange(); // Do the regular upstream refresh LLFolderViewFolder::refresh(); @@ -476,8 +470,13 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi if (vmi) { + bool old_value = mIsInActiveVoiceChannel; mIsInActiveVoiceChannel = vmi->getUUID() == session_id; mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel); + if (old_value != mIsInActiveVoiceChannel) + { + refresh(); + } } } @@ -570,6 +569,7 @@ void LLConversationViewParticipant::draw() F32 text_left = (F32)getLabelXPos(); LLColor4 color; + LLLocalSpeakerMgr *speakerMgr = LLLocalSpeakerMgr::getInstance(); if (speakerMgr && speakerMgr->isSpeakerToBeRemoved(mUUID)) @@ -581,9 +581,14 @@ void LLConversationViewParticipant::draw() color = mIsSelected ? sHighlightFgColor : sFgColor; } + LLConversationItemParticipant* participant_model = dynamic_cast(getViewModelItem()); + if (participant_model) + { + mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted()); + } + drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor); drawLabel(font, text_left, y, color, right_x); - refresh(); LLView::draw(); } @@ -607,16 +612,39 @@ S32 LLConversationViewParticipant::arrange(S32* width, S32* height) return arranged; } +// virtual +void LLConversationViewParticipant::refresh() +{ + // Refresh the participant view from its model data + LLConversationItemParticipant* participant_model = dynamic_cast(getViewModelItem()); + participant_model->resetRefresh(); + + // *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat + mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted()); + + // Do the regular upstream refresh + LLFolderViewItem::refresh(); +} + void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder) { // Add the item to the folder (conversation) LLFolderViewItem::addToFolder(folder); // Retrieve the folder (conversation) UUID, which is also the speaker session UUID - LLConversationItem* vmi = getParentFolder() ? dynamic_cast(getParentFolder()->getViewModelItem()) : NULL; - if (vmi) + LLFolderViewFolder *prnt = getParentFolder(); + if (prnt) { - addToSession(vmi->getUUID()); + LLConversationItem* vmi = dynamic_cast(prnt->getViewModelItem()); + if (vmi) + { + addToSession(vmi->getUUID()); + } + LLConversationViewSession* session = dynamic_cast(prnt); + if (session) + { + allowSpeakingIndicator(session->isInActiveVoiceChannel()); + } } } @@ -746,9 +774,9 @@ LLView* LLConversationViewParticipant::getItemChildView(EAvatarListItemChildInde return child_view; } -void LLConversationViewParticipant::hideSpeakingIndicator() +void LLConversationViewParticipant::allowSpeakingIndicator(bool val) { - mSpeakingIndicator->setVisible(false); + mSpeakingIndicator->setIsActiveChannel(val); } // EOF diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h index 76da653c26..fb14d32a71 100644 --- a/indra/newview/llconversationview.h +++ b/indra/newview/llconversationview.h @@ -92,6 +92,7 @@ public: void setHighlightState(bool hihglight_state); LLFloater* getSessionFloater(); + bool isInActiveVoiceChannel() { return mIsInActiveVoiceChannel; } private: @@ -138,6 +139,7 @@ public: virtual ~LLConversationViewParticipant( void ); bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); } + /*virtual*/ void refresh(); void addToFolder(LLFolderViewFolder* folder); void addToSession(const LLUUID& session_id); @@ -146,7 +148,7 @@ public: /*virtual*/ S32 getLabelXPos(); /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask ); - void hideSpeakingIndicator(); + void allowSpeakingIndicator(bool val); protected: friend class LLUICtrlFactory; diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index af6977d3cd..83a6e9f279 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -125,17 +125,11 @@ BOOL LLViewerDynamicTexture::render() //----------------------------------------------------------------------------- void LLViewerDynamicTexture::preRender(BOOL clear_depth) { - // changes to support higher resolution rendering in the preview - ////only images up to 512x512 are supported - //llassert(mFullHeight <= 512); - //llassert(mFullWidth <= 512); gPipeline.allocatePhysicsBuffer(); llassert(mFullWidth <= static_cast(gPipeline.mPhysicsDisplay.getWidth())); llassert(mFullHeight <= static_cast(gPipeline.mPhysicsDisplay.getHeight())); -// if (gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI) if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI) -// { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -221,12 +215,10 @@ BOOL LLViewerDynamicTexture::updateAllInstances() { return TRUE; } - // changes to support higher resolution rendering in the preview - // bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mWaterDis.isComplete() && !gGLManager.mIsATI; + bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsATI; if (use_fbo) { -// gPipeline.mWaterDis.bindTarget(); gPipeline.mPhysicsDisplay.bindTarget(); } // @@ -265,10 +257,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() if (use_fbo) { - // changes to support higher resolution rendering in the preview - // gPipeline.mWaterDis.flush(); gPipeline.mPhysicsDisplay.flush(); - // } return ret; diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp index f13d24960d..1aa794cab9 100644 --- a/indra/newview/llfloateravatarpicker.cpp +++ b/indra/newview/llfloateravatarpicker.cpp @@ -967,7 +967,7 @@ bool LLFloaterAvatarPicker::isSelectBtnEnabled() { bool ret_val = visibleItemsSelected(); - if ( ret_val ) + if ( ret_val && !isMinimized()) { std::string acvtive_panel_name; LLScrollListCtrl* list = NULL; diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp index 54f7a16e1e..34d85dbd3b 100644 --- a/indra/newview/llfloaterconversationpreview.cpp +++ b/indra/newview/llfloaterconversationpreview.cpp @@ -58,6 +58,7 @@ LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_i mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")), mAccountName(session_id[LL_FCP_ACCOUNT_NAME]), mCompleteName(session_id[LL_FCP_COMPLETE_NAME]), + mMutex(), mShowHistory(false), mMessages(NULL), mHistoryThreadsBusy(false), diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp index deb4c109b0..121a621dd5 100644 --- a/indra/newview/llfloaterimcontainer.cpp +++ b/indra/newview/llfloaterimcontainer.cpp @@ -270,6 +270,9 @@ BOOL LLFloaterIMContainer::postBuild() // When display name option change, we need to reload all participant names LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this)); + mParticipantRefreshTimer.setTimerExpirySec(0); + mParticipantRefreshTimer.start(); + return TRUE; } @@ -421,14 +424,66 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate() void LLFloaterIMContainer::idle(void* user_data) { LLFloaterIMContainer* self = static_cast(user_data); - - // Update the distance to agent in the nearby chat session if required - // Note: it makes no sense of course to update the distance in other session - if (self->mConversationViewModel.getSorter().getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE) - { - self->setNearbyDistances(); - } - self->mConversationsRoot->update(); + + if (!self->getVisible() || self->isMinimized()) + { + return; + } + self->idleUpdate(); +} + +void LLFloaterIMContainer::idleUpdate() +{ + if (mTabContainer->getTabCount() == 0) + { + // Do not close the container when every conversation is torn off because the user + // still needs the conversation list. Simply collapse the message pane in that case. + collapseMessagesPane(true); + } + + U32 sort_order = mConversationViewModel.getSorter().getSortOrderParticipants(); + + if (mParticipantRefreshTimer.hasExpired()) + { + const LLConversationItem *current_session = getCurSelectedViewModelItem(); + if (current_session) + { + // Update moderator options visibility + LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin(); + LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd(); + bool is_moderator = isGroupModerator(); + bool can_ban = haveAbilityToBan(); + while (current_participant_model != end_participant_model) + { + LLConversationItemParticipant* participant_model = dynamic_cast(*current_participant_model); + participant_model->setModeratorOptionsVisible(is_moderator && participant_model->getUUID() != gAgentID); + participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID); + + current_participant_model++; + } + // Update floater's title as required by the currently selected session or use the default title + LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID()); + setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle); + } + + mParticipantRefreshTimer.setTimerExpirySec(1.0f); + } + + // Update the distance to agent in the nearby chat session if required + // Note: it makes no sense of course to update the distance in other session + if (sort_order == LLConversationFilter::SO_DISTANCE) + { + // almost real-time updates + setNearbyDistances(); //calls arrange all + } + mConversationsRoot->update(); //arranges, resizes, heavy + + // "Manually" resize of mConversationsPane: same as temporarity cancellation of the flag "auto_resize=false" for it + if (!mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()) + { + LLRect stack_rect = mConversationsStack->getRect(); + mConversationsPane->reshape(stack_rect.getWidth(), stack_rect.getHeight(), true); + } } bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event) @@ -527,39 +582,6 @@ bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event) void LLFloaterIMContainer::draw() { - if (mTabContainer->getTabCount() == 0) - { - // Do not close the container when every conversation is torn off because the user - // still needs the conversation list. Simply collapse the message pane in that case. - collapseMessagesPane(true); - } - - const LLConversationItem *current_session = getCurSelectedViewModelItem(); - if (current_session) - { - // Update moderator options visibility - LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin(); - LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd(); - while (current_participant_model != end_participant_model) - { - LLConversationItemParticipant* participant_model = dynamic_cast(*current_participant_model); - participant_model->setModeratorOptionsVisible(isGroupModerator() && participant_model->getUUID() != gAgentID); - participant_model->setGroupBanVisible(haveAbilityToBan() && participant_model->getUUID() != gAgentID); - - current_participant_model++; - } - // Update floater's title as required by the currently selected session or use the default title - LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID()); - setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle); - } - - // "Manually" resize of mConversationsPane: same as temporarity cancellation of the flag "auto_resize=false" for it - if (!mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()) - { - LLRect stack_rect = mConversationsStack->getRect(); - mConversationsPane->reshape(stack_rect.getWidth(), stack_rect.getHeight(), true); - } - LLFloater::draw(); } diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h index 4a0afaadc9..1ff65ca46f 100644 --- a/indra/newview/llfloaterimcontainer.h +++ b/indra/newview/llfloaterimcontainer.h @@ -182,6 +182,8 @@ private: void openNearbyChat(); bool isParticipantListExpanded(); + void idleUpdate(); // for convenience (self) from static idle + LLButton* mExpandCollapseBtn; LLButton* mStubCollapseBtn; LLButton* mSpeakBtn; @@ -228,6 +230,8 @@ private: LLConversationViewModel mConversationViewModel; LLFolderView* mConversationsRoot; LLEventStream mConversationsEventStream; + + LLTimer mParticipantRefreshTimer; }; #endif // LL_LLFLOATERIMCONTAINER_H diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp index 41653423a7..4a7e930a8f 100644 --- a/indra/newview/llfloaterland.cpp +++ b/indra/newview/llfloaterland.cpp @@ -480,6 +480,7 @@ BOOL LLPanelLandGeneral::postBuild() mTextSalePending = getChild("SalePending"); mTextOwnerLabel = getChild("Owner:"); mTextOwner = getChild("OwnerText"); + mTextOwner->setIsFriendCallback(LLAvatarActions::isFriend); mContentRating = getChild("ContentRatingText"); mLandType = getChild("LandTypeText"); @@ -1313,6 +1314,7 @@ BOOL LLPanelLandObjects::postBuild() mIconGroup = LLUIImageList::getInstance()->getUIImage("icon_group.tga", 0); mOwnerList = getChild("owner list"); + mOwnerList->setIsFriendCallback(LLAvatarActions::isFriend); mOwnerList->sortByColumnIndex(3, FALSE); childSetCommitCallback("owner list", onCommitList, this); mOwnerList->setDoubleClickCallback(onDoubleClickOwner, this); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 2e06d3d09f..c965f933b1 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -310,10 +310,10 @@ BOOL LLFloaterModelPreview::postBuild() getChild("lod_triangle_limit_" + lod_name[lod])->setCommitCallback(boost::bind(&LLFloaterModelPreview::onLODParamCommit, this, lod, true)); } - childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); - childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); - childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); - childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this), NULL); + childSetCommitCallback("upload_skin", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL); + childSetCommitCallback("upload_joints", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL); + childSetCommitCallback("lock_scale_if_joint_position", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL); + childSetCommitCallback("upload_textures", boost::bind(&LLFloaterModelPreview::onUploadOptionChecked, this, _1), NULL); childSetTextArg("status", "[STATUS]", getString("status_idle")); @@ -465,33 +465,53 @@ void LLFloaterModelPreview::initModelPreview() { delete mModelPreview; } + + S32 tex_width = 512; + S32 tex_height = 512; + + S32 max_width = llmin(gSavedSettings.getS32("PreviewRenderSize"), (S32)gPipeline.mScreenWidth); + S32 max_height = llmin(gSavedSettings.getS32("PreviewRenderSize"), (S32)gPipeline.mScreenHeight); - S32 tex_width = 512; - S32 tex_height = 512; - - S32 max_width = llmin(gSavedSettings.getS32("PreviewRenderSize"), (S32)gPipeline.mScreenWidth); - S32 max_height = llmin(gSavedSettings.getS32("PreviewRenderSize"), (S32)gPipeline.mScreenHeight); - - while ((tex_width << 1) <= max_width) - { - tex_width <<= 1; - } - while ((tex_height << 1) <= max_height) - { - tex_height <<= 1; - } - - mModelPreview = new LLModelPreview(tex_width, tex_height, this); + while ((tex_width << 1) <= max_width) + { + tex_width <<= 1; + } + while ((tex_height << 1) <= max_height) + { + tex_height <<= 1; + } + + mModelPreview = new LLModelPreview(tex_width, tex_height, this); mModelPreview->setPreviewTarget(16.f); mModelPreview->setDetailsCallback(boost::bind(&LLFloaterModelPreview::setDetails, this, _1, _2, _3, _4, _5)); mModelPreview->setModelUpdatedCallback(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, _1)); } +void LLFloaterModelPreview::onUploadOptionChecked(LLUICtrl* ctrl) +{ + if (mModelPreview) + { + auto name = ctrl->getName(); + mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name]; + } + toggleCalculateButton(true); +} + void LLFloaterModelPreview::onViewOptionChecked(LLUICtrl* ctrl) { if (mModelPreview) { + // + //auto name = ctrl->getName(); + //mModelPreview->mViewOption[name] = !mModelPreview->mViewOption[name]; + //if (name == "show_physics") + //{ + // auto enabled = mModelPreview->mViewOption[name]; + // childSetEnabled("physics_explode", enabled); + // childSetVisible("physics_explode", enabled); + //} mModelPreview->mViewOption[ctrl->getName()] = !mModelPreview->mViewOption[ctrl->getName()]; + // mModelPreview->refresh(); } } @@ -676,6 +696,7 @@ void LLFloaterModelPreview::onGenerateNormalsCommit(LLUICtrl* ctrl, void* userda void LLFloaterModelPreview::toggleGenarateNormals() { bool enabled = childGetValue("gen_normals").asBoolean(); + mModelPreview->mViewOption["gen_normals"] = enabled; childSetEnabled("crease_angle", enabled); if(enabled) { mModelPreview->generateNormals(); @@ -719,7 +740,6 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit) } } -// extracted method to simplify changes in layout void LLFloaterModelPreview::draw3dPreview() { gGL.color3f(1.f, 1.f, 1.f); @@ -727,6 +747,7 @@ void LLFloaterModelPreview::draw3dPreview() gGL.getTexUnit(0)->bind(mModelPreview); + LLView* preview_panel = getChild("preview_panel"); if (!preview_panel) @@ -1245,10 +1266,8 @@ void LLFloaterModelPreview::initDecompControls() std::string label = llformat("%.1f", value); combo_box->add(label, value, ADD_BOTTOM, true); } - combo_box->setValue(param[i].mDefault.mFloat); - } - + combo_box->setValue(param[i].mDefault.mFloat); combo_box->setCommitCallback(onPhysicsParamCommit, (void*) ¶m[i]); } } @@ -1320,7 +1339,7 @@ void LLFloaterModelPreview::initDecompControls() //LL_INFOS() << "-----------------------------" << LL_ENDL; } } - + mDefaultDecompParams = mDecompParams; childSetCommitCallback("physics_explode", LLFloaterModelPreview::onExplodeCommit, this); } @@ -1354,7 +1373,7 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl //----------------------------------------------------------------------------- LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) -: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE) +: LLViewerDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE), LLMutex() , mLodsQuery() , mLodsWithParsingError() , mPelvisZOffset( 0.0f ) @@ -1364,7 +1383,7 @@ LLModelPreview::LLModelPreview(S32 width, S32 height, LLFloater* fmp) , mResetJoints( false ) , mModelNoErrors( true ) , mLastJointUpdate( false ) -, mHasDegenerate( false ) // +, mHasDegenerate( false ) { mNeedsUpdate = TRUE; mCameraDistance = 0.f; @@ -1570,8 +1589,6 @@ void LLModelPreview::rebuildUploadData() std::string requested_name = mFMP->getChild("description_form")->getValue().asString(); - std::string metric = mFMP->getChild("model_category_combo")->getValue().asString(); - LLSpinCtrl* scale_spinner = mFMP->getChild("import_scale"); F32 scale = scale_spinner->getValue().asReal(); @@ -1612,7 +1629,6 @@ void LLModelPreview::rebuildUploadData() if (base_model && !requested_name.empty()) { base_model->mRequestedLabel = requested_name; - base_model->mMetric = metric; } for (int i = LLModel::NUM_LODS - 1; i >= LLModel::LOD_IMPOSTOR; i--) @@ -2954,7 +2970,7 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim void LLModelPreview::updateStatusMessages() { -// bit mask values for physics errors. used to prevent overwrite of single line status +// bit mask values for physics errors. used to prevent overwrite of single line status // TODO: use this to provied multiline status enum PhysicsError { @@ -2964,10 +2980,10 @@ void LLModelPreview::updateStatusMessages() TOOMANYHULLS=4, TOOMANYVERTSINHULL=8 }; -// + assert_main_thread(); - U32 has_physics_error{ PhysicsError::NONE }; // physics error bitmap + U32 has_physics_error{ PhysicsError::NONE }; // physics error bitmap //triangle/vertex/submesh count for each mesh asset for each lod std::vector tris[LLModel::NUM_LODS]; std::vector verts[LLModel::NUM_LODS]; @@ -3056,38 +3072,25 @@ void LLModelPreview::updateStatusMessages() { mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH]; } - // make has_degenerate a member so that we can use it in the render method - // has_degenerate = false + mHasDegenerate = false; {//check for degenerate triangles in physics mesh U32 lod = LLModel::LOD_PHYSICS; const LLVector4a scale(0.5f); - for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i)// make has_degenerate a member + for (U32 i = 0; i < mModel[lod].size() && !mHasDegenerate; ++i) { //for each model in the lod if (mModel[lod][i] && mModel[lod][i]->mPhysics.mHull.empty()) { //no decomp exists S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces(); - for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j)// make has_degenerate a member + for (S32 j = 0; j < cur_submeshes && !mHasDegenerate; ++j) { //for each submesh (face), add triangles and vertices to current total LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j); - for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; )// make has_degenerate a member + for (S32 k = 0; (k < face.mNumIndices) && !mHasDegenerate; ) { - U16 index_a = face.mIndices[k+0]; - U16 index_b = face.mIndices[k+1]; - U16 index_c = face.mIndices[k+2]; - // FIRE-23367/23387 - Allow forced empty triangle placeholders created by the LOD processing. - // LLVector4a v1; v1.setMul(face.mPositions[index_a], scale); - // LLVector4a v2; v2.setMul(face.mPositions[index_b], scale); - // LLVector4a v3; v3.setMul(face.mPositions[index_c], scale); + U16 index_a = face.mIndices[k + 0]; + U16 index_b = face.mIndices[k + 1]; + U16 index_c = face.mIndices[k + 2]; - // if (ll_is_degenerate(v1, v2, v3)) - // { - // mHasDegenerate = true;// make has_degenerate a member - // } - // else - // { - // k += 3; - // } if (index_c == 0 && index_b == 0 && index_a == 0) // test in reverse as 3rd index is less likely to be 0 in a normal case { LL_DEBUGS("MeshValidation") << "Empty placeholder triangle (3 identical index 0 verts) ignored" << LL_ENDL; @@ -3099,23 +3102,31 @@ void LLModelPreview::updateStatusMessages() LLVector4a v3; v3.setMul(face.mPositions[index_c], scale); if (ll_is_degenerate(v1, v2, v3)) { - mHasDegenerate = true;// make has_degenerate a member + mHasDegenerate = true; } } k += 3; - // } } } } } - // flag degenerates here rather than deferring to a MAV error later + // flag degenerates here rather than deferring to a MAV error later + // + //mFMP->childSetVisible("physics_status_message_text", mHasDegenerate); //display or clear + //auto degenerateIcon = mFMP->getChild("physics_status_message_icon"); + //degenerateIcon->setVisible(mHasDegenerate); + // if (mHasDegenerate) { has_physics_error |= PhysicsError::DEGENERATE; + // + //mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_degenerate_triangles")); + //LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Error"); + //degenerateIcon->setImage(img); + // } - // mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH])); @@ -3258,16 +3269,16 @@ void LLModelPreview::updateStatusMessages() } // standardise error handling - //if (!(has_physics_error & PhysicsError::DEGENERATE)){ // only update this field (incluides clearing it) if it is not already in use. - // mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit); - // LLIconCtrl* physStatusIcon = mFMP->getChild("physics_status_message_icon"); - // physStatusIcon->setVisible(physExceededVertexLimit); - // if (physExceededVertexLimit) - // { - // mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded")); - // LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning"); - // physStatusIcon->setImage(img); - // } + //if (!(has_physics_error & PhysicsError::DEGENERATE)){ // only update this field (incluides clearing it) if it is not already in use. + // mFMP->childSetVisible("physics_status_message_text", physExceededVertexLimit); + // LLIconCtrl* physStatusIcon = mFMP->getChild("physics_status_message_icon"); + // physStatusIcon->setVisible(physExceededVertexLimit); + // if (physExceededVertexLimit) + // { + // mFMP->childSetValue("physics_status_message_text", mFMP->getString("phys_status_vertex_limit_exceeded")); + // LLUIImagePtr img = LLUI::getUIImage("ModelImport_Status_Warning"); + // physStatusIcon->setImage(img); + // } //} #ifdef OPENSIM has_physics_error |= PhysicsError::NOHAVOK; @@ -3345,12 +3356,9 @@ void LLModelPreview::updateStatusMessages() } } // Improve the error checking the TO DO here is no longer applicable but not an FS comment so edited to stop it being picked up - //// To do investigate use of has_degenerate and include into mModelNoErrors upload blocking mechanics - //// current use of has_degenerate won't block upload permanently - later checks will restore the button //if (!mModelNoErrors || mHasDegenerate) - //{ - // mFMP->childDisable("ok_btn"); - if ((gSavedSettings.getBOOL("FSIgnoreClientsideMeshValidation")==FALSE) && (!mModelNoErrors || (has_physics_error > PhysicsError::NOHAVOK))) // block for all cases of phsyics error except NOHAVOK + if (!gSavedSettings.getBOOL("FSIgnoreClientsideMeshValidation") && (!mModelNoErrors || (has_physics_error > PhysicsError::NOHAVOK))) // block for all cases of phsyics error except NOHAVOK + // { mFMP->childDisable("ok_btn"); mFMP->childDisable("calculate_btn"); @@ -3429,14 +3437,14 @@ void LLModelPreview::updateStatusMessages() mViewOption["show_physics"] = true; fmp->childSetValue("show_physics", true); } - // handle hiding of hull only explode slider - //else - //{ - // fmp->disableViewOption("show_physics"); - // mViewOption["show_physics"] = false; - // fmp->childSetValue("show_physics", false); - - //} + // handle hiding of hull only explode slider + //} + //else + //{ + // fmp->disableViewOption("show_physics"); + // mViewOption["show_physics"] = false; + // fmp->childSetValue("show_physics", false); + //} mViewOption["show_physics"] = true; if (phys_hulls > 0) { @@ -3755,7 +3763,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) } vb = new LLVertexBuffer(mask, 0); - + if (!vb->allocateBuffer(num_vertices, num_indices, TRUE)) { // We are likely to crash due this failure, if this happens, find a way to gracefully stop preview @@ -4024,7 +4032,7 @@ BOOL LLModelPreview::render() bool physics = mViewOption["show_physics"]; bool uv_guide = mViewOption["show_uv_guide"]; // Add UV guide overlay in mesh preview - // Extra configurability, to be exposed later as controls? + // Extra configurability, to be exposed later as controls? static LLCachedControl canvas_col(gSavedSettings, "MeshPreviewCanvasColor"); static LLCachedControl edge_col(gSavedSettings, "MeshPreviewEdgeColor"); static LLCachedControl base_col(gSavedSettings, "MeshPreviewBaseColor"); @@ -4037,16 +4045,12 @@ BOOL LLModelPreview::render() static LLCachedControl deg_fill_col(gSavedSettings, "MeshPreviewDegenerateFillColor"); static LLCachedControl deg_edge_width(gSavedSettings, "MeshPreviewDegenerateEdgeWidth"); static LLCachedControl deg_point_size(gSavedSettings, "MeshPreviewDegeneratePointSize"); - // + S32 width = getWidth(); S32 height = getHeight(); LLGLSUIDefault def; LLGLDisable no_blend(GL_BLEND); -// Clean up render of mesh preview -// LLGLEnable blend(GL_BLEND); -// gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); -// LLGLEnable cull(GL_CULL_FACE); LLGLDepthTest depth(GL_TRUE); @@ -4066,8 +4070,7 @@ BOOL LLModelPreview::render() gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); gGL.loadIdentity(); - // uploader improvements - //gGL.color4f(0.169f, 0.169f, 0.169f, 1.f); + gGL.color4fv(static_cast(canvas_col).mV); gl_rect_2d_simple( width, height ); @@ -4216,11 +4219,7 @@ BOOL LLModelPreview::render() stop_glerror(); gGL.pushMatrix(); - // mesh uploader improvements configurable brightness - //const F32 BRIGHTNESS = 0.9f; - //gGL.color3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); gGL.color4fv(edge_col().mV); - // const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; @@ -4302,12 +4301,8 @@ BOOL LLModelPreview::render() mTextureSet.insert(tex); } } - // improved mesh uploader - // else - // { - // gGL.diffuseColor4f(1,1,1,1); - // } } + // improved mesh uploader else if (uv_guide) { if(mUVGuideTexture) @@ -4320,19 +4315,15 @@ BOOL LLModelPreview::render() gGL.diffuseColor4fv(static_cast(base_col).mV); } + // else { - // gGL.diffuseColor4f(1,1,1,1); gGL.diffuseColor4fv(static_cast(base_col).mV); - // } buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - // improved mesh uploader - //gGL.diffuseColor3f(0.4f, 0.4f, 0.4f); gGL.diffuseColor4fv(static_cast(edge_col).mV); - // if (edges) { glLineWidth(edge_width); @@ -4347,25 +4338,10 @@ BOOL LLModelPreview::render() if (physics) { - // model upload improvements - use the settings - ////Vector4a physicsFillColour(0.4, 0.4, 0.4, 0.4); - //const LLColor4 physicsFillColour(0.0, 0.5, 1.0, 0.5); - ////LLVector4a physicsEdgeColour(1.0, 1.0, 0.0, 1.0); - //const LLColor4 physicsEdgeColour=physicsFillColour*0.5; - //const LLColor4 degenerateFill(1.0, 0.0, 0.0, 0.5); - //const LLColor4 degenerateEdge(1.0,0.0,0.0,1.0); - // - glClear(GL_DEPTH_BUFFER_BIT); - // refactor to remove silly variable names - // for (U32 i = 0; i < 2; i++) for (U32 pass = 0; pass < 2; pass++) - // { - // refactor to remove silly variable names - //if (i == 0) if (pass == 0) - // { //depth only pass gGL.setColorMask(false, false); } @@ -4375,10 +4351,7 @@ BOOL LLModelPreview::render() } //enable alpha blending on second pass but not first pass - // refactor to remove silly variable names - //LLGLState blend(GL_BLEND, i); LLGLState blend(GL_BLEND, pass); - // gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); @@ -4482,16 +4455,11 @@ BOOL LLModelPreview::render() gGL.popMatrix(); } - // refactor to remove silly variable names - // also only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks] - //if (i > 0) + // only do this if mDegenerate was set in the preceding mesh checks [Check this if the ordering ever breaks] if (pass > 0 && mHasDegenerate) - // { glLineWidth(deg_edge_width); glPointSize(deg_point_size); -// This single line is why the degenerate triangles display has been crap forever. -// gPipeline.enableLightsFullbright(LLColor4::white); //show degenerate triangles LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); LLGLDisable cull(GL_CULL_FACE); @@ -4529,13 +4497,10 @@ BOOL LLModelPreview::render() } auto num_degenerate = 0; - // More nested i variable silliness - // for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i) auto num_models = mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); for (U32 v = 0; v < num_models; ++v) { LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v]; - // if(buffer->getNumVerts() < 3)continue; buffer->setBuffer(type_mask & buffer->getTypeMask()); @@ -4548,7 +4513,6 @@ BOOL LLModelPreview::render() buffer->getIndexStrider(idx, 0); LLVector4a v1, v2, v3; - // rename inner most i to avoid merge confusion for (U32 indices_offset = 0; indices_offset < buffer->getNumIndices(); indices_offset += 3) { v1.setMul(pos[*idx++], scale); @@ -4621,7 +4585,7 @@ BOOL LLModelPreview::render() LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT]; const LLMeshSkinInfo *skin = &model->mSkinInfo; U32 count = LLSkinningUtil::getMeshJointCount(skin); - //LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, + //LLSkinningUtil::initSkinningMatrixPalette((LLMatrix4*)mat, count, // skin, getPreviewAvatar()); LLSkinningUtil::initSkinningMatrixPalette(mat, count, skin, getPreviewAvatar()); @@ -4680,8 +4644,6 @@ BOOL LLModelPreview::render() } // buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0); - // configurable colour and width - //gGL.diffuseColor3f(0.4f, 0.4f, 0.4f); if (edges) { @@ -4692,7 +4654,6 @@ BOOL LLModelPreview::render() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1.f); } - // } } } @@ -4750,11 +4711,9 @@ void LLModelPreview::rotate(F32 yaw_radians, F32 pitch_radians) void LLModelPreview::zoom(F32 zoom_amt) { F32 new_zoom = mCameraZoom+zoom_amt; - // add configurable zoom TODO: stop clamping in render - // mCameraZoom = llclamp(new_zoom, 1.f, 10.f); + // TODO: stop clamping in render static LLCachedControl zoom_limit(gSavedSettings, "MeshPreviewZoomLimit"); mCameraZoom = llclamp(new_zoom, 1.f, zoom_limit()); - // } void LLModelPreview::pan(F32 right, F32 up) @@ -4818,6 +4777,7 @@ void LLFloaterModelPreview::onReset(void* user_data) std::string filename = mp->mLODFile[LLModel::LOD_HIGH]; fmp->resetDisplayOptions(); + fmp->resetUploadOptions(); //reset model preview fmp->initModelPreview(); @@ -4931,11 +4891,6 @@ void LLFloaterModelPreview::setStatusMessage(const std::string& msg) mStatusMessage = msg; } -void LLFloaterModelPreview::toggleCalculateButton() -{ - toggleCalculateButton(true); -} - void LLFloaterModelPreview::toggleCalculateButton(bool visible) { mCalculateBtn->setVisible(visible); @@ -4962,12 +4917,6 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible) childSetTextArg("server_weight", "[SIM]", tbd); childSetTextArg("physics_weight", "[PH]", tbd); childSetTextArg("upload_fee", "[FEE]", tbd); - // add extended info fields - //childSetTextArg("price_breakdown", "[STREAMING]", dashes); - //childSetTextArg("price_breakdown", "[PHYSICS]", dashes); - //childSetTextArg("price_breakdown", "[INSTANCES]", dashes); - //childSetTextArg("price_breakdown", "[TEXTURES]", dashes); - //childSetTextArg("price_breakdown", "[MODEL]", dashes); std::string dashes = hasString("--") ? getString("--") : "--"; childSetTextArg("price_breakdown", "[STREAMING]", dashes); childSetTextArg("price_breakdown", "[PHYSICS]", dashes); @@ -4977,7 +4926,6 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible) childSetTextArg("physics_breakdown", "[PCH]", dashes); childSetTextArg("physics_breakdown", "[PM]", dashes); childSetTextArg("physics_breakdown", "[PHU]", dashes); - // } } @@ -5004,6 +4952,37 @@ void LLFloaterModelPreview::resetDisplayOptions() } } +void LLFloaterModelPreview::resetUploadOptions() +{ + childSetValue("import_scale", 1); + childSetValue("pelvis_offset", 0); + childSetValue("physics_explode", 0); + childSetValue("physics_file", ""); + childSetVisible("Retain%", false); + childSetVisible("Retain%_label", false); + childSetVisible("Detail Scale", true); + childSetVisible("Detail Scale label", true); + + getChild("lod_source_" + lod_name[NUM_LOD - 1])->setCurrentByIndex(LLModelPreview::LOD_FROM_FILE); + for (S32 lod = 0; lod < NUM_LOD - 1; ++lod) + { + getChild("lod_source_" + lod_name[lod])->setCurrentByIndex(LLModelPreview::GENERATE); + childSetValue("lod_file_" + lod_name[lod], ""); + } + + getChild("physics_lod_combo")->setCurrentByIndex(0); + + for(auto& p : mDefaultDecompParams) + { + std::string ctrl_name(p.first); + LLUICtrl* ctrl = getChild(ctrl_name); + if (ctrl) + { + ctrl->setValue(p.second); + } + } +} + void LLFloaterModelPreview::onModelPhysicsFeeReceived(const LLSD& result, std::string upload_url) { mModelPhysicsFee = result; @@ -5027,7 +5006,7 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived() childSetTextArg("price_breakdown", "[INSTANCES]", llformat("%d", result["upload_price_breakdown"]["mesh_instance"].asInteger())); childSetTextArg("price_breakdown", "[TEXTURES]", llformat("%d", result["upload_price_breakdown"]["texture"].asInteger())); childSetTextArg("price_breakdown", "[MODEL]", llformat("%d", result["upload_price_breakdown"]["model"].asInteger())); -// Updates for enhanced Mesh feedback at upload + childSetTextArg("physics_breakdown", "[PCH]", llformat("%0.3f", result["model_physics_cost"]["hull"].asReal())); childSetTextArg("physics_breakdown", "[PM]", llformat("%0.3f", result["model_physics_cost"]["mesh"].asReal())); childSetTextArg("physics_breakdown", "[PHU]", llformat("%0.3f", result["model_physics_cost"]["decomposition"].asReal())); @@ -5036,7 +5015,7 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived() childSetTextArg("streaming_breakdown", "[STR_MED]", llformat("%d", result["streaming_params"]["medium_lod"].asInteger())); childSetTextArg("streaming_breakdown", "[STR_LOW]", llformat("%d", result["streaming_params"]["low_lod"].asInteger())); childSetTextArg("streaming_breakdown", "[STR_LOWEST]", llformat("%d", result["streaming_params"]["lowest_lod"].asInteger())); -// + childSetVisible("upload_fee", true); childSetVisible("price_breakdown", true); mUploadBtn->setEnabled(isModelUploadAllowed()); diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 4e9b575882..1677fe0571 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -109,6 +109,7 @@ public: void loadModel(S32 lod, const std::string& file_name, bool force_disable_slm = false); void onViewOptionChecked(LLUICtrl* ctrl); + void onUploadOptionChecked(LLUICtrl* ctrl); bool isViewOptionChecked(const LLSD& userdata); bool isViewOptionEnabled(const LLSD& userdata); void setViewOptionEnabled(const std::string& option, bool enabled); @@ -179,6 +180,7 @@ protected: LLModelPreview* mModelPreview; LLPhysicsDecomp::decomp_params mDecompParams; + LLPhysicsDecomp::decomp_params mDefaultDecompParams; S32 mLastMouseX; S32 mLastMouseY; @@ -203,7 +205,6 @@ protected: private: void onClickCalculateBtn(); - void toggleCalculateButton(); void onLoDSourceCommit(S32 lod); @@ -213,6 +214,8 @@ private: // resets display options of model preview to their defaults. void resetDisplayOptions(); + void resetUploadOptions(); + void createSmoothComboBox(LLComboBox* combo_box, float min, float max); LLButton* mUploadBtn; diff --git a/indra/newview/llfloatermyscripts.cpp b/indra/newview/llfloatermyscripts.cpp new file mode 100644 index 0000000000..fa2de21a8f --- /dev/null +++ b/indra/newview/llfloatermyscripts.cpp @@ -0,0 +1,294 @@ +/** + * @file llfloatermyscripts.cpp + * @brief LLFloaterMyScripts class implementation. + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2019, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfloatermyscripts.h" + +#include "llagent.h" +#include "llcorehttputil.h" +#include "llcoros.h" +#include "lleventcoro.h" +#include "llfloaterreg.h" +#include "llscrolllistctrl.h" +#include "lltrans.h" +#include "llviewerregion.h" + +const S32 SIZE_OF_ONE_KB = 1024; + +LLFloaterMyScripts::LLFloaterMyScripts(const LLSD& seed) + : LLFloater(seed), + mGotAttachmentMemoryUsed(false), + mAttachmentMemoryMax(0), + mAttachmentMemoryUsed(0), + mGotAttachmentURLsUsed(false), + mAttachmentURLsMax(0), + mAttachmentURLsUsed(0) +{ +} + +BOOL LLFloaterMyScripts::postBuild() +{ + childSetAction("refresh_list_btn", onClickRefresh, this); + + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); + getChild("loading_text")->setValue(LLSD(msg_waiting)); + return requestAttachmentDetails(); +} + +BOOL LLFloaterMyScripts::requestAttachmentDetails() +{ + if (!gAgent.getRegion()) return FALSE; + + LLSD body; + std::string url = gAgent.getRegion()->getCapability("AttachmentResources"); + if (!url.empty()) + { + LLCoros::instance().launch("LLFloaterMyScripts::getAttachmentLimitsCoro", + boost::bind(&LLFloaterMyScripts::getAttachmentLimitsCoro, this, url)); + return TRUE; + } + else + { + return FALSE; + } +} + +void LLFloaterMyScripts::getAttachmentLimitsCoro(std::string url) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + + LLSD result = httpAdapter->getAndSuspend(httpRequest, url); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL; + return; + } + + LLFloaterMyScripts* instance = LLFloaterReg::getTypedInstance("my_scripts"); + + if (!instance) + { + LL_WARNS() << "Failed to get LLFloaterMyScripts instance" << LL_ENDL; + return; + } + + instance->getChild("loading_text")->setValue(LLSD(std::string(""))); + + LLButton* btn = instance->getChild("refresh_list_btn"); + if (btn) + { + btn->setEnabled(true); + } + + result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); + instance->setAttachmentDetails(result); +} + + +void LLFloaterMyScripts::setAttachmentDetails(LLSD content) +{ + LLScrollListCtrl *list = getChild("scripts_list"); + + if(!list) + { + return; + } + + S32 number_attachments = content["attachments"].size(); + + for(int i = 0; i < number_attachments; i++) + { + std::string humanReadableLocation = ""; + if(content["attachments"][i].has("location")) + { + std::string actualLocation = content["attachments"][i]["location"]; + humanReadableLocation = LLTrans::getString(actualLocation.c_str()); + } + + S32 number_objects = content["attachments"][i]["objects"].size(); + for(int j = 0; j < number_objects; j++) + { + LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID(); + S32 size = 0; + if(content["attachments"][i]["objects"][j]["resources"].has("memory")) + { + size = content["attachments"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB; + } + S32 urls = 0; + if(content["attachments"][i]["objects"][j]["resources"].has("urls")) + { + urls = content["attachments"][i]["objects"][j]["resources"]["urls"].asInteger(); + } + std::string name = content["attachments"][i]["objects"][j]["name"].asString(); + + LLSD element; + + element["id"] = task_id; + element["columns"][0]["column"] = "size"; + element["columns"][0]["value"] = llformat("%d", size); + element["columns"][0]["font"] = "SANSSERIF"; + element["columns"][0]["halign"] = LLFontGL::RIGHT; + + element["columns"][1]["column"] = "urls"; + element["columns"][1]["value"] = llformat("%d", urls); + element["columns"][1]["font"] = "SANSSERIF"; + element["columns"][1]["halign"] = LLFontGL::RIGHT; + + element["columns"][2]["column"] = "name"; + element["columns"][2]["value"] = name; + element["columns"][2]["font"] = "SANSSERIF"; + + element["columns"][3]["column"] = "location"; + element["columns"][3]["value"] = humanReadableLocation; + element["columns"][3]["font"] = "SANSSERIF"; + + list->addElement(element); + } + } + + setAttachmentSummary(content); + + getChild("loading_text")->setValue(LLSD(std::string(""))); + + LLButton* btn = getChild("refresh_list_btn"); + if(btn) + { + btn->setEnabled(true); + } +} + +void LLFloaterMyScripts::clearList() +{ + LLCtrlListInterface *list = childGetListInterface("scripts_list"); + + if (list) + { + list->operateOnAll(LLCtrlListInterface::OP_DELETE); + } + + std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); + getChild("loading_text")->setValue(LLSD(msg_waiting)); +} + +void LLFloaterMyScripts::setAttachmentSummary(LLSD content) +{ + if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) + { + mAttachmentMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mAttachmentMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotAttachmentMemoryUsed = true; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) + { + mAttachmentMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mAttachmentMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; + mGotAttachmentMemoryUsed = true; + } + else + { + LL_WARNS() << "attachment details don't contain memory summary info" << LL_ENDL; + return; + } + + if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) + { + mAttachmentURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); + mAttachmentURLsMax = content["summary"]["available"][0]["amount"].asInteger(); + mGotAttachmentURLsUsed = true; + } + else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) + { + mAttachmentURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); + mAttachmentURLsMax = content["summary"]["available"][1]["amount"].asInteger(); + mGotAttachmentURLsUsed = true; + } + else + { + LL_WARNS() << "attachment details don't contain urls summary info" << LL_ENDL; + return; + } + + if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0)) + { + LLStringUtil::format_map_t args_attachment_memory; + args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed); + std::string translate_message = "ScriptLimitsMemoryUsedSimple"; + + if (0 < mAttachmentMemoryMax) + { + S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed; + + args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax); + args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available); + translate_message = "ScriptLimitsMemoryUsed"; + } + + getChild("memory_used")->setValue(LLTrans::getString(translate_message, args_attachment_memory)); + } + + if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0)) + { + S32 attachment_urls_available = mAttachmentURLsMax - mAttachmentURLsUsed; + + LLStringUtil::format_map_t args_attachment_urls; + args_attachment_urls["[COUNT]"] = llformat ("%d", mAttachmentURLsUsed); + args_attachment_urls["[MAX]"] = llformat ("%d", mAttachmentURLsMax); + args_attachment_urls["[AVAILABLE]"] = llformat ("%d", attachment_urls_available); + std::string msg_attachment_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_attachment_urls); + getChild("urls_used")->setValue(LLSD(msg_attachment_urls)); + } +} + +// static +void LLFloaterMyScripts::onClickRefresh(void* userdata) +{ + LLFloaterMyScripts* instance = LLFloaterReg::getTypedInstance("my_scripts"); + if(instance) + { + LLButton* btn = instance->getChild("refresh_list_btn"); + + //To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer! + //turn the button off, then turn it on when we get a response + if(btn) + { + btn->setEnabled(false); + } + instance->clearList(); + instance->requestAttachmentDetails(); + } + else + { + LL_WARNS() << "could not find LLFloaterMyScripts instance after refresh button clicked" << LL_ENDL; + } +} + diff --git a/indra/newview/llfloatermyscripts.h b/indra/newview/llfloatermyscripts.h new file mode 100644 index 0000000000..fe33ab90ae --- /dev/null +++ b/indra/newview/llfloatermyscripts.h @@ -0,0 +1,60 @@ +/** + * @file llfloatermyscripts.h + * @brief LLFloaterMyScripts class definition. + * + * $LicenseInfo:firstyear=2004&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2019, 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_LLFLOATERMYSCRIPTS_H +#define LL_LLFLOATERMYSCRIPTS_H + +#include "llfloater.h" +#include "llpanel.h" + +class LLFloaterMyScripts : public LLFloater +{ +public: + LLFloaterMyScripts(const LLSD& seed); + + BOOL postBuild(); + void setAttachmentDetails(LLSD content); + void setAttachmentSummary(LLSD content); + BOOL requestAttachmentDetails(); + void clearList(); + +private: + void getAttachmentLimitsCoro(std::string url); + + bool mGotAttachmentMemoryUsed; + S32 mAttachmentMemoryMax; + S32 mAttachmentMemoryUsed; + + bool mGotAttachmentURLsUsed; + S32 mAttachmentURLsMax; + S32 mAttachmentURLsUsed; + +protected: + + static void onClickRefresh(void* userdata); +}; + +#endif diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 43cbd67a15..bca50e215f 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -131,12 +131,13 @@ #include "llfeaturemanager.h" #include "llviewertexturelist.h" +#include "llsearchableui.h" + // Firestorm Includes #include "exogroupmutelist.h" #include "fsavatarrenderpersistence.h" #include "fsdroptarget.h" #include "fsfloaterimcontainer.h" -#include "fssearchableui.h" #include "growlmanager.h" #include "lfsimfeaturehandler.h" #include "llavatarname.h" // Deeper name cache stuffs @@ -176,6 +177,25 @@ static const F32 MIN_ARC_LOG = log(MIN_ARC_LIMIT); static const F32 MAX_ARC_LOG = log(MAX_ARC_LIMIT); static const F32 ARC_LIMIT_MAP_SCALE = (MAX_ARC_LOG - MIN_ARC_LOG) / (MAX_INDIRECT_ARC_LIMIT - MIN_INDIRECT_ARC_LIMIT); +struct LabelDef : public LLInitParam::Block +{ + Mandatory name; + Mandatory value; + + LabelDef() + : name("name"), + value("value") + {} +}; + +struct LabelTable : public LLInitParam::Block +{ + Multiple labels; + LabelTable() + : labels("label") + {} +}; + class LLVoiceSetKeyDialog : public LLModalDialog { public: @@ -469,8 +489,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mOriginalIMViaEmail(false), mLanguageChanged(false), mAvatarDataInitialized(false), - mClickActionDirty(false), - mSearchData(NULL) // Hook up and init for filtering + mClickActionDirty(false) { LLConversationLog::instance().addObserver(this); @@ -544,6 +563,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) mCommitCallbackRegistrar.add("Pref.ClearLog", boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance())); mCommitCallbackRegistrar.add("Pref.DeleteTranscripts", boost::bind(&LLFloaterPreference::onDeleteTranscripts, this)); + mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // Hook up for filtering // mCommitCallbackRegistrar.add("NACL.AntiSpamUnblock", boost::bind(&LLFloaterPreference::onClickClearSpamList, this)); @@ -575,8 +595,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key) // FIRE-2912: Reset voice button mCommitCallbackRegistrar.add("Pref.ResetVoice", boost::bind(&LLFloaterPreference::onClickResetVoice, this)); - - mCommitCallbackRegistrar.add("UpdateFilter", boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); // Hook up for filtering } void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type ) @@ -708,6 +726,33 @@ BOOL LLFloaterPreference::postBuild() LLSliderCtrl* fov_slider = getChild("camera_fov"); fov_slider->setMinValue(LLViewerCamera::getInstance()->getMinView()); fov_slider->setMaxValue(LLViewerCamera::getInstance()->getMaxView()); + + // Hook up and init for filtering + mFilterEdit = getChild("search_prefs_edit"); + mFilterEdit->setKeystrokeCallback(boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); + + // Load and assign label for 'default language' + std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_DEFAULT_SKIN, "default_languages.xml"); + std::map labels; + if (loadFromFilename(user_filename, labels)) + { + std::string system_lang = gSavedSettings.getString("SystemLanguage"); + std::map::iterator iter = labels.find(system_lang); + if (iter != labels.end()) + { + getChild("language_combobox")->add(iter->second, LLSD("default"), ADD_TOP, true); + } + else + { + LL_WARNS() << "Language \"" << system_lang << "\" is not in default_languages.xml" << LL_ENDL; + getChild("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true); + } + } + else + { + LL_WARNS() << "Failed to load labels from " << user_filename << ". Using default." << LL_ENDL; + getChild("language_combobox")->add("System default", LLSD("default"), ADD_TOP, true); + } // [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2011-06-11 (Catznip-2.6.c) | Added: Catznip-2.6.0c #ifndef LL_SEND_CRASH_REPORTS @@ -749,11 +794,6 @@ BOOL LLFloaterPreference::postBuild() populateFontSelectionCombo(); // - // Hook up and init for filtering - mFilterEdit = getChild("search_prefs_edit"); - mFilterEdit->setKeystrokeCallback(boost::bind(&LLFloaterPreference::onUpdateFilterTerm, this, false)); - // - // Update label for max. non imposters and max complexity gSavedSettings.getControl("IndirectMaxNonImpostors")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateMaxNonImpostorsLabel, this, _2)); gSavedSettings.getControl("RenderAvatarMaxComplexity")->getCommitSignal()->connect(boost::bind(&LLFloaterPreference::updateMaxComplexityLabel, this, _2)); @@ -881,8 +921,6 @@ void LLFloaterPreference::onDoNotDisturbResponseChanged() LLFloaterPreference::~LLFloaterPreference() { LLConversationLog::instance().removeObserver(this); - - delete mSearchData; } void LLFloaterPreference::draw() @@ -1229,17 +1267,17 @@ void LLFloaterPreference::onOpen(const LLSD& key) //exceptions_btn->setEnabled(started); // - // Hook up and init for filtering collectSearchableItems(); if (!mFilterEdit->getText().empty()) { mFilterEdit->setText(LLStringExplicit("")); onUpdateFilterTerm(true); + // Hook up and init for filtering if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab"))) tabcontainer->selectFirstTab(); + // } - // } void LLFloaterPreference::onVertexShaderEnable() @@ -3212,6 +3250,45 @@ void LLFloaterPreference::updateMaxComplexity() getChild("IndirectMaxComplexityText")); } +bool LLFloaterPreference::loadFromFilename(const std::string& filename, std::map &label_map) +{ + LLXMLNodePtr root; + + if (!LLXMLNode::parseFile(filename, root, NULL)) + { + LL_WARNS() << "Unable to parse file " << filename << LL_ENDL; + return false; + } + + if (!root->hasName("labels")) + { + LL_WARNS() << filename << " is not a valid definition file" << LL_ENDL; + return false; + } + + LabelTable params; + LLXUIParser parser; + parser.readXUI(root, params, filename); + + if (params.validateBlock()) + { + for (LLInitParam::ParamIterator::const_iterator it = params.labels.begin(); + it != params.labels.end(); + ++it) + { + LabelDef label_entry = *it; + label_map[label_entry.name] = label_entry.value; + } + } + else + { + LL_WARNS() << filename << " failed to load" << LL_ENDL; + return false; + } + + return true; +} + void LLFloaterPreferenceGraphicsAdvanced::updateMaxComplexity() { // Called when the IndirectMaxComplexity control changes @@ -3688,6 +3765,7 @@ BOOL LLPanelPreference::postBuild() if (hasChild("mute_chb_label", TRUE)) { getChild("mute_chb_label")->setShowCursorHand(false); + getChild("mute_chb_label")->setSoundFlags(LLView::MOUSE_UP); getChild("mute_chb_label")->setClickedCallback(boost::bind(&toggleMuteWhenMinimized)); } @@ -3852,6 +3930,11 @@ void LLPanelPreference::toggleMuteWhenMinimized() { std::string mute("MuteWhenMinimized"); gSavedSettings.setBOOL(mute, !gSavedSettings.getBOOL(mute)); + LLFloaterPreference* instance = LLFloaterReg::findTypedInstance("preferences"); + if (instance) + { + instance->getChild("mute_when_minimized")->setBtnFocus(); + } } // Only enable Growl checkboxes if Growl is usable @@ -4186,6 +4269,11 @@ void LLPanelPreferenceGraphics::onPresetsListChange() //{ // instance->saveSettings(); //make cancel work correctly after changing the preset //} + //else + //{ + // std::string dummy; + // instance->saveGraphicsPreset(dummy); + //} } void LLPanelPreferenceGraphics::setPresetText() @@ -4575,6 +4663,113 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings() } +void LLFloaterPreference::onUpdateFilterTerm(bool force) +{ + LLWString seachValue = utf8str_to_wstring( mFilterEdit->getValue() ); + LLWStringUtil::toLower( seachValue ); + + if( !mSearchData || (mSearchData->mLastFilter == seachValue && !force)) + return; + + mSearchData->mLastFilter = seachValue; + + if( !mSearchData->mRootTab ) + return; + + mSearchData->mRootTab->hightlightAndHide( seachValue ); + LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" ); + if( pRoot ) + pRoot->selectFirstTab(); +} + +void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer ) +{ + if( !aView ) + return; + + llassert_always( aParentPanel || aParentTabContainer ); + + LLView::child_list_const_iter_t itr = aView->beginChild(); + LLView::child_list_const_iter_t itrEnd = aView->endChild(); + + while( itr != itrEnd ) + { + LLView *pView = *itr; + ll::prefs::PanelDataPtr pCurPanelData = aParentPanel; + ll::prefs::TabContainerDataPtr pCurTabContainer = aParentTabContainer; + if( !pView ) + continue; + LLPanel const *pPanel = dynamic_cast< LLPanel const *>( pView ); + LLTabContainer const *pTabContainer = dynamic_cast< LLTabContainer const *>( pView ); + ll::ui::SearchableControl const *pSCtrl = dynamic_cast< ll::ui::SearchableControl const *>( pView ); + + if( pTabContainer ) + { + pCurPanelData.reset(); + + pCurTabContainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData ); + pCurTabContainer->mTabContainer = const_cast< LLTabContainer *>( pTabContainer ); + pCurTabContainer->mLabel = pTabContainer->getLabel(); + pCurTabContainer->mPanel = 0; + + if( aParentPanel ) + aParentPanel->mChildPanel.push_back( pCurTabContainer ); + if( aParentTabContainer ) + aParentTabContainer->mChildPanel.push_back( pCurTabContainer ); + } + else if( pPanel ) + { + pCurTabContainer.reset(); + + pCurPanelData = ll::prefs::PanelDataPtr( new ll::prefs::PanelData ); + pCurPanelData->mPanel = pPanel; + pCurPanelData->mLabel = pPanel->getLabel(); + + llassert_always( aParentPanel || aParentTabContainer ); + + if( aParentTabContainer ) + aParentTabContainer->mChildPanel.push_back( pCurPanelData ); + else if( aParentPanel ) + aParentPanel->mChildPanel.push_back( pCurPanelData ); + } + else if( pSCtrl && pSCtrl->getSearchText().size() ) + { + ll::prefs::SearchableItemPtr item = ll::prefs::SearchableItemPtr( new ll::prefs::SearchableItem() ); + item->mView = pView; + item->mCtrl = pSCtrl; + + item->mLabel = utf8str_to_wstring( pSCtrl->getSearchText() ); + LLWStringUtil::toLower( item->mLabel ); + + llassert_always( aParentPanel || aParentTabContainer ); + + if( aParentPanel ) + aParentPanel->mChildren.push_back( item ); + if( aParentTabContainer ) + aParentTabContainer->mChildren.push_back( item ); + } + collectChildren( pView, pCurPanelData, pCurTabContainer ); + ++itr; + } +} + +void LLFloaterPreference::collectSearchableItems() +{ + mSearchData.reset( nullptr ); + LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" ); + if( mFilterEdit && pRoot ) + { + mSearchData.reset(new ll::prefs::SearchData() ); + + ll::prefs::TabContainerDataPtr pRootTabcontainer = ll::prefs::TabContainerDataPtr( new ll::prefs::TabContainerData ); + pRootTabcontainer->mTabContainer = pRoot; + pRootTabcontainer->mLabel = pRoot->getLabel(); + mSearchData->mRootTab = pRootTabcontainer; + + collectChildren( this, ll::prefs::PanelDataPtr(), pRootTabcontainer ); + } +} + // [SL:KB] - Patch: Viewer-CrashReporting | Checked: 2010-11-16 (Catznip-2.6.0a) | Added: Catznip-2.4.0b static LLPanelInjector t_pref_crashreports("panel_preference_crashreports"); @@ -5746,113 +5941,3 @@ void LLPanelPreferenceOpensim::onClickPickDebugSearchURL() #endif // OPENSIM // - -// Code to filter/search in the prefs panel -void LLFloaterPreference::onUpdateFilterTerm(bool force) -{ - LLWString seachValue = utf8str_to_wstring( mFilterEdit->getValue() ); - LLWStringUtil::toLower( seachValue ); - - if( !mSearchData || (mSearchData->mLastFilter == seachValue && !force)) - return; - - mSearchData->mLastFilter = seachValue; - - if( !mSearchData->mRootTab ) - return; - - mSearchData->mRootTab->hightlightAndHide( seachValue ); - LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" ); - if( pRoot ) - pRoot->selectFirstTab(); -} - -void collectChildren( LLView const *aView, nd::prefs::PanelDataPtr aParentPanel, nd::prefs::TabContainerDataPtr aParentTabContainer ) -{ - if( !aView ) - return; - - llassert_always( aParentPanel || aParentTabContainer ); - - LLView::child_list_const_iter_t itr = aView->beginChild(); - LLView::child_list_const_iter_t itrEnd = aView->endChild(); - - while( itr != itrEnd ) - { - LLView *pView = *itr; - nd::prefs::PanelDataPtr pCurPanelData = aParentPanel; - nd::prefs::TabContainerDataPtr pCurTabContainer = aParentTabContainer; - if( !pView ) - continue; - LLPanel const *pPanel = dynamic_cast< LLPanel const *>( pView ); - LLTabContainer const *pTabContainer = dynamic_cast< LLTabContainer const *>( pView ); - nd::ui::SearchableControl const *pSCtrl = dynamic_cast< nd::ui::SearchableControl const *>( pView ); - - if( pTabContainer ) - { - pCurPanelData.reset(); - - pCurTabContainer = nd::prefs::TabContainerDataPtr( new nd::prefs::TabContainerData ); - pCurTabContainer->mTabContainer = const_cast< LLTabContainer *>( pTabContainer ); - pCurTabContainer->mLabel = pTabContainer->getLabel(); - pCurTabContainer->mPanel = 0; - - if( aParentPanel ) - aParentPanel->mChildPanel.push_back( pCurTabContainer ); - if( aParentTabContainer ) - aParentTabContainer->mChildPanel.push_back( pCurTabContainer ); - } - else if( pPanel ) - { - pCurTabContainer.reset(); - - pCurPanelData = nd::prefs::PanelDataPtr( new nd::prefs::PanelData ); - pCurPanelData->mPanel = pPanel; - pCurPanelData->mLabel = pPanel->getLabel(); - - llassert_always( aParentPanel || aParentTabContainer ); - - if( aParentTabContainer ) - aParentTabContainer->mChildPanel.push_back( pCurPanelData ); - else if( aParentPanel ) - aParentPanel->mChildPanel.push_back( pCurPanelData ); - } - else if( pSCtrl && pSCtrl->getSearchText().size() ) - { - nd::prefs::SearchableItemPtr item = nd::prefs::SearchableItemPtr( new nd::prefs::SearchableItem() ); - item->mView = pView; - item->mCtrl = pSCtrl; - - item->mLabel = utf8str_to_wstring( pSCtrl->getSearchText() ); - LLWStringUtil::toLower( item->mLabel ); - - llassert_always( aParentPanel || aParentTabContainer ); - - if( aParentPanel ) - aParentPanel->mChildren.push_back( item ); - if( aParentTabContainer ) - aParentTabContainer->mChildren.push_back( item ); - } - collectChildren( pView, pCurPanelData, pCurTabContainer ); - ++itr; - } -} - -void LLFloaterPreference::collectSearchableItems() -{ - delete mSearchData; - mSearchData = NULL; - LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" ); - if( mFilterEdit && pRoot ) - { - mSearchData = new nd::prefs::SearchData(); - - nd::prefs::TabContainerDataPtr pRootTabcontainer = nd::prefs::TabContainerDataPtr( new nd::prefs::TabContainerData ); - pRootTabcontainer->mTabContainer = pRoot; - pRootTabcontainer->mLabel = pRoot->getLabel(); - mSearchData->mRootTab = pRootTabcontainer; - - collectChildren( this, nd::prefs::PanelDataPtr(), pRootTabcontainer ); - } -} -// diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 920badce5f..35666d4aaf 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -38,14 +38,6 @@ #include "llconversationlog.h" #include "llsearcheditor.h" -namespace nd -{ - namespace prefs - { - struct SearchData; - } -} - class LLConversationLogObserver; class LLPanelPreference; class LLPanelLCD; @@ -58,6 +50,14 @@ class LLTextBox; class LLComboBox; class LLLineEditor; +namespace ll +{ + namespace prefs + { + struct SearchData; + } +} + typedef std::map notifications_map; typedef enum @@ -272,6 +272,7 @@ private: void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response); void updateDeleteTranscriptsButton(); void updateMaxComplexity(); + static bool loadFromFilename(const std::string& filename, std::map &label_map); static std::string sSkin; notifications_map mNotificationOptions; @@ -290,9 +291,9 @@ private: LOG_CLASS(LLFloaterPreference); LLSearchEditor *mFilterEdit; - void onUpdateFilterTerm(bool force = false); + std::unique_ptr< ll::prefs::SearchData > mSearchData; - nd::prefs::SearchData *mSearchData; + void onUpdateFilterTerm( bool force = false ); void collectSearchableItems(); }; diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 21df769d0c..3746b9b6c2 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -90,19 +90,6 @@ LLFloaterScriptLimits::LLFloaterScriptLimits(const LLSD& seed) BOOL LLFloaterScriptLimits::postBuild() { - // a little cheap and cheerful - if there's an about land panel open default to showing parcel info, - // otherwise default to showing attachments (avatar appearance) - bool selectParcelPanel = false; - - LLFloaterLand* instance = LLFloaterReg::getTypedInstance("about_land"); - if(instance) - { - if(instance->isShown()) - { - selectParcelPanel = true; - } - } - mTab = getChild("scriptlimits_panels"); if(!mTab) @@ -111,28 +98,12 @@ BOOL LLFloaterScriptLimits::postBuild() return FALSE; } - // contruct the panels + // contruct the panel LLPanelScriptLimitsRegionMemory* panel_memory = new LLPanelScriptLimitsRegionMemory; mInfoPanels.push_back(panel_memory); panel_memory->buildFromFile( "panel_script_limits_region_memory.xml"); mTab->addTabPanel(panel_memory); - - LLPanelScriptLimitsAttachment* panel_attachments = new LLPanelScriptLimitsAttachment; - mInfoPanels.push_back(panel_attachments); - panel_attachments->buildFromFile("panel_script_limits_my_avatar.xml"); - mTab->addTabPanel(panel_attachments); - - - if(mInfoPanels.size() > 0) - { - mTab->selectTab(0); - } - - if(!selectParcelPanel && (mInfoPanels.size() > 1)) - { - mTab->selectTab(1); - } - + mTab->selectTab(0); return TRUE; } @@ -969,269 +940,3 @@ void LLPanelScriptLimitsRegionMemory::onClickReturn(void* userdata) } } -///---------------------------------------------------------------------------- -// Attachment Panel -///---------------------------------------------------------------------------- - -BOOL LLPanelScriptLimitsAttachment::requestAttachmentDetails() -{ - if (!gAgent.getRegion()) return FALSE; - - LLSD body; - std::string url = gAgent.getRegion()->getCapability("AttachmentResources"); - if (!url.empty()) - { - LLCoros::instance().launch("LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro", - boost::bind(&LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro, this, url)); - return TRUE; - } - else - { - return FALSE; - } -} - -void LLPanelScriptLimitsAttachment::getAttachmentLimitsCoro(std::string url) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - - LLSD result = httpAdapter->getAndSuspend(httpRequest, url); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL; - return; - } - - LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance("script_limits"); - - if (!instance) - { - LL_WARNS() << "Failed to get llfloaterscriptlimits instance" << LL_ENDL; - return; - } - - LLTabContainer* tab = instance->getChild("scriptlimits_panels"); - if (!tab) - { - LL_WARNS() << "Failed to get scriptlimits_panels" << LL_ENDL; - return; - } - - LLPanelScriptLimitsAttachment* panel = (LLPanelScriptLimitsAttachment*)tab->getChild("script_limits_my_avatar_panel"); - if (!panel) - { - LL_WARNS() << "Failed to get script_limits_my_avatar_panel" << LL_ENDL; - return; - } - - panel->getChild("loading_text")->setValue(LLSD(std::string(""))); - - LLButton* btn = panel->getChild("refresh_list_btn"); - if (btn) - { - btn->setEnabled(true); - } - - result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS); - panel->setAttachmentDetails(result); -} - - -void LLPanelScriptLimitsAttachment::setAttachmentDetails(LLSD content) -{ - LLScrollListCtrl *list = getChild("scripts_list"); - - if(!list) - { - return; - } - - S32 number_attachments = content["attachments"].size(); - - for(int i = 0; i < number_attachments; i++) - { - std::string humanReadableLocation = ""; - if(content["attachments"][i].has("location")) - { - std::string actualLocation = content["attachments"][i]["location"]; - humanReadableLocation = LLTrans::getString(actualLocation.c_str()); - } - - S32 number_objects = content["attachments"][i]["objects"].size(); - for(int j = 0; j < number_objects; j++) - { - LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID(); - S32 size = 0; - if(content["attachments"][i]["objects"][j]["resources"].has("memory")) - { - size = content["attachments"][i]["objects"][j]["resources"]["memory"].asInteger() / SIZE_OF_ONE_KB; - } - S32 urls = 0; - if(content["attachments"][i]["objects"][j]["resources"].has("urls")) - { - urls = content["attachments"][i]["objects"][j]["resources"]["urls"].asInteger(); - } - std::string name = content["attachments"][i]["objects"][j]["name"].asString(); - - LLSD element; - - element["id"] = task_id; - element["columns"][0]["column"] = "size"; - element["columns"][0]["value"] = llformat("%d", size); - element["columns"][0]["font"] = "SANSSERIF"; - element["columns"][0]["halign"] = LLFontGL::RIGHT; - - element["columns"][1]["column"] = "urls"; - element["columns"][1]["value"] = llformat("%d", urls); - element["columns"][1]["font"] = "SANSSERIF"; - element["columns"][1]["halign"] = LLFontGL::RIGHT; - - element["columns"][2]["column"] = "name"; - element["columns"][2]["value"] = name; - element["columns"][2]["font"] = "SANSSERIF"; - - element["columns"][3]["column"] = "location"; - element["columns"][3]["value"] = humanReadableLocation; - element["columns"][3]["font"] = "SANSSERIF"; - - list->addElement(element); - } - } - - setAttachmentSummary(content); - - getChild("loading_text")->setValue(LLSD(std::string(""))); - - LLButton* btn = getChild("refresh_list_btn"); - if(btn) - { - btn->setEnabled(true); - } -} - -BOOL LLPanelScriptLimitsAttachment::postBuild() -{ - childSetAction("refresh_list_btn", onClickRefresh, this); - - std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); - getChild("loading_text")->setValue(LLSD(msg_waiting)); - return requestAttachmentDetails(); -} - -void LLPanelScriptLimitsAttachment::clearList() -{ - LLCtrlListInterface *list = childGetListInterface("scripts_list"); - - if (list) - { - list->operateOnAll(LLCtrlListInterface::OP_DELETE); - } - - std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting"); - getChild("loading_text")->setValue(LLSD(msg_waiting)); -} - -void LLPanelScriptLimitsAttachment::setAttachmentSummary(LLSD content) -{ - if(content["summary"]["used"][0]["type"].asString() == std::string("memory")) - { - mAttachmentMemoryUsed = content["summary"]["used"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; - mAttachmentMemoryMax = content["summary"]["available"][0]["amount"].asInteger() / SIZE_OF_ONE_KB; - mGotAttachmentMemoryUsed = true; - } - else if(content["summary"]["used"][1]["type"].asString() == std::string("memory")) - { - mAttachmentMemoryUsed = content["summary"]["used"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; - mAttachmentMemoryMax = content["summary"]["available"][1]["amount"].asInteger() / SIZE_OF_ONE_KB; - mGotAttachmentMemoryUsed = true; - } - else - { - LL_WARNS() << "attachment details don't contain memory summary info" << LL_ENDL; - return; - } - - if(content["summary"]["used"][0]["type"].asString() == std::string("urls")) - { - mAttachmentURLsUsed = content["summary"]["used"][0]["amount"].asInteger(); - mAttachmentURLsMax = content["summary"]["available"][0]["amount"].asInteger(); - mGotAttachmentURLsUsed = true; - } - else if(content["summary"]["used"][1]["type"].asString() == std::string("urls")) - { - mAttachmentURLsUsed = content["summary"]["used"][1]["amount"].asInteger(); - mAttachmentURLsMax = content["summary"]["available"][1]["amount"].asInteger(); - mGotAttachmentURLsUsed = true; - } - else - { - LL_WARNS() << "attachment details don't contain urls summary info" << LL_ENDL; - return; - } - - if((mAttachmentMemoryUsed >= 0) && (mAttachmentMemoryMax >= 0)) - { - LLStringUtil::format_map_t args_attachment_memory; - args_attachment_memory["[COUNT]"] = llformat ("%d", mAttachmentMemoryUsed); - std::string translate_message = "ScriptLimitsMemoryUsedSimple"; - - if (0 < mAttachmentMemoryMax) - { - S32 attachment_memory_available = mAttachmentMemoryMax - mAttachmentMemoryUsed; - - args_attachment_memory["[MAX]"] = llformat ("%d", mAttachmentMemoryMax); - args_attachment_memory["[AVAILABLE]"] = llformat ("%d", attachment_memory_available); - translate_message = "ScriptLimitsMemoryUsed"; - } - - getChild("memory_used")->setValue(LLTrans::getString(translate_message, args_attachment_memory)); - } - - if((mAttachmentURLsUsed >= 0) && (mAttachmentURLsMax >= 0)) - { - S32 attachment_urls_available = mAttachmentURLsMax - mAttachmentURLsUsed; - - LLStringUtil::format_map_t args_attachment_urls; - args_attachment_urls["[COUNT]"] = llformat ("%d", mAttachmentURLsUsed); - args_attachment_urls["[MAX]"] = llformat ("%d", mAttachmentURLsMax); - args_attachment_urls["[AVAILABLE]"] = llformat ("%d", attachment_urls_available); - std::string msg_attachment_urls = LLTrans::getString("ScriptLimitsURLsUsed", args_attachment_urls); - getChild("urls_used")->setValue(LLSD(msg_attachment_urls)); - } -} - -// static -void LLPanelScriptLimitsAttachment::onClickRefresh(void* userdata) -{ - LLFloaterScriptLimits* instance = LLFloaterReg::getTypedInstance("script_limits"); - if(instance) - { - LLTabContainer* tab = instance->getChild("scriptlimits_panels"); - LLPanelScriptLimitsAttachment* panel_attachments = (LLPanelScriptLimitsAttachment*)tab->getChild("script_limits_my_avatar_panel"); - LLButton* btn = panel_attachments->getChild("refresh_list_btn"); - - //To stop people from hammering the refesh button and accidentally dosing themselves - enough requests can crash the viewer! - //turn the button off, then turn it on when we get a response - if(btn) - { - btn->setEnabled(false); - } - panel_attachments->clearList(); - panel_attachments->requestAttachmentDetails(); - - return; - } - else - { - LL_WARNS() << "could not find LLPanelScriptLimitsRegionMemory instance after refresh button clicked" << LL_ENDL; - return; - } -} - diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h index 16450c6527..d2192f9d01 100644 --- a/indra/newview/llfloaterscriptlimits.h +++ b/indra/newview/llfloaterscriptlimits.h @@ -152,51 +152,4 @@ protected: static void onClickReturn(void* userdata); }; -///////////////////////////////////////////////////////////////////////////// -// Attachment panel -///////////////////////////////////////////////////////////////////////////// - -class LLPanelScriptLimitsAttachment : public LLPanelScriptLimitsInfo -{ - -public: - LLPanelScriptLimitsAttachment() - : LLPanelScriptLimitsInfo(), - mGotAttachmentMemoryUsed(false), - mAttachmentMemoryMax(0), - mAttachmentMemoryUsed(0), - mGotAttachmentURLsUsed(false), - mAttachmentURLsMax(0), - mAttachmentURLsUsed(0) - {}; - - ~LLPanelScriptLimitsAttachment() - { - }; - - // LLPanel - virtual BOOL postBuild(); - - void setAttachmentDetails(LLSD content); - - void setAttachmentSummary(LLSD content); - BOOL requestAttachmentDetails(); - void clearList(); - -private: - void getAttachmentLimitsCoro(std::string url); - - bool mGotAttachmentMemoryUsed; - S32 mAttachmentMemoryMax; - S32 mAttachmentMemoryUsed; - - bool mGotAttachmentURLsUsed; - S32 mAttachmentURLsMax; - S32 mAttachmentURLsUsed; - -protected: - - static void onClickRefresh(void* userdata); -}; - #endif diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp index ef8ad056d9..e773c407d3 100644 --- a/indra/newview/llfloatertopobjects.cpp +++ b/indra/newview/llfloatertopobjects.cpp @@ -83,8 +83,6 @@ LLFloaterTopObjects::LLFloaterTopObjects(const LLSD& key) mCommitCallbackRegistrar.add("TopObjects.ShowBeacon", boost::bind(&LLFloaterTopObjects::onClickShowBeacon, this)); mCommitCallbackRegistrar.add("TopObjects.ReturnSelected", boost::bind(&LLFloaterTopObjects::onReturnSelected, this)); mCommitCallbackRegistrar.add("TopObjects.ReturnAll", boost::bind(&LLFloaterTopObjects::onReturnAll, this)); - mCommitCallbackRegistrar.add("TopObjects.DisableSelected", boost::bind(&LLFloaterTopObjects::onDisableSelected, this)); - mCommitCallbackRegistrar.add("TopObjects.DisableAll", boost::bind(&LLFloaterTopObjects::onDisableAll, this)); mCommitCallbackRegistrar.add("TopObjects.Refresh", boost::bind(&LLFloaterTopObjects::onRefresh, this)); mCommitCallbackRegistrar.add("TopObjects.GetByObjectName", boost::bind(&LLFloaterTopObjects::onGetByObjectName, this)); mCommitCallbackRegistrar.add("TopObjects.GetByOwnerName", boost::bind(&LLFloaterTopObjects::onGetByOwnerName, this)); @@ -159,6 +157,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) { U32 request_flags; U32 total_count; + U64 total_memory = 0; msg->getU32Fast(_PREHASH_RequestData, _PREHASH_RequestFlags, request_flags); msg->getU32Fast(_PREHASH_RequestData, _PREHASH_TotalObjectCount, total_count); @@ -206,6 +205,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) { parcel_buf = parcel_name; script_memory = script_size; + total_memory += script_size; } } @@ -279,8 +279,10 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data) { setTitle(getString("top_scripts_title")); list->setColumnLabel("score", getString("scripts_score_label")); - + LLUIString format = getString("top_scripts_text"); + total_memory /= 1024; + format.setArg("[MEMORY]", llformat("%ld", total_memory)); format.setArg("[COUNT]", llformat("%d", total_count)); format.setArg("[TIME]", llformat("%0.3f", mtotalScore)); getChild("title_text")->setValue(LLSD(format)); @@ -364,7 +366,7 @@ void LLFloaterTopObjects::onClickShowBeacon() showBeacon(); } -void LLFloaterTopObjects::doToObjects(int action, bool all) +void LLFloaterTopObjects::returnObjects(bool all) { LLMessageSystem *msg = gMessageSystem; @@ -388,14 +390,7 @@ void LLFloaterTopObjects::doToObjects(int action, bool all) } if (start_message) { - if (action == ACTION_RETURN) - { - msg->newMessageFast(_PREHASH_ParcelReturnObjects); - } - else - { - msg->newMessageFast(_PREHASH_ParcelDisableObjects); - } + msg->newMessageFast(_PREHASH_ParcelReturnObjects); msg->nextBlockFast(_PREHASH_AgentData); msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID,gAgent.getSessionID()); @@ -429,7 +424,7 @@ bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD if(!instance) return false; if (option == 0) { - instance->doToObjects(ACTION_RETURN, true); + instance->returnObjects(true); } return false; } @@ -442,31 +437,7 @@ void LLFloaterTopObjects::onReturnAll() void LLFloaterTopObjects::onReturnSelected() { - doToObjects(ACTION_RETURN, false); -} - - -//static -bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response) -{ - S32 option = LLNotificationsUtil::getSelectedOption(notification, response); - LLFloaterTopObjects* instance = LLFloaterReg::getTypedInstance("top_objects"); - if(!instance) return false; - if (option == 0) - { - instance->doToObjects(ACTION_DISABLE, true); - } - return false; -} - -void LLFloaterTopObjects::onDisableAll() -{ - LLNotificationsUtil::add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll); -} - -void LLFloaterTopObjects::onDisableSelected() -{ - doToObjects(ACTION_DISABLE, false); + returnObjects(false); } diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h index 6b17295bcd..495ff41eff 100644 --- a/indra/newview/llfloatertopobjects.h +++ b/indra/newview/llfloatertopobjects.h @@ -79,12 +79,10 @@ private: static void onDoubleClickObjectsList(void* data); void onClickShowBeacon(); - void doToObjects(int action, bool all); + void returnObjects(bool all); void onReturnAll(); void onReturnSelected(); - void onDisableAll(); - void onDisableSelected(); // TP to object void onTeleportToObject(); @@ -99,7 +97,6 @@ private: void onAvatarCheck(const LLUUID& avatar_id, const LLAvatarName av_name); static bool callbackReturnAll(const LLSD& notification, const LLSD& response); - static bool callbackDisableAll(const LLSD& notification, const LLSD& response); void onGetByOwnerName(); void onGetByObjectName(); @@ -121,12 +118,6 @@ private: F32 mtotalScore; - enum - { - ACTION_RETURN = 0, - ACTION_DISABLE - }; - static LLFloaterTopObjects* sInstance; }; diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp index 5f884044ec..b5e2e42b06 100644 --- a/indra/newview/llfloateruipreview.cpp +++ b/indra/newview/llfloateruipreview.cpp @@ -60,6 +60,7 @@ #include "llfloaterreg.h" #include "llscrollcontainer.h" // scroll container for overlapping elements #include "lllivefile.h" // live file poll/stat/reload +#include "llviewermenufile.h" // LLFilePickerReplyThread // Boost (for linux/unix command-line execv) #include @@ -207,7 +208,9 @@ private: void onClickSaveAll(S32 id); void onClickEditFloater(); void onClickBrowseForEditor(); + void getExecutablePath(const std::vector& filenames); void onClickBrowseForDiffs(); + void getDiffsFilePath(const std::vector& filenames); void onClickToggleDiffHighlighting(); void onClickToggleOverlapping(); void onClickCloseDisplayedFloater(S32 id); @@ -1048,15 +1051,14 @@ void LLFloaterUIPreview::onClickEditFloater() // Respond to button click to browse for an executable with which to edit XML files void LLFloaterUIPreview::onClickBrowseForEditor() { - // Let the user choose an executable through the file picker dialog box - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getOpenFile(LLFilePicker::FFLOAD_EXE)) - { - return; // user cancelled -- do nothing - } + // Let the user choose an executable through the file picker dialog box + (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false))->getFile(); +} +void LLFloaterUIPreview::getExecutablePath(const std::vector& filenames) +{ // put the selected path into text field - const std::string chosen_path = picker.getFirstFile(); + const std::string chosen_path = filenames[0]; std::string executable_path = chosen_path; #if LL_DARWIN // on Mac, if it's an application bundle, figure out the actual path from the Info.plist file @@ -1106,15 +1108,13 @@ void LLFloaterUIPreview::onClickBrowseForEditor() void LLFloaterUIPreview::onClickBrowseForDiffs() { // create load dialog box - LLFilePicker::ELoadFilter type = (LLFilePicker::ELoadFilter)((intptr_t)((void*)LLFilePicker::FFLOAD_XML)); // nothing for *.exe so just use all - LLFilePicker& picker = LLFilePicker::instance(); - if (!picker.getOpenFile(type)) // user cancelled -- do nothing - { - return; - } + (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile(); +} +void LLFloaterUIPreview::getDiffsFilePath(const std::vector& filenames) +{ // put the selected path into text field - const std::string chosen_path = picker.getFirstFile(); + const std::string chosen_path = filenames[0]; mDiffPathTextBox->setText(std::string(chosen_path)); // copy the path to the executable to the textfield for display and later fetching if(LLView::sHighlightingDiffs) // if we're already highlighting, toggle off and then on so we get the data from the new file { diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 371c7fd44e..2fc375f66d 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1345,17 +1345,35 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, } else // IM_TASK_INVENTORY_OFFERED { - if (sizeof(S8) != binary_bucket_size) + if (offline == IM_OFFLINE && session_id.isNull() && aux_id.notNull() && binary_bucket_size > sizeof(S8)* 5) { - LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL; - delete info; - // Don't flash task icon - //break; - return; + // cap received offline message + std::string str_bucket = ll_safe_string((char*)binary_bucket, binary_bucket_size); + typedef boost::tokenizer > tokenizer; + boost::char_separator sep("|", "", boost::keep_empty_tokens); + tokenizer tokens(str_bucket, sep); + tokenizer::iterator iter = tokens.begin(); + + info->mType = (LLAssetType::EType)(atoi((*(iter++)).c_str())); + // Note There is more elements in 'tokens' ... + + info->mObjectID = LLUUID::null; + info->mFromObject = TRUE; + } + else + { + if (sizeof(S8) != binary_bucket_size) + { + LL_WARNS("Messaging") << "Malformed inventory offer from object" << LL_ENDL; + delete info; + // Don't flash task icon + //break; + return; + } + info->mType = (LLAssetType::EType) binary_bucket[0]; + info->mObjectID = LLUUID::null; + info->mFromObject = TRUE; } - info->mType = (LLAssetType::EType) binary_bucket[0]; - info->mObjectID = LLUUID::null; - info->mFromObject = TRUE; } info->mIM = dialog; diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 0424206502..0a28e99955 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -1584,7 +1584,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type, break; default: - LL_INFOS() << "Unhandled asset type (llassetstorage.h): " + LL_INFOS_ONCE() << "Unhandled asset type (llassetstorage.h): " << (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << LL_ENDL; break; } @@ -6985,7 +6985,7 @@ bool confirm_attachment_rez(const LLSD& notification, const LLSD& response) if (!gAgentAvatarp->canAttachMoreObjects()) { LLSD args; - args["MAX_ATTACHMENTS"] = llformat("%d", MAX_AGENT_ATTACHMENTS); + args["MAX_ATTACHMENTS"] = llformat("%d", gAgentAvatarp->getMaxAttachments()); LLNotificationsUtil::add("MaxAttachmentsOnOutfit", args); return false; } @@ -8284,7 +8284,10 @@ void LLFolderViewGroupedItemBridge::groupFilterContextMenu(folder_view_item_dequ { if (!LLAppearanceMgr::instance().canAddWearables(ids) && canWearSelected(ids)) { - disabled_items.push_back(std::string("Wearable Add")); + disabled_items.push_back(std::string("Wearable And Object Wear")); + disabled_items.push_back(std::string("Wearable Add")); + disabled_items.push_back(std::string("Attach To")); + disabled_items.push_back(std::string("Attach To HUD")); } } disable_context_entries_if_present(menu, disabled_items); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index f1f5ec786e..96dda51a1f 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1975,9 +1975,19 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item) if (LLAssetType::lookup(item->getType()) == LLAssetType::BADLOOKUP) { - LL_WARNS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName() - << " type: " << item->getType() - << " inv-type: " << item->getInventoryType() << " ]." << LL_ENDL; + if (item->getType() >= LLAssetType::AT_COUNT) + { + // Not yet supported. + LL_DEBUGS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName() + << " type: " << item->getType() + << " inv-type: " << item->getInventoryType() << " ]." << LL_ENDL; + } + else + { + LL_WARNS(LOG_INV) << "Got unknown asset type for item [ name: " << item->getName() + << " type: " << item->getType() + << " inv-type: " << item->getInventoryType() << " ]." << LL_ENDL; + } } // This condition means that we tried to add a link without the baseobj being in memory. diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp index 95673b08a9..3e85f65068 100644 --- a/indra/newview/llinventorypanel.cpp +++ b/indra/newview/llinventorypanel.cpp @@ -968,7 +968,8 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id, LLInventoryO if (objectp->getType() >= LLAssetType::AT_COUNT) { - LL_WARNS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : " + // Example: Happens when we add assets of new, not yet supported type to library + LL_DEBUGS() << "LLInventoryPanel::buildNewViews called with unknown objectp->mType : " << ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID() << LL_ENDL; diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp index 5f2404efb3..7ebaa856f1 100644 --- a/indra/newview/lllogchat.cpp +++ b/indra/newview/lllogchat.cpp @@ -660,43 +660,10 @@ void LLLogChat::findTranscriptFiles(std::string pattern, std::vectoradd(dirname, filename); - - LLFILE * filep = LLFile::fopen(fullname, "rb"); - if (NULL != filep) + if (isTranscriptFileFound(fullname)) { - if(makeLogFileName("chat")== fullname) - { - //Add Nearby chat history to the list of transcriptions - list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename)); - LLFile::close(filep); - continue; - } - char buffer[LOG_RECALL_SIZE]; - - fseek(filep, 0, SEEK_END); // seek to end of file - S32 bytes_to_read = ftell(filep); // get current file pointer - fseek(filep, 0, SEEK_SET); // seek back to beginning of file - - // limit the number characters to read from file - if (bytes_to_read >= LOG_RECALL_SIZE) - { - bytes_to_read = LOG_RECALL_SIZE - 1; - } - - if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep)) - { - //matching a timestamp - boost::match_results matches; - // Seconds in timestamp - //if (boost::regex_match(std::string(buffer), matches, TIMESTAMP)) - if (boost::regex_match(std::string(buffer), matches, TIMESTAMP) || boost::regex_match(std::string(buffer), matches, TIMESTAMP_AND_SEC)) - // - { - list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename)); - } - } - LLFile::close(filep); - } + list_of_transcriptions.push_back(fullname); + } } } @@ -849,57 +816,13 @@ void LLLogChat::deleteTranscripts() // static bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group) { - // FIRE-13725 / CHUIBUG-222: Viewer freezes when opening preferences or right-clicking on friends' names - //std::vector list_of_transcriptions; - //LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); - - //if (list_of_transcriptions.size() > 0) - //{ - // LLAvatarName avatar_name; - // LLAvatarNameCache::get(avatar_id, &avatar_name); - // // [Legacy IM logfile names] - // //std::string avatar_user_name = avatar_name.getAccountName(); - // std::string avatar_user_name; - // if (gSavedSettings.getBOOL("UseLegacyIMLogNames")) - // { - // avatar_user_name = avatar_name.getUserName(); - // avatar_user_name = avatar_user_name.substr(0, avatar_user_name.find(" Resident"));; - // } - // else - // { - // avatar_user_name = avatar_name.getAccountName(); - // std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); - // } - // // [Legacy IM logfile names] - // if(!is_group) - // { - // //std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); - // BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) - // { - // if (std::string::npos != transcript_file_name.find(avatar_user_name)) - // { - // return true; - // } - // } - // } - // else - // { - // std::string file_name; - // gCacheName->getGroupName(avatar_id, file_name); - // file_name = makeLogFileName(file_name); - // BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) - // { - // if (transcript_file_name == file_name) - // { - // return true; - // } - // } - // } - - //} - std::string file_name; - if (!is_group) + //LLAvatarName avatar_name; + //LLAvatarNameCache::get(avatar_id, &avatar_name); + //std::string avatar_user_name = avatar_name.getAccountName(); + if(!is_group) { + // [Legacy IM logfile names] + //std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); LLAvatarName avatar_name; LLAvatarNameCache::get(avatar_id, &avatar_name); std::string avatar_user_name; @@ -913,60 +836,68 @@ bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id, bool is_group) avatar_user_name = avatar_name.getAccountName(); std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_'); } - file_name = makeLogFileName(avatar_user_name); + // [Legacy IM logfile names] + return isTranscriptFileFound(makeLogFileName(avatar_user_name)); } else { + std::string file_name; gCacheName->getGroupName(avatar_id, file_name); file_name = makeLogFileName(file_name); + return isTranscriptFileFound(makeLogFileName(file_name)); } - if ( (!file_name.empty()) && (LLFile::isfile(file_name)) ) - { - return true; - } - // - return false; } bool LLLogChat::isNearbyTranscriptExist() { - // FIRE-13725 / CHUIBUG-222: Viewer freezes when opening preferences or right-clicking on friends' names - //std::vector list_of_transcriptions; - //LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); - - //std::string file_name; - //file_name = makeLogFileName("chat"); - //BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) - //{ - // if (transcript_file_name == file_name) - // { - // return true; - // } - //} - std::string strFilePath = makeLogFileName("chat"); - if ( (!strFilePath.empty()) && (LLFile::isfile(strFilePath)) ) - { - return true; - } - // - return false; + return isTranscriptFileFound(makeLogFileName("chat"));; } bool LLLogChat::isAdHocTranscriptExist(std::string file_name) { - std::vector list_of_transcriptions; - LLLogChat::getListOfTranscriptFiles(list_of_transcriptions); + return isTranscriptFileFound(makeLogFileName(file_name));; +} - file_name = makeLogFileName(file_name); - BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions) +// static +bool LLLogChat::isTranscriptFileFound(std::string fullname) +{ + bool result = false; + LLFILE * filep = LLFile::fopen(fullname, "rb"); + if (NULL != filep) { - if (transcript_file_name == file_name) - { - return true; + if (makeLogFileName("chat") == fullname) + { + LLFile::close(filep); + return true; } + char buffer[LOG_RECALL_SIZE]; + + fseek(filep, 0, SEEK_END); // seek to end of file + S32 bytes_to_read = ftell(filep); // get current file pointer + fseek(filep, 0, SEEK_SET); // seek back to beginning of file + + // limit the number characters to read from file + if (bytes_to_read >= LOG_RECALL_SIZE) + { + bytes_to_read = LOG_RECALL_SIZE - 1; + } + + if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep)) + { + //matching a timestamp + boost::match_results matches; + // Seconds in timestamp + //if (boost::regex_match(std::string(buffer), matches, TIMESTAMP)) + if (boost::regex_match(std::string(buffer), matches, TIMESTAMP) || boost::regex_match(std::string(buffer), matches, TIMESTAMP_AND_SEC)) + // + { + result = true; + } + } + LLFile::close(filep); } - return false; + return result; } //*TODO mark object's names in a special way so that they will be distinguishable form avatar name @@ -1196,6 +1127,8 @@ void LLDeleteHistoryThread::run() LLActionThread::LLActionThread(const std::string& name) : LLThread(name), + mMutex(), + mRunCondition(), mFinished(false) { } diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h index 6022e539a9..fcbd38a044 100644 --- a/indra/newview/lllogchat.h +++ b/indra/newview/lllogchat.h @@ -121,6 +121,7 @@ public: static bool isTranscriptExist(const LLUUID& avatar_id, bool is_group=false); static bool isNearbyTranscriptExist(); static bool isAdHocTranscriptExist(std::string file_name); + static bool isTranscriptFileFound(std::string fullname); static bool historyThreadsFinished(LLUUID session_id); static LLLoadHistoryThread* getLoadHistoryThread(LLUUID session_id); diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp index 9208e105bb..2df3b58b0f 100644 --- a/indra/newview/lllogininstance.cpp +++ b/indra/newview/lllogininstance.cpp @@ -63,6 +63,9 @@ #include const S32 LOGIN_MAX_RETRIES = 3; +const F32 LOGIN_SRV_TIMEOUT_MIN = 10.f; +const F32 LOGIN_SRV_TIMEOUT_MAX = 120.f; +const F32 LOGIN_DNS_TIMEOUT_FACTOR = 0.9f; // make DNS wait shorter then retry time class LLLoginInstance::Disposable { public: @@ -252,8 +255,10 @@ void LLLoginInstance::constructAuthParams(LLPointer user_credentia // Specify desired timeout/retry options LLSD http_params; - http_params["timeout"] = gSavedSettings.getF32("LoginSRVTimeout"); + F32 srv_timeout = llclamp(gSavedSettings.getF32("LoginSRVTimeout"), LOGIN_SRV_TIMEOUT_MIN, LOGIN_SRV_TIMEOUT_MAX); + http_params["timeout"] = srv_timeout; http_params["retries"] = LOGIN_MAX_RETRIES; + http_params["DNSCacheTimeout"] = srv_timeout * LOGIN_DNS_TIMEOUT_FACTOR; //Default: indefinite mRequestData.clear(); mRequestData["method"] = "login_to_simulator"; diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp index 79bab4b077..6736e9a950 100644 --- a/indra/newview/llmainlooprepeater.cpp +++ b/indra/newview/llmainlooprepeater.cpp @@ -46,7 +46,7 @@ void LLMainLoopRepeater::start(void) { if(mQueue != 0) return; - mQueue = new LLThreadSafeQueue( 1024); + mQueue = new LLThreadSafeQueue(1024); mMainLoopConnection = LLEventPumps::instance(). obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1)); mRepeaterConnection = LLEventPumps::instance(). diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp index 38417b4b3e..bf4579c756 100644 --- a/indra/newview/llmanip.cpp +++ b/indra/newview/llmanip.cpp @@ -479,7 +479,6 @@ void LLManip::renderXYZ(const LLVector3 &vec) { const S32 PAD = 10; std::string feedback_string; - LLVector3 camera_pos = LLViewerCamera::getInstance()->getOrigin() + LLViewerCamera::getInstance()->getAtAxis(); S32 window_center_x = gViewerWindow->getWorldViewRectScaled().getWidth() / 2; S32 window_center_y = gViewerWindow->getWorldViewRectScaled().getHeight() / 2; S32 vertical_offset = window_center_y - VERTICAL_OFFSET; @@ -490,46 +489,54 @@ void LLManip::renderXYZ(const LLVector3 &vec) LLUIImagePtr imagep = LLUI::getUIImage("Rounded_Square"); gViewerWindow->setup2DRender(); const LLVector2& display_scale = gViewerWindow->getDisplayScale(); - gGL.scalef(display_scale.mV[VX], display_scale.mV[VY], 1.f); gGL.color4f(0.f, 0.f, 0.f, 0.7f); imagep->draw( - window_center_x - 115, - window_center_y + vertical_offset - PAD, - 235, - PAD * 2 + 10, + (window_center_x - 115) * display_scale.mV[VX], + (window_center_y + vertical_offset - PAD) * display_scale.mV[VY], + 235 * display_scale.mV[VX], + (PAD * 2 + 10) * display_scale.mV[VY], LLColor4(0.f, 0.f, 0.f, 0.7f) ); - } - gGL.popMatrix(); + LLFontGL* font = LLFontGL::getFontSansSerif(); + LLLocale locale(LLLocale::USER_LOCALE); + LLGLDepthTest gls_depth(GL_FALSE); - gViewerWindow->setup3DRender(); + // render drop shadowed text (manually because of bigger 'distance') + F32 right_x; + feedback_string = llformat("X: %.3f", vec.mV[VX]); + font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 102.f + 1.f, window_center_y + vertical_offset - 2.f, LLColor4::black, + LLFontGL::LEFT, LLFontGL::BASELINE, + LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x); - { - LLFontGL* font = LLFontGL::getFontSansSerif(); - LLLocale locale(LLLocale::USER_LOCALE); - LLGLDepthTest gls_depth(GL_FALSE); - // render drop shadowed text - feedback_string = llformat("X: %.3f", vec.mV[VX]); - hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE); + feedback_string = llformat("Y: %.3f", vec.mV[VY]); + font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 27.f + 1.f, window_center_y + vertical_offset - 2.f, LLColor4::black, + LLFontGL::LEFT, LLFontGL::BASELINE, + LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x); - feedback_string = llformat("Y: %.3f", vec.mV[VY]); - hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE); - - feedback_string = llformat("Z: %.3f", vec.mV[VZ]); - hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f + 1.f, (F32)vertical_offset - 1.f, LLColor4::black, FALSE); + feedback_string = llformat("Z: %.3f", vec.mV[VZ]); + font->render(utf8str_to_wstring(feedback_string), 0, window_center_x + 48.f + 1.f, window_center_y + vertical_offset - 2.f, LLColor4::black, + LLFontGL::LEFT, LLFontGL::BASELINE, + LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x); - // render text on top - feedback_string = llformat("X: %.3f", vec.mV[VX]); - hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -102.f, (F32)vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f), FALSE); + // render text on top + feedback_string = llformat("X: %.3f", vec.mV[VX]); + font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 102.f, window_center_y + vertical_offset, LLColor4(1.f, 0.5f, 0.5f, 1.f), + LLFontGL::LEFT, LLFontGL::BASELINE, + LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x); - gGL.diffuseColor3f(0.5f, 1.f, 0.5f); - feedback_string = llformat("Y: %.3f", vec.mV[VY]); - hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, -27.f, (F32)vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f), FALSE); - - gGL.diffuseColor3f(0.5f, 0.5f, 1.f); - feedback_string = llformat("Z: %.3f", vec.mV[VZ]); - hud_render_text(utf8str_to_wstring(feedback_string), camera_pos, *font, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 48.f, (F32)vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f), FALSE); - } + feedback_string = llformat("Y: %.3f", vec.mV[VY]); + font->render(utf8str_to_wstring(feedback_string), 0, window_center_x - 27.f, window_center_y + vertical_offset, LLColor4(0.5f, 1.f, 0.5f, 1.f), + LLFontGL::LEFT, LLFontGL::BASELINE, + LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x); + + feedback_string = llformat("Z: %.3f", vec.mV[VZ]); + font->render(utf8str_to_wstring(feedback_string), 0, window_center_x + 48.f, window_center_y + vertical_offset, LLColor4(0.5f, 0.5f, 1.f, 1.f), + LLFontGL::LEFT, LLFontGL::BASELINE, + LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, 1000, &right_x); + } + gGL.popMatrix(); + + gViewerWindow->setup3DRender(); } void LLManip::renderTickText(const LLVector3& pos, const std::string& text, const LLColor4 &color) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index cf52983982..de684be963 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -26,10 +26,11 @@ #include "llviewerprecompiledheaders.h" +#include "llapr.h" +#include "apr_portable.h" #include "apr_pools.h" #include "apr_dso.h" #include "llhttpconstants.h" -#include "llapr.h" #include "llmeshrepository.h" #include "llagent.h" @@ -1912,7 +1913,22 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat return false; } - header_size += stream.tellg(); + if (!header.isMap()) + { + LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL; + return false; + } + + if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION) + { + LL_INFOS(LOG_MESH) << "Wrong version in header for " << mesh_id << LL_ENDL; + header["404"] = 1; + } + // make sure there is at least one lod, function returns -1 and marks as 404 otherwise + else if (LLMeshRepository::getActualMeshLOD(header, 0) >= 0) + { + header_size += stream.tellg(); + } } else { @@ -2264,7 +2280,6 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) std::map mesh_index; std::string model_name; - std::string model_metric; S32 instance_num = 0; @@ -2294,11 +2309,6 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) model_name = data.mBaseModel->getName(); } - if (model_metric.empty()) - { - model_metric = data.mBaseModel->getMetric(); - } - std::stringstream ostr; LLModel::Decomposition& decomp = @@ -2453,11 +2463,6 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) model_name = data.mBaseModel->getName(); } - if (model_metric.empty()) - { - model_metric = data.mBaseModel->getMetric(); - } - std::stringstream ostr; LLModel::Decomposition& decomp = @@ -2588,8 +2593,7 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) if (model_name.empty()) model_name = "mesh model"; result["name"] = model_name; - if (model_metric.empty()) model_metric = "MUT_Unspecified"; - res["metric"] = model_metric; + res["metric"] = "MUT_Unspecified"; result["asset_resources"] = res; dump_llsd_to_file(result,make_dump_name("whole_model_",dump_num)); @@ -3009,12 +3013,17 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod) { lod = llclamp(lod, 0, 3); + if (header.has("404")) + { + return -1; + } + // OpenSim mesh fix //S32 version = header["version"]; S32 version = header["version"].asInteger(); // - if (header.has("404") || version > MAX_MESH_VERSION) + if (version > MAX_MESH_VERSION) { return -1; } @@ -3261,11 +3270,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b if (header_bytes > 0 && !header.has("404") - // OpenSim mesh fix - //&& header.has("version") - && (header.has("version") || !LLGridManager::instance().isInSecondLife()) - // - && header["version"].asInteger() <= MAX_MESH_VERSION) + && (!header.has("version") || header["version"].asInteger() <= MAX_MESH_VERSION)) { std::stringstream str; @@ -4472,17 +4477,13 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte F32 dlow = llmin(radius/0.06f, max_distance); F32 dmid = llmin(radius/0.24f, max_distance); - // replace often called setting with LLCachedControl - // F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount"); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead - // F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free" + static LLCachedControl metadata_discount_ch(gSavedSettings, "MeshMetaDataDiscount", 384); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead + static LLCachedControl minimum_size_ch(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free" + static LLCachedControl bytes_per_triangle_ch(gSavedSettings, "MeshBytesPerTriangle", 16); - // F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle"); - - static LLCachedControl< U32 > METADATA_DISCOUNT( gSavedSettings, "MeshMetaDataDiscount"); - static LLCachedControl< U32 > MINIMUM_SIZE( gSavedSettings, "MeshMinimumByteSize"); - static LLCachedControl< U32 > bytes_per_triangle( gSavedSettings ,"MeshBytesPerTriangle"); - - // + F32 metadata_discount = (F32)metadata_discount_ch; + F32 minimum_size = (F32)minimum_size_ch; + F32 bytes_per_triangle = (F32)bytes_per_triangle_ch; S32 bytes_lowest = header["lowest_lod"]["size"].asInteger(); S32 bytes_low = header["low_lod"]["size"].asInteger(); @@ -4509,18 +4510,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte bytes_lowest = bytes_low; } - // replace often called setting with LLCachedControl - // F32 triangles_lowest = llmax((F32) bytes_lowest-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; - // F32 triangles_low = llmax((F32) bytes_low-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; - // F32 triangles_mid = llmax((F32) bytes_mid-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; - // F32 triangles_high = llmax((F32) bytes_high-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; - - F32 triangles_lowest = llmax((F32) bytes_lowest-(F32)METADATA_DISCOUNT, (F32)MINIMUM_SIZE)/(F32)bytes_per_triangle; - F32 triangles_low = llmax((F32) bytes_low-(F32)METADATA_DISCOUNT, (F32)MINIMUM_SIZE)/(F32)bytes_per_triangle; - F32 triangles_mid = llmax((F32) bytes_mid-(F32)METADATA_DISCOUNT, (F32)MINIMUM_SIZE)/(F32)bytes_per_triangle; - F32 triangles_high = llmax((F32) bytes_high-(F32)METADATA_DISCOUNT, (F32)MINIMUM_SIZE)/(F32)bytes_per_triangle; - - // + F32 triangles_lowest = llmax((F32) bytes_lowest-metadata_discount, minimum_size)/bytes_per_triangle; + F32 triangles_low = llmax((F32) bytes_low-metadata_discount, minimum_size)/bytes_per_triangle; + F32 triangles_mid = llmax((F32) bytes_mid-metadata_discount, minimum_size)/bytes_per_triangle; + F32 triangles_high = llmax((F32) bytes_high-metadata_discount, minimum_size)/bytes_per_triangle; if (bytes) { @@ -4619,13 +4612,13 @@ bool LLMeshCostData::init(const LLSD& header) mSizeByLOD[2] = bytes_med; mSizeByLOD[3] = bytes_high; - F32 METADATA_DISCOUNT = (F32) gSavedSettings.getU32("MeshMetaDataDiscount"); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead - F32 MINIMUM_SIZE = (F32) gSavedSettings.getU32("MeshMinimumByteSize"); //make sure nothing is "free" - F32 bytes_per_triangle = (F32) gSavedSettings.getU32("MeshBytesPerTriangle"); + static LLCachedControl metadata_discount(gSavedSettings, "MeshMetaDataDiscount", 384); //discount 128 bytes to cover the cost of LLSD tags and compression domain overhead + static LLCachedControl minimum_size(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free" + static LLCachedControl bytes_per_triangle(gSavedSettings, "MeshBytesPerTriangle", 16); for (S32 i=0; i<4; i++) { - mEstTrisByLOD[i] = llmax((F32) mSizeByLOD[i]-METADATA_DISCOUNT, MINIMUM_SIZE)/bytes_per_triangle; + mEstTrisByLOD[i] = llmax((F32)mSizeByLOD[i] - (F32)metadata_discount, (F32)minimum_size) / (F32)bytes_per_triangle; } return true; diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp index 93b3b540b7..54e0079472 100644 --- a/indra/newview/llmoveview.cpp +++ b/indra/newview/llmoveview.cpp @@ -772,7 +772,6 @@ void LLPanelStandStopFlying::updatePosition() // Keep the Stand & Stop Flying panel always in the same position, // if (mAttached) return; // -// S32 y_pos = 0; // S32 bottom_tb_center = 0; // if (LLToolBar* toolbar_bottom = gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_BOTTOM)) // { @@ -786,20 +785,6 @@ void LLPanelStandStopFlying::updatePosition() // left_tb_width = toolbar_left->getRect().getWidth(); // } // -// if (!mStateManagementButtons.get()) // Obsolete?!! -// { -// LLPanel* panel_ssf_container = gToolBarView->getChild("state_management_buttons_container"); -// if (panel_ssf_container) -// { -// mStateManagementButtons = panel_ssf_container->getHandle(); -// } -// } -// -// if(LLPanel* panel_ssf_container = mStateManagementButtons.get()) -// { -// panel_ssf_container->setOrigin(0, y_pos); -// } -// // if (gToolBarView != NULL && gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)->hasButtons()) // { // S32 x_pos = bottom_tb_center - getRect().getWidth() / 2 - left_tb_width; diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h index 0e2a262486..9d183bbd19 100644 --- a/indra/newview/llmoveview.h +++ b/indra/newview/llmoveview.h @@ -177,8 +177,6 @@ private: */ LLHandle mOriginalParent; - LLHandle mStateManagementButtons; - /** * True if the panel is currently attached to the movement controls floater. * diff --git a/indra/newview/llnotificationlistitem.cpp b/indra/newview/llnotificationlistitem.cpp index 99c6ffcba1..136009d38f 100644 --- a/indra/newview/llnotificationlistitem.cpp +++ b/indra/newview/llnotificationlistitem.cpp @@ -136,7 +136,8 @@ std::string LLNotificationListItem::buildNotificationDate(const LLDate& time_sta // +LLTrans::getString("TimeDay")+"]/[" // +LLTrans::getString("TimeYear")+"] [" // +LLTrans::getString("TimeHour")+"]:[" - // +LLTrans::getString("TimeMin")+"]"; + // +LLTrans::getString("TimeMin")+"] [" + // +LLTrans::getString("TimeTimezone")+"]"; // break; case Local: timeStr = LLTrans::getString("NotificationItemDateStringLocal"); @@ -388,24 +389,14 @@ BOOL LLGroupNoticeNotificationListItem::postBuild() mTitleBoxExp->setValue(mParams.subject); mNoticeTextExp->setValue(mParams.message); - // FIRE-17313: Display group notices in SLT - //mTimeBox->setValue(buildNotificationDate(mParams.time_stamp, UTC)); - //mTimeBoxExp->setValue(buildNotificationDate(mParams.time_stamp, UTC)); - ////Workaround: in case server timestamp is 0 - we use the time when notification was actually received - //if (mParams.time_stamp.isNull()) - //{ - // mTimeBox->setValue(buildNotificationDate(mParams.received_time, UTC)); - // mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time, UTC)); - //} - mTimeBox->setValue(buildNotificationDate(mParams.time_stamp, SLT)); - mTimeBoxExp->setValue(buildNotificationDate(mParams.time_stamp, SLT)); + mTimeBox->setValue(buildNotificationDate(mParams.time_stamp)); + mTimeBoxExp->setValue(buildNotificationDate(mParams.time_stamp)); //Workaround: in case server timestamp is 0 - we use the time when notification was actually received if (mParams.time_stamp.isNull()) { - mTimeBox->setValue(buildNotificationDate(mParams.received_time, SLT)); - mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time, SLT)); + mTimeBox->setValue(buildNotificationDate(mParams.received_time)); + mTimeBoxExp->setValue(buildNotificationDate(mParams.received_time)); } - // setSender(mParams.sender); if (mInventoryOffer != NULL) diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 1e09cd1f2a..46472051ab 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -691,8 +691,14 @@ void LLOutfitsList::applyFilterToTab( bool LLOutfitsList::canWearSelected() { + if (!isAgentAvatarValid()) + { + return false; + } + uuid_vec_t selected_items; getSelectedItemsUUIDs(selected_items); + S32 nonreplacable_objects = 0; for (uuid_vec_t::const_iterator it = selected_items.begin(); it != selected_items.end(); ++it) { @@ -703,10 +709,21 @@ bool LLOutfitsList::canWearSelected() { return false; } + + const LLViewerInventoryItem* item = gInventory.getItem(id); + if (!item) + { + return false; + } + + if (item->getType() == LLAssetType::AT_OBJECT) + { + nonreplacable_objects++; + } } - // All selected items can be worn. - return true; + // All selected items can be worn. But do we have enough space for them? + return nonreplacable_objects == 0 || gAgentAvatarp->canAttachMoreObjects(nonreplacable_objects); } void LLOutfitsList::wearSelectedItems() diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp index 492daea14d..96f2cdf63c 100644 --- a/indra/newview/lloutputmonitorctrl.cpp +++ b/indra/newview/lloutputmonitorctrl.cpp @@ -74,9 +74,12 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p) mImageLevel3(p.image_level_3), mAutoUpdate(p.auto_update), mSpeakerId(p.speaker_id), + mIsModeratorMuted(false), mIsAgentControl(false), mIndicatorToggled(false), - mShowParticipantsSpeaking(false) + mShowParticipantsSpeaking(false), + mChannelState(INACTIVE_CHANNEL), + mAlwaysVisible(false) // Option to not hide it if speaker ID is set to null { //static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange); //static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red); @@ -128,7 +131,7 @@ void LLOutputMonitorCtrl::draw() //const F32 LEVEL_2 = LLVoiceClient::OVERDRIVEN_POWER_LEVEL; // Centralized voice power level - if (getVisible() && mAutoUpdate && !mIsMuted && mSpeakerId.notNull()) + if (getVisible() && mAutoUpdate && !getIsMuted() && mSpeakerId.notNull()) { setPower(LLVoiceClient::getInstance()->getCurrentPower(mSpeakerId)); if(mIsAgentControl) @@ -161,7 +164,7 @@ void LLOutputMonitorCtrl::draw() LLPointer icon; // Centralized voice power level - //if (mIsMuted) + //if (getIsMuted()) //{ // icon = mImageMute; //} @@ -291,12 +294,29 @@ BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask) return TRUE; } +void LLOutputMonitorCtrl::setIsActiveChannel(bool val) +{ + setChannelState(val ? ACTIVE_CHANNEL : INACTIVE_CHANNEL); +} + +void LLOutputMonitorCtrl::setChannelState(EChannelState state) +{ + mChannelState = state; + if (state == INACTIVE_CHANNEL) + { + // switchIndicator will set it to TRUE when channel becomes active + setVisible(FALSE); + } +} + void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/, bool show_other_participants_speaking /* = false */) { if (speaker_id.isNull() && mSpeakerId.notNull()) { LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this); - switchIndicator(false); + // Option to not hide it if speaker ID is set to null + if (!mAlwaysVisible) + switchIndicator(false); mSpeakerId = speaker_id; } @@ -340,8 +360,10 @@ void LLOutputMonitorCtrl::onChange() // virtual void LLOutputMonitorCtrl::switchIndicator(bool switch_on) { - - if(getVisible() != (BOOL)switch_on) + // [FS communication UI] + //if ((mChannelState != INACTIVE_CHANNEL) && (getVisible() != (BOOL)switch_on)) + if (getVisible() != (BOOL)switch_on) + // [FS communication UI] { setVisible(switch_on); @@ -383,7 +405,7 @@ void LLOutputMonitorCtrl::notifyParentVisibilityChanged() static LLDefaultChildRegistry::Register r2("nearby_voice_monitor"); NearbyVoiceMonitor::Params::Params() -: auto_hide("auto_hide",false) +: auto_hide("auto_hide", false) { } @@ -391,39 +413,37 @@ NearbyVoiceMonitor::NearbyVoiceMonitor(const NearbyVoiceMonitor::Params& p) : LLOutputMonitorCtrl(p), mAutoHide(p.auto_hide) { - mSpeakerMgr=LLLocalSpeakerMgr::getInstance(); + mAlwaysVisible = true; + mSpeakerMgr = LLLocalSpeakerMgr::getInstance(); } void NearbyVoiceMonitor::draw() { LLSpeakerMgr::speaker_list_t speaker_list; LLUUID id; - BOOL draw=FALSE; + bool draw = false; - id.setNull(); mSpeakerMgr->update(TRUE); mSpeakerMgr->getSpeakerList(&speaker_list, FALSE); - for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i) + for (LLSpeakerMgr::speaker_list_t::const_iterator it = speaker_list.begin(); it != speaker_list.end(); ++it) { - LLPointer s = *i; - if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING) + LLPointer speaker = *it; + if (speaker->mSpeechVolume > 0.f || speaker->mStatus == LLSpeaker::STATUS_SPEAKING) { - draw=TRUE; - id = s->mID; + draw = true; + id = speaker->mID; break; } } setSpeakerId(id); - switchIndicator(true); // Ansa: Make sure the output monitor is visible at all times - if(!mAutoHide || draw) + if (!mAutoHide || draw) { LLOutputMonitorCtrl::draw(); } } - // Add new control to have a nearby voice output monitor ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h index fdc4224772..0c4619422a 100644 --- a/indra/newview/lloutputmonitorctrl.h +++ b/indra/newview/lloutputmonitorctrl.h @@ -63,6 +63,9 @@ protected: LLOutputMonitorCtrl(const Params&); friend class LLUICtrlFactory; + // Option to not hide it if speaker ID is set to null + bool mAlwaysVisible; + public: virtual ~LLOutputMonitorCtrl(); @@ -72,18 +75,26 @@ public: void setPower(F32 val); F32 getPower(F32 val) const { return mPower; } - - // FS Communications UI - bool getIsMuted() const { return mIsMuted; } - void setIsMuted(bool val) { mIsMuted = val; } - // - + + bool getIsMuted() const { return (mIsMuted || mIsModeratorMuted); } + void setIsModeratorMuted(bool val) { mIsModeratorMuted = val; } + // For the current user, need to know the PTT state to show // correct button image. void setIsAgentControl(bool val) { mIsAgentControl = val; } - void setIsTalking(bool val) { mIsTalking = val; } + enum EChannelState + { + ACTIVE_CHANNEL, + INACTIVE_CHANNEL, + UNDEFINED_CHANNEL + }; + + // switchIndicator controls visibility, 'active channel' governs if we are allowed to show indicator + void setIsActiveChannel(bool val); + void setChannelState(EChannelState state); + void setShowParticipantsSpeaking(bool show) { mShowParticipantsSpeaking = show; } /** @@ -136,6 +147,7 @@ private: F32 mPower; bool mIsAgentControl; + bool mIsModeratorMuted; bool mIsMuted; bool mIsTalking; bool mShowParticipantsSpeaking; @@ -153,6 +165,8 @@ private: LLUUID mSpeakerId; bool mIndicatorToggled; + + EChannelState mChannelState; }; ////////////////////////////////////////////////////////////////////////// @@ -170,12 +184,12 @@ public: Params(); }; - NearbyVoiceMonitor(const Params& p); + NearbyVoiceMonitor(const Params& p); void draw(); protected: - BOOL mAutoHide; + bool mAutoHide; LLLocalSpeakerMgr* mSpeakerMgr; }; diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp index 2ca590a4ba..93bae46f97 100644 --- a/indra/newview/llpanelclassified.cpp +++ b/indra/newview/llpanelclassified.cpp @@ -647,12 +647,9 @@ BOOL LLPanelClassifiedEdit::postBuild() { LLPanelClassifiedInfo::postBuild(); - LLTextureCtrl* snapshot = getChild("classified_snapshot"); - snapshot->setOnSelectCallback(boost::bind(&LLPanelClassifiedEdit::onChange, this)); - LLUICtrl* edit_icon = getChild("edit_icon"); - snapshot->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon)); - snapshot->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon)); + mSnapshotCtrl->setMouseEnterCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseEnter, this, edit_icon)); + mSnapshotCtrl->setMouseLeaveCallback(boost::bind(&LLPanelClassifiedEdit::onTexturePickerMouseLeave, this, edit_icon)); edit_icon->setVisible(false); LLLineEditor* line_edit = getChild("classified_name"); @@ -1166,6 +1163,7 @@ void LLPanelClassifiedEdit::onTexturePickerMouseLeave(LLUICtrl* ctrl) void LLPanelClassifiedEdit::onTextureSelected() { setSnapshotId(mSnapshotCtrl->getValue().asUUID()); + onChange(); } ////////////////////////////////////////////////////////////////////////// diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index b9fb242265..c38a7c2bd4 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -1568,6 +1568,11 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) mColorSwatch->setFallbackImage(LLUI::getUIImage("locked_image.j2c") ); mColorSwatch->setValid(FALSE); } + LLRadioGroup* radio_mat_type = getChild("radio_material_type"); + if (radio_mat_type) + { + radio_mat_type->setSelectedIndex(0); + } getChildView("color trans")->setEnabled(FALSE); mCtrlRpt->setEnabled(FALSE); getChildView("tex gen")->setEnabled(FALSE); diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp index 25a5a1c08e..c8936ed6ec 100644 --- a/indra/newview/llpanelgroupgeneral.cpp +++ b/indra/newview/llpanelgroupgeneral.cpp @@ -555,11 +555,12 @@ bool LLPanelGroupGeneral::createGroupCallback(const LLSD& notification, const LL // Yay! We are making a new group! U32 enrollment_fee = (mCtrlEnrollmentFee->get() ? (U32) mSpinEnrollmentFee->get() : 0); - + LLUUID insignia_id = mInsignia->getImageItemID().isNull() ? LLUUID::null : mInsignia->getImageAssetID(); + LLGroupMgr::getInstance()->sendCreateGroupRequest(mGroupNameEditor->getText(), mEditCharter->getText(), mCtrlShowInGroupList->get(), - mInsignia->getImageAssetID(), + insignia_id, enrollment_fee, mCtrlOpenEnrollment->get(), false, diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp index 8db5506f4a..07ea4b0f97 100644 --- a/indra/newview/llpaneloutfitsinventory.cpp +++ b/indra/newview/llpaneloutfitsinventory.cpp @@ -259,6 +259,11 @@ void LLPanelOutfitsInventory::onSave() // FIRE-17626: Attachment count in appearance floater void LLPanelOutfitsInventory::onCOFChanged() { + if (!isAgentAvatarValid()) + { + return; + } + const LLUUID cof = LLAppearanceMgr::instance().getCOF(); LLInventoryModel::item_array_t obj_items; LLInventoryModel::cat_array_t cats; @@ -268,7 +273,7 @@ void LLPanelOutfitsInventory::onCOFChanged() LLStringUtil::format_map_t args; args["COUNT"] = llformat("%d", attachments); - args["MAX"] = llformat("%d", MAX_AGENT_ATTACHMENTS); + args["MAX"] = llformat("%d", gAgentAvatarp->getMaxAttachments()); std::string title = getString("cof_tab_label", args); mAppearanceTabs->setPanelTitle(mAppearanceTabs->getIndexForPanel(mCurrentOutfitPanel), title); } diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp index 9dc652a535..cabe536391 100644 --- a/indra/newview/llpanelpeople.cpp +++ b/indra/newview/llpanelpeople.cpp @@ -67,6 +67,7 @@ #include "llrecentpeople.h" #include "llviewercontrol.h" // for gSavedSettings #include "llviewermenu.h" // for gMenuHolder +#include "llviewerregion.h" #include "llvoiceclient.h" #include "llworld.h" #include "llspeakers.h" @@ -662,6 +663,19 @@ void LLPanelPeople::removePicker() BOOL LLPanelPeople::postBuild() { + // Don't bother with "want more?" advertisement + //S32 max_premium = PREMIUM_MAX_AGENT_GROUPS; + //if (gAgent.getRegion()) + //{ + // LLSD features; + // gAgent.getRegion()->getSimulatorFeatures(features); + // if (features.has("MaxAgentGroupsPremium")) + // { + // max_premium = features["MaxAgentGroupsPremium"].asInteger(); + // } + //} + // + // Firestorm radar //getChild("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); getChild("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); @@ -669,7 +683,7 @@ BOOL LLPanelPeople::postBuild() getChild("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2)); // Don't bother with "want more?" advertisement - //if(gMaxAgentGroups <= BASE_MAX_AGENT_GROUPS) + //if(gMaxAgentGroups <= max_premium) //{ // getChild("groupcount")->setText(getString("GroupCountWithInfo")); // getChild("groupcount")->setURLClickedCallback(boost::bind(&LLPanelPeople::onGroupLimitInfo, this)); @@ -1328,8 +1342,25 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string) void LLPanelPeople::onGroupLimitInfo() { LLSD args; - args["MAX_BASIC"] = BASE_MAX_AGENT_GROUPS; - args["MAX_PREMIUM"] = PREMIUM_MAX_AGENT_GROUPS; + + S32 max_basic = BASE_MAX_AGENT_GROUPS; + S32 max_premium = PREMIUM_MAX_AGENT_GROUPS; + if (gAgent.getRegion()) + { + LLSD features; + gAgent.getRegion()->getSimulatorFeatures(features); + if (features.has("MaxAgentGroupsBasic")) + { + max_basic = features["MaxAgentGroupsBasic"].asInteger(); + } + if (features.has("MaxAgentGroupsPremium")) + { + max_premium = features["MaxAgentGroupsPremium"].asInteger(); + } + } + args["MAX_BASIC"] = max_basic; + args["MAX_PREMIUM"] = max_premium; + LLNotificationsUtil::add("GroupLimitInfo", args); } diff --git a/indra/newview/llsearchableui.cpp b/indra/newview/llsearchableui.cpp new file mode 100644 index 0000000000..de90896548 --- /dev/null +++ b/indra/newview/llsearchableui.cpp @@ -0,0 +1,159 @@ +/** +* @file llsearchableui.cpp +* +* $LicenseInfo:firstyear=2019&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2019, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" +#include "llsearchableui.h" + +#include "llview.h" +#include "lltabcontainer.h" +#include "llmenugl.h" + +ll::prefs::SearchableItem::~SearchableItem() +{} + +void ll::prefs::SearchableItem::setNotHighlighted() +{ + mCtrl->setHighlighted( false ); +} + +bool ll::prefs::SearchableItem::hightlightAndHide( LLWString const &aFilter ) +{ + if( mCtrl->getHighlighted() ) + return true; + + LLView const *pView = dynamic_cast< LLView const* >( mCtrl ); + if( pView && !pView->getVisible() ) + return false; + + if( aFilter.empty() ) + { + mCtrl->setHighlighted( false ); + return true; + } + + if( mLabel.find( aFilter ) != LLWString::npos ) + { + mCtrl->setHighlighted( true ); + return true; + } + + return false; +} + +ll::prefs::PanelData::~PanelData() +{} + +bool ll::prefs::PanelData::hightlightAndHide( LLWString const &aFilter ) +{ + for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr ) + (*itr)->setNotHighlighted( ); + + if (aFilter.empty()) + { + return true; + } + + bool bVisible(false); + for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr ) + bVisible |= (*itr)->hightlightAndHide( aFilter ); + + for( tPanelDataList::iterator itr = mChildPanel.begin(); itr != mChildPanel.end(); ++itr ) + bVisible |= (*itr)->hightlightAndHide( aFilter ); + + return bVisible; +} + +bool ll::prefs::TabContainerData::hightlightAndHide( LLWString const &aFilter ) +{ + for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr ) + (*itr)->setNotHighlighted( ); + + bool bVisible(false); + for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr ) + bVisible |= (*itr)->hightlightAndHide( aFilter ); + + for( tPanelDataList::iterator itr = mChildPanel.begin(); itr != mChildPanel.end(); ++itr ) + { + bool bPanelVisible = (*itr)->hightlightAndHide( aFilter ); + if( (*itr)->mPanel ) + mTabContainer->setTabVisibility( (*itr)->mPanel, bPanelVisible ); + bVisible |= bPanelVisible; + } + + return bVisible; +} + +ll::statusbar::SearchableItem::SearchableItem() + : mMenu(0) + , mCtrl(0) + , mWasHiddenBySearch( false ) +{ } + +void ll::statusbar::SearchableItem::setNotHighlighted( ) +{ + for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr ) + (*itr)->setNotHighlighted( ); + + if( mCtrl ) + { + mCtrl->setHighlighted( false ); + + if( mWasHiddenBySearch ) + mMenu->setVisible( TRUE ); + } +} + +bool ll::statusbar::SearchableItem::hightlightAndHide( LLWString const &aFilter ) +{ + if( mMenu && !mMenu->getVisible() && !mWasHiddenBySearch ) + return false; + + setNotHighlighted( ); + + bool bVisible(false); + for( tSearchableItemList::iterator itr = mChildren.begin(); itr != mChildren.end(); ++itr ) + bVisible |= (*itr)->hightlightAndHide( aFilter ); + + if( aFilter.empty() ) + { + if( mCtrl ) + mCtrl->setHighlighted( false ); + return true; + } + + if( mLabel.find( aFilter ) != LLWString::npos ) + { + if( mCtrl ) + mCtrl->setHighlighted( true ); + return true; + } + + if( mCtrl && !bVisible ) + { + mWasHiddenBySearch = true; + mMenu->setVisible(FALSE); + } + return bVisible; +} diff --git a/indra/newview/llsearchableui.h b/indra/newview/llsearchableui.h new file mode 100644 index 0000000000..42b2866fb6 --- /dev/null +++ b/indra/newview/llsearchableui.h @@ -0,0 +1,121 @@ +/** +* @file llsearchableui.h +* +* $LicenseInfo:firstyear=2019&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2019, 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_SEARCHABLE_UI_H +#define LL_SEARCHABLE_UI_H + +class LLMenuItemGL; +class LLView; +class LLPanel; +class LLTabContainer; + +#include "llsearchablecontrol.h" + +namespace ll +{ + namespace prefs + { + struct SearchableItem; + struct PanelData; + struct TabContainerData; + + typedef boost::shared_ptr< SearchableItem > SearchableItemPtr; + typedef boost::shared_ptr< PanelData > PanelDataPtr; + typedef boost::shared_ptr< TabContainerData > TabContainerDataPtr; + + typedef std::vector< TabContainerData > tTabContainerDataList; + typedef std::vector< SearchableItemPtr > tSearchableItemList; + typedef std::vector< PanelDataPtr > tPanelDataList; + + struct SearchableItem + { + LLWString mLabel; + LLView const *mView; + ll::ui::SearchableControl const *mCtrl; + + std::vector< boost::shared_ptr< SearchableItem > > mChildren; + + virtual ~SearchableItem(); + + void setNotHighlighted(); + virtual bool hightlightAndHide( LLWString const &aFilter ); + }; + + struct PanelData + { + LLPanel const *mPanel; + std::string mLabel; + + std::vector< boost::shared_ptr< SearchableItem > > mChildren; + std::vector< boost::shared_ptr< PanelData > > mChildPanel; + + virtual ~PanelData(); + + virtual bool hightlightAndHide( LLWString const &aFilter ); + }; + + struct TabContainerData: public PanelData + { + LLTabContainer *mTabContainer; + virtual bool hightlightAndHide( LLWString const &aFilter ); + }; + + struct SearchData + { + TabContainerDataPtr mRootTab; + LLWString mLastFilter; + }; + } + namespace statusbar + { + struct SearchableItem; + + typedef boost::shared_ptr< SearchableItem > SearchableItemPtr; + + typedef std::vector< SearchableItemPtr > tSearchableItemList; + + struct SearchableItem + { + LLWString mLabel; + LLMenuItemGL *mMenu; + tSearchableItemList mChildren; + ll::ui::SearchableControl const *mCtrl; + bool mWasHiddenBySearch; + + SearchableItem(); + + void setNotHighlighted( ); + bool hightlightAndHide( LLWString const &aFilter ); + }; + + struct SearchData + { + SearchableItemPtr mRootMenu; + LLWString mLastFilter; + }; + } +} + +#endif diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp index 7ed7d1733e..629851ea0a 100644 --- a/indra/newview/llstatusbar.cpp +++ b/indra/newview/llstatusbar.cpp @@ -82,12 +82,13 @@ #include "llparcel.h" #include "llstring.h" #include "message.h" +#include "llsearchableui.h" +#include "llsearcheditor.h" // system includes #include // Firestorm includes -#include "fssearchableui.h" #include "llagentui.h" #include "llaudioengine.h" #include "llclipboard.h" @@ -183,13 +184,12 @@ LLStatusBar::LLStatusBar(const LLRect& rect) mShowParcelIcons(TRUE), mSquareMetersCredit(0), mSquareMetersCommitted(0), + mFilterEdit(NULL), // Edit for filtering + mSearchPanel(NULL), // Panel for filtering mPathfindingFlashOn(TRUE), // Pathfinding rebake functions mAudioStreamEnabled(FALSE), // Media/Stream separation mRebakeStuck(FALSE), // FIRE-7639 - Stop the blinking after a while mNearbyIcons(FALSE), // Script debug - mSearchData(NULL), // Hook up and init for filtering - mFilterEdit(NULL), // Edit for filtering - mSearchPanel(NULL), // Panel for filtering mIconPresets(NULL), mMediaToggle(NULL), mMouseEnterPresetsConnection(), @@ -411,6 +411,16 @@ BOOL LLStatusBar::postBuild() mPanelNearByMedia->setFollows(FOLLOWS_TOP|FOLLOWS_RIGHT); mPanelNearByMedia->setVisible(FALSE); + // Hook up and init for filtering + mFilterEdit = getChild( "search_menu_edit" ); + mSearchPanel = getChild( "menu_search_panel" ); + + mSearchPanel->setVisible(gSavedSettings.getBOOL("MenuSearch")); + mFilterEdit->setKeystrokeCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this)); + mFilterEdit->setCommitCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this)); + collectSearchableItems(); + gSavedSettings.getControl("MenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::updateMenuSearchVisibility, this, _2)); + // Script debug mScriptOut = getChild("scriptout"); mScriptOut->setMouseDownCallback(boost::bind(&LLFloaterScriptDebug::show, LLUUID::null)); @@ -436,8 +446,6 @@ BOOL LLStatusBar::postBuild() mBalancePanel = getChild("balance_bg"); mTimeMediaPanel = getChild("time_and_media_bg"); - mFilterEdit = getChild("search_menu_edit"); - mSearchPanel = getChild("menu_search_panel"); mFPSText = getChild("FPSText"); mVolumeIconsWidth = mBtnVolume->getRect().mRight - mStreamToggle->getRect().mLeft; @@ -469,14 +477,6 @@ BOOL LLStatusBar::postBuild() updateNetstatVisibility(LLSD(FALSE)); } - // Hook up and init for filtering - mSearchPanel->setVisible(gSavedSettings.getBOOL("FSMenuSearch")); - mFilterEdit->setKeystrokeCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this)); - mFilterEdit->setCommitCallback(boost::bind(&LLStatusBar::onUpdateFilterTerm, this)); - collectSearchableItems(); - gSavedSettings.getControl("FSMenuSearch")->getCommitSignal()->connect(boost::bind(&LLStatusBar::updateMenuSearchVisibility, this, _2)); - // - // FIRE-14482: Show FPS in status bar gSavedSettings.getControl("FSStatusBarShowFPS")->getSignal()->connect(boost::bind(&LLStatusBar::onShowFPSChanged, this, _2)); if (!gSavedSettings.getBOOL("FSStatusBarShowFPS")) @@ -663,6 +663,7 @@ void LLStatusBar::setVisibleForMouselook(bool visible) // mBtnVolume->setVisible(visible); // mStreamToggle->setVisible(visible); // ## Zi: Media/Stream separation // mMediaToggle->setVisible(visible); + mSearchPanel->setVisible(visible && gSavedSettings.getBOOL("MenuSearch")); BOOL FSEnableVolumeControls = gSavedSettings.getBOOL("FSEnableVolumeControls"); mBtnVolume->setVisible(visible && FSEnableVolumeControls); mStreamToggle->setVisible(visible && FSEnableVolumeControls); // ## Zi: Media/Stream separation @@ -672,7 +673,6 @@ void LLStatusBar::setVisibleForMouselook(bool visible) mSGBandwidth->setVisible(visible && showNetStats); mSGPacketLoss->setVisible(visible && showNetStats); mBandwidthButton->setVisible(visible && showNetStats); // FIRE-6287: Clicking on traffic indicator toggles Lag Meter window - mSearchPanel->setVisible(visible && gSavedSettings.getBOOL("FSMenuSearch")); mTimeMediaPanel->setVisible(visible); setBackgroundVisible(visible); mIconPresets->setVisible(visible); @@ -728,12 +728,11 @@ void LLStatusBar::setBalance(S32 balance) balance_bg_view->setShape(balance_bg_rect); } - // FS:ND> If the search panel is shown, move this according to the new balance width. Parcel text will reshape itself in setParcelInfoText + // If the search panel is shown, move this according to the new balance width. Parcel text will reshape itself in setParcelInfoText if (mSearchPanel && mSearchPanel->getVisible()) { updateMenuSearchPosition(); } - // if (mBalance && (fabs((F32)(mBalance - balance)) > gSavedSettings.getF32("UISndMoneyChangeThreshold"))) { @@ -1040,6 +1039,74 @@ void LLStatusBar::onVolumeChanged(const LLSD& newvalue) refresh(); } +void LLStatusBar::onUpdateFilterTerm() +{ + LLWString searchValue = utf8str_to_wstring( mFilterEdit->getValue() ); + LLWStringUtil::toLower( searchValue ); + + if( !mSearchData || mSearchData->mLastFilter == searchValue ) + return; + + mSearchData->mLastFilter = searchValue; + + mSearchData->mRootMenu->hightlightAndHide( searchValue ); + gMenuBarView->needsArrange(); +} + +void collectChildren( LLMenuGL *aMenu, ll::statusbar::SearchableItemPtr aParentMenu ) +{ + for( U32 i = 0; i < aMenu->getItemCount(); ++i ) + { + LLMenuItemGL *pMenu = aMenu->getItem( i ); + + ll::statusbar::SearchableItemPtr pItem( new ll::statusbar::SearchableItem ); + pItem->mCtrl = pMenu; + pItem->mMenu = pMenu; + pItem->mLabel = utf8str_to_wstring( pMenu->ll::ui::SearchableControl::getSearchText() ); + LLWStringUtil::toLower( pItem->mLabel ); + aParentMenu->mChildren.push_back( pItem ); + + LLMenuItemBranchGL *pBranch = dynamic_cast< LLMenuItemBranchGL* >( pMenu ); + if( pBranch ) + collectChildren( pBranch->getBranch(), pItem ); + } + +} + +void LLStatusBar::collectSearchableItems() +{ + mSearchData.reset( new ll::statusbar::SearchData ); + ll::statusbar::SearchableItemPtr pItem( new ll::statusbar::SearchableItem ); + mSearchData->mRootMenu = pItem; + collectChildren( gMenuBarView, pItem ); +} + +void LLStatusBar::updateMenuSearchVisibility(const LLSD& data) +{ + bool visible = data.asBoolean(); + mSearchPanel->setVisible(visible); + if (!visible) + { + mFilterEdit->setText(LLStringUtil::null); + onUpdateFilterTerm(); + } + else + { + updateMenuSearchPosition(); + } +} + +void LLStatusBar::updateMenuSearchPosition() +{ + const S32 HPAD = 12; + LLRect balanceRect = getChildView("balance_bg")->getRect(); + LLRect searchRect = mSearchPanel->getRect(); + S32 w = searchRect.getWidth(); + searchRect.mLeft = balanceRect.mLeft - w - HPAD; + searchRect.mRight = searchRect.mLeft + w; + mSearchPanel->setShape( searchRect ); +} + ////////////////////////////////////////////////////////////////////////////// // Firestorm methods @@ -1555,75 +1622,6 @@ void LLStatusBar::onMouseLeaveParcelInfo() mParcelInfoText->setColor(LLUIColorTable::instance().getColor("ParcelNormalColor")); } -void LLStatusBar::onUpdateFilterTerm() -{ - LLWString searchValue = utf8str_to_wstring( mFilterEdit->getValue() ); - LLWStringUtil::toLower( searchValue ); - - if( !mSearchData || mSearchData->mLastFilter == searchValue ) - return; - - mSearchData->mLastFilter = searchValue; - - mSearchData->mRootMenu->hightlightAndHide( searchValue ); - gMenuBarView->needsArrange(); -} - -void collectChildren( LLMenuGL *aMenu, nd::statusbar::SearchableItemPtr aParentMenu ) -{ - for( U32 i = 0; i < aMenu->getItemCount(); ++i ) - { - LLMenuItemGL *pMenu = aMenu->getItem( i ); - - nd::statusbar::SearchableItemPtr pItem( new nd::statusbar::SearchableItem ); - pItem->mCtrl = pMenu; - pItem->mMenu = pMenu; - pItem->mLabel = utf8str_to_wstring( pMenu->nd::ui::SearchableControl::getSearchText() ); - LLWStringUtil::toLower( pItem->mLabel ); - aParentMenu->mChildren.push_back( pItem ); - - LLMenuItemBranchGL *pBranch = dynamic_cast< LLMenuItemBranchGL* >( pMenu ); - if( pBranch ) - collectChildren( pBranch->getBranch(), pItem ); - } - -} - -void LLStatusBar::collectSearchableItems() -{ - mSearchData = new nd::statusbar::SearchData; - nd::statusbar::SearchableItemPtr pItem( new nd::statusbar::SearchableItem ); - mSearchData->mRootMenu = pItem; - collectChildren( gMenuBarView, pItem ); -} - -void LLStatusBar::updateMenuSearchVisibility(const LLSD& data) -{ - bool visible = data.asBoolean(); - mSearchPanel->setVisible(visible); - if (!visible) - { - mFilterEdit->setText(LLStringUtil::null); - onUpdateFilterTerm(); - } - else - { - updateMenuSearchPosition(); - } - update(); -} - -void LLStatusBar::updateMenuSearchPosition() -{ - const S32 HPAD = 12; - LLRect balanceRect = getChildView("balance_bg")->getRect(); - LLRect searchRect = mSearchPanel->getRect(); - S32 w = searchRect.getWidth(); - searchRect.mLeft = balanceRect.mLeft - w - HPAD; - searchRect.mRight = searchRect.mLeft + w; - mSearchPanel->setShape( searchRect ); -} - void LLStatusBar::onPopupRolloverChanged(const LLSD& newvalue) { bool new_value = newvalue.asBoolean(); diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h index 1e9247e09b..43d98c2989 100644 --- a/indra/newview/llstatusbar.h +++ b/indra/newview/llstatusbar.h @@ -31,15 +31,6 @@ // Pathfinding support #include "llpathfindingnavmesh.h" -#include "llsearcheditor.h" - -namespace nd -{ - namespace statusbar - { - struct SearchData; - } -} // "Constants" loaded from settings.xml at start time extern S32 STATUS_BAR_HEIGHT; @@ -57,6 +48,7 @@ class LLPanelPresetsPulldown; class LLPanelVolumePulldown; class LLPanelNearByMedia; class LLIconCtrl; +class LLSearchEditor; class LLParcelChangeObserver; class LLPanel; @@ -96,6 +88,13 @@ public: U32 mPing; }; +namespace ll +{ + namespace statusbar + { + struct SearchData; + } +} class LLStatusBar : public LLPanel { @@ -172,6 +171,15 @@ private: static void onClickVolume(void* data); // Open popup panels on click if FSStatusBarMenuButtonPopupOnRollover is disabled static void onClickBalance(void* data); + + LLSearchEditor *mFilterEdit; + LLPanel *mSearchPanel; + void onUpdateFilterTerm(); + + std::unique_ptr< ll::statusbar::SearchData > mSearchData; + void collectSearchableItems(); + void updateMenuSearchVisibility( const LLSD& data ); + void updateMenuSearchPosition(); class LLParcelChangeObserver; @@ -381,17 +389,6 @@ private: void onMouseLeaveParcelInfo(); // - // Seach in menu - LLSearchEditor *mFilterEdit; - LLPanel *mSearchPanel; - void onUpdateFilterTerm(); - - nd::statusbar::SearchData *mSearchData; - void collectSearchableItems(); - void updateMenuSearchVisibility(const LLSD& data); - void updateMenuSearchPosition(); - // - std::string mCurrentLocationString; }; diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 81d7b04454..2fc7a3e605 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -825,6 +825,10 @@ void LLTextureCacheWorker::endWork(S32 param, bool aborted) LLTextureCache::LLTextureCache(bool threaded) : LLWorkerThread("TextureCache", threaded), + mWorkersMutex(), + mHeaderMutex(), + mListMutex(), + mFastCacheMutex(), mHeaderAPRFile(NULL), mReadOnly(TRUE), //do not allow to change the texture cache until setReadOnly() is called. mTexturesSizeTotal(0), @@ -1035,11 +1039,11 @@ S64 LLTextureCache::initCache(ELLPath location, S64 max_size, BOOL texture_cache { llassert_always(getPending() == 0) ; //should not start accessing the texture cache before initialized. - S64 header_size = (max_size / 100) * 36; //0.36 * max_size - S64 max_entries = header_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE); + S64 entries_size = (max_size * 36) / 100; //0.36 * max_size + S64 max_entries = entries_size / (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE); sCacheMaxEntries = (S32)(llmin((S64)sCacheMaxEntries, max_entries)); - header_size = sCacheMaxEntries * TEXTURE_CACHE_ENTRY_SIZE; - max_size -= header_size; + entries_size = sCacheMaxEntries * (TEXTURE_CACHE_ENTRY_SIZE + TEXTURE_FAST_CACHE_ENTRY_SIZE); + max_size -= entries_size; if (sCacheMaxTexturesSize > 0) sCacheMaxTexturesSize = llmin(sCacheMaxTexturesSize, max_size); else diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 20f78c8b40..8713bbde65 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -141,7 +141,7 @@ LLFloaterTexturePicker::~LLFloaterTexturePicker() void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selection /*=true*/) { - if( mImageAssetID != image_id && mActive) + if( ((mImageAssetID != image_id) || mTentative) && mActive) { mNoCopyTextureSelected = FALSE; mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here? diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index d6d826f179..4f44ecd8ce 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -939,6 +939,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mCanUseHTTP(true), mRetryAttempt(0), mActiveCount(0), + mWorkMutex(), mFirstPacket(0), mLastPacket(-1), mTotalPackets(0), @@ -2578,6 +2579,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image mDebugPause(FALSE), mPacketCount(0), mBadPacketCount(0), + mQueueMutex(), + mNetworkQueueMutex(), mTextureCache(cache), mImageDecodeThread(imagedecodethread), mTextureBandwidth(0), diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index a2155bde1f..a01c01847e 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -35,7 +35,6 @@ #include "lluuid.h" #include "llworkerthread.h" #include "lltextureinfo.h" -#include "llapr.h" #include "llimageworker.h" #include "httprequest.h" #include "httpoptions.h" diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp index be746d60bf..ceb451ebfb 100644 --- a/indra/newview/lltoastgroupnotifypanel.cpp +++ b/indra/newview/lltoastgroupnotifypanel.cpp @@ -101,10 +101,9 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notifi // +LLTrans::getString("TimeMth")+"] [" // +LLTrans::getString("TimeDay")+"] [" // +LLTrans::getString("TimeYear")+"] [" - // +LLTrans::getString("TimeHour12")+"]:[" + // +LLTrans::getString("TimeHour")+"]:[" // +LLTrans::getString("TimeMin")+"]:[" // +LLTrans::getString("TimeSec")+"] [" - // +LLTrans::getString("TimeAMPM")+"] [" // +LLTrans::getString("TimeTimezone")+"]"; std::string timeStr = LLTrans::getString("GroupNoticesToastDateString"); // diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index cb4e84cb1b..5538dc5400 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -50,8 +50,6 @@ const S32 BOTTOM_PAD = VPAD * 3; const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding S32 BUTTON_WIDTH = 90; -// *TODO: magic numbers - copied from llnotify.cpp(250) -const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; //static @@ -326,7 +324,7 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) mTextBox = getChild("text_editor_box"); } - mTextBox->setMaxTextLength(MAX_LENGTH); + mTextBox->setMaxTextLength(LLToastPanel::MAX_TEXT_LENGTH); mTextBox->setVisible(TRUE); mTextBox->setPlainText(!show_images); mTextBox->setContentTrusted(is_content_trusted); @@ -437,16 +435,16 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images ) //can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'. mInfoPanel->setFollowsAll(); // FIRE-17100: Customizable number of rows in a script dialog - //snapToMessageHeight(mTextBox, MAX_LENGTH); + //snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH); if (mIsScriptDialog) { S32 rows = gSavedSettings.getS32("FSRowsPerScriptDialog"); - llclamp(rows, 2, MAX_LENGTH); + llclamp(rows, 2, LLToastPanel::MAX_TEXT_LENGTH); snapToMessageHeight(mTextBox, rows); } else { - snapToMessageHeight(mTextBox, MAX_LENGTH); + snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH); } // @@ -509,7 +507,7 @@ void LLIMToastNotifyPanel::snapToMessageHeight() //Add message height if it is visible if (mTextBox->getVisible()) { - S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, MAX_LENGTH); + S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH); //reshape the panel with new height if (new_panel_height != getRect().getHeight()) diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp index d832a7cff5..c96eb36320 100644 --- a/indra/newview/lltoastpanel.cpp +++ b/indra/newview/lltoastpanel.cpp @@ -26,6 +26,7 @@ #include "llviewerprecompiledheaders.h" +#include "lldbstrings.h" #include "llpanelgenerictip.h" #include "llpanelonlinestatus.h" #include "llnotifications.h" @@ -35,6 +36,8 @@ //static const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32) +// 'magic numbers', consider initializing (512+20) part from xml/notifications +const S32 LLToastPanel::MAX_TEXT_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; LLToastPanel::LLToastPanel(const LLNotificationPtr& notification) { diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h index 51630381f2..6a9b72a5ae 100644 --- a/indra/newview/lltoastpanel.h +++ b/indra/newview/lltoastpanel.h @@ -49,6 +49,7 @@ public: virtual const LLUUID& getID(); static const S32 MIN_PANEL_HEIGHT; + static const S32 MAX_TEXT_LENGTH; /** * Builder method for constructing notification specific panels. diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp index 518c6c0ee4..eb86a44055 100644 --- a/indra/newview/lltoastscripttextbox.cpp +++ b/indra/newview/lltoastscripttextbox.cpp @@ -36,8 +36,6 @@ #include "llviewertexteditor.h" const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT= 14; -// *TODO: magic numbers - copied from lltoastnotifypanel.cpp(50) which was copied from llnotify.cpp(250) -const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification) : LLToastPanel(notification) @@ -45,7 +43,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification buildFromFile( "panel_notify_textbox.xml"); mInfoText = getChild("text_editor_box"); - mInfoText->setMaxTextLength(MAX_LENGTH); + mInfoText->setMaxTextLength(LLToastPanel::MAX_TEXT_LENGTH); mInfoText->setValue(notification->getMessage()); getChild("ignore_btn")->setClickedCallback(boost::bind(&LLToastScriptTextbox::onClickIgnore, this)); diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp index da64fc844d..b5d78f3654 100644 --- a/indra/newview/lltool.cpp +++ b/indra/newview/lltool.cpp @@ -191,11 +191,9 @@ LLTool* LLTool::getOverrideTool(MASK mask) { return NULL; } - // Use faster LLCachedControls for frequently visited locations - //if (gSavedSettings.getBOOL("EnableAltZoom")) - static LLCachedControl enableAltZoom(gSavedSettings, "EnableAltZoom"); - if (enableAltZoom) - // + + static LLCachedControl alt_zoom(gSavedSettings, "EnableAltZoom", true); + if (alt_zoom) { if (mask & MASK_ALT) { diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index 22bd037b92..85cdffff26 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -120,12 +120,25 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask) mMouseOutsideSlop = FALSE; mMouseDownX = x; mMouseDownY = y; - LLTimer pick_timer; - BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); - //left mouse down always picks transparent (but see handleMouseUp) - mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged); - //LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL; // Clean up log spam left over from SL-713, MAINT-7709. + LLTimer pick_timer; + BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); + mPick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged); + LLViewerObject *object = mPick.getObject(); + LLViewerObject *parent = object ? object->getRootEdit() : NULL; + if (!object + || object->isAttachment() + || object->getClickAction() == CLICK_ACTION_DISABLED + || (!useClickAction(mask, object, parent) && !object->flagHandleTouch() && !(parent && parent->flagHandleTouch()))) + { + // Unless we are hovering over actionable visible object + // left mouse down always picks transparent (but see handleMouseUp). + // Also see LLToolPie::handleHover() - priorities are a bit different there. + // Todo: we need a more consistent set of rules to work with + mPick = gViewerWindow->pickImmediate(x, y, TRUE /*transparent*/, pick_rigged); + } + //LL_INFOS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL; // Clean up log spam left over from SL-713, MAINT-7709. LL_DEBUGS() << "pick_rigged is " << (S32) pick_rigged << " pick time elapsed " << pick_timer.getElapsedTimeF32() << LL_ENDL; + mPick.mKeyMask = mask; mMouseButtonDown = true; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index a7edaa8cad..b52b8a5733 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -291,7 +291,7 @@ static bool handleAnisotropicChanged(const LLSD& newvalue) static bool handleVolumeLODChanged(const LLSD& newvalue) { - LLVOVolume::sLODFactor = (F32) newvalue.asReal(); + LLVOVolume::sLODFactor = llclamp((F32) newvalue.asReal(), 0.01f, MAX_LOD_FACTOR); LLVOVolume::sDistanceFactor = 1.f-LLVOVolume::sLODFactor * 0.1f; // Warning about too high LOD on LOD change @@ -306,13 +306,13 @@ static bool handleVolumeLODChanged(const LLSD& newvalue) static bool handleAvatarLODChanged(const LLSD& newvalue) { - LLVOAvatar::sLODFactor = (F32) newvalue.asReal(); + LLVOAvatar::sLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR); return true; } static bool handleAvatarPhysicsLODChanged(const LLSD& newvalue) { - LLVOAvatar::sPhysicsLODFactor = (F32) newvalue.asReal(); + LLVOAvatar::sPhysicsLODFactor = llclamp((F32) newvalue.asReal(), 0.f, MAX_AVATAR_LOD_FACTOR); return true; } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 0ccd89080b..a5b7e41c3e 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -89,6 +89,7 @@ #include "llfloatermediasettings.h" #include "llfloatermemleak.h" #include "llfloatermodelpreview.h" +#include "llfloatermyscripts.h" #include "llfloatermyenvironment.h" #include "llfloaternamedesc.h" #include "llfloaternotificationsconsole.h" @@ -413,6 +414,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("script_debug_output", "floater_script_debug_panel.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("script_floater", "floater_script.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("script_limits", "floater_script_limits.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("my_scripts", "floater_my_scripts.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater); LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("sound_devices", "floater_sound_devices.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index 38e60dc567..bbf957db64 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -686,23 +686,19 @@ void LLViewerMedia::updateMedia(void *dummy_arg) std::vector proximity_order; + static LLCachedControl inworld_media_enabled(gSavedSettings, "AudioStreamingMedia", true); + static LLCachedControl inworld_audio_enabled(gSavedSettings, "AudioStreamingMusic", true); // Replace frequently called gSavedSettings - //bool inworld_media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia"); - //bool inworld_audio_enabled = gSavedSettings.getBOOL("AudioStreamingMusic"); //U32 max_instances = gSavedSettings.getU32("PluginInstancesTotal"); //U32 max_normal = gSavedSettings.getU32("PluginInstancesNormal"); //U32 max_low = gSavedSettings.getU32("PluginInstancesLow"); //F32 max_cpu = gSavedSettings.getF32("PluginInstancesCPULimit"); - static LLCachedControl sAudioStreamingMedia(gSavedSettings, "AudioStreamingMedia"); - static LLCachedControl sAudioStreamingMusic(gSavedSettings, "AudioStreamingMusic"); static LLCachedControl sPluginInstancesTotal(gSavedSettings, "PluginInstancesTotal"); static LLCachedControl sPluginInstancesNormal(gSavedSettings, "PluginInstancesNormal"); static LLCachedControl sPluginInstancesLow(gSavedSettings, "PluginInstancesLow"); static LLCachedControl sPluginInstancesCPULimit(gSavedSettings, "PluginInstancesCPULimit"); - bool inworld_media_enabled = sAudioStreamingMedia; - bool inworld_audio_enabled = sAudioStreamingMusic; U32 max_instances = sPluginInstancesTotal(); U32 max_normal = sPluginInstancesNormal(); U32 max_low = sPluginInstancesLow(); @@ -968,7 +964,8 @@ void LLViewerMedia::setAllMediaEnabled(bool val) LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); } -// if (gSavedSettings.getBOOL("AudioStreamingMusic") && +// static LLCachedControl audio_streaming_music(gSavedSettings, "AudioStreamingMusic", true); +// if (audio_streaming_music && // !LLViewerMedia::isParcelAudioPlaying() && // gAudiop && // LLViewerMedia::hasParcelAudio()) @@ -1040,7 +1037,8 @@ void LLViewerMedia::setAllMediaPaused(bool val) LLViewerParcelMedia::play(LLViewerParcelMgr::getInstance()->getAgentParcel()); } - if (gSavedSettings.getBOOL("AudioStreamingMusic") && + static LLCachedControl audio_streaming_music(gSavedSettings, "AudioStreamingMusic", true); + if (audio_streaming_music && !LLViewerMedia::isParcelAudioPlaying() && gAudiop && LLViewerMedia::hasParcelAudio()) @@ -3384,8 +3382,39 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla } else { - // Don't track redirects. - setNavState(MEDIANAVSTATE_NONE); + bool internal_nav = false; + if (url != mCurrentMediaURL) + { + // Check if it is internal navigation + // Note: Not sure if we should detect internal navigations as 'address change', + // but they are not redirects and do not cause NAVIGATE_BEGIN (also see SL-1005) + size_t pos = url.find("#"); + if (pos != std::string::npos) + { + // assume that new link always have '#', so this is either + // transfer from 'link#1' to 'link#2' or from link to 'link#2' + // filter out cases like 'redirect?link' + std::string base_url = url.substr(0, pos); + pos = mCurrentMediaURL.find(base_url); + if (pos == 0) + { + // base link hasn't changed + internal_nav = true; + } + } + } + + if (internal_nav) + { + // Internal navigation by '#' + mCurrentMediaURL = url; + setNavState(MEDIANAVSTATE_FIRST_LOCATION_CHANGED); + } + else + { + // Don't track redirects. + setNavState(MEDIANAVSTATE_NONE); + } } } break; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 7b5fd84f3c..fbfbe210e8 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -8772,8 +8772,11 @@ BOOL object_selected_and_point_valid(const LLSD& sdParam) /* BOOL object_is_wearable() { -// if (!object_selected_and_point_valid()) - if (!object_selected_and_point_valid(LLSD(0))) + if (!isAgentAvatarValid()) + { + return FALSE; + } + if (!object_selected_and_point_valid()) { return FALSE; } @@ -8781,17 +8784,7 @@ BOOL object_is_wearable() { return FALSE; } - LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection(); - for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin(); - iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++) - { - LLSelectNode* node = *iter; - if (node->mPermissions->getOwner() == gAgent.getID()) - { - return TRUE; - } - } - return FALSE; + return gAgentAvatarp->canAttachMoreObjects(); } */ // [/RLVa:KB] @@ -11724,7 +11717,7 @@ void initialize_menus() enable.add("Object.EnableOpen", boost::bind(&enable_object_open)); enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1)); enable.add("Object.EnableDelete", boost::bind(&enable_object_delete)); -// enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid)); +// enable.add("Object.EnableWear", boost::bind(&object_is_wearable)); // [RLVa:KB] - Checked: 2010-03-16 (RLVa-1.2.0a) | Added: RLVa-1.2.0a enable.add("Object.EnableWear", boost::bind(&object_selected_and_point_valid, _2)); // [/RLVa:KB] diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index ca57d1b43b..12b77e20a6 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -6975,17 +6975,6 @@ void notify_cautioned_script_question(const LLSD& notification, const LLSD& resp void script_question_mute(const LLUUID& item_id, const std::string& object_name); -bool unknown_script_question_cb(const LLSD& notification, const LLSD& response) -{ - // Only care if they muted the object here. - if ( response["Mute"] ) // mute - { - LLUUID task_id = notification["payload"]["task_id"].asUUID(); - script_question_mute(task_id,notification["payload"]["object_name"].asString()); - } - return false; -} - void experiencePermissionBlock(LLUUID experience, LLSD result) { LLSD permission; @@ -7101,8 +7090,7 @@ void script_question_mute(const LLUUID& task_id, const std::string& object_name) bool matches(const LLNotificationPtr notification) const { if (notification->getName() == "ScriptQuestionCaution" - || notification->getName() == "ScriptQuestion" - || notification->getName() == "UnknownScriptQuestion") + || notification->getName() == "ScriptQuestion") { return (notification->getPayload()["task_id"].asUUID() == blocked_id); } @@ -7119,7 +7107,6 @@ void script_question_mute(const LLUUID& task_id, const std::string& object_name) static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb); static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb); static LLNotificationFunctorRegistration script_question_cb_reg_3("ScriptQuestionExperience", script_question_cb); -static LLNotificationFunctorRegistration unknown_script_question_cb_reg("UnknownScriptQuestion", unknown_script_question_cb); void process_script_experience_details(const LLSD& experience_details, LLSD args, LLSD payload) { @@ -7226,27 +7213,28 @@ void process_script_question(LLMessageSystem *msg, void **user_data) // check whether permission question should cause special caution dialog caution |= (script_perm.caution); - if ((("ScriptTakeMoney" == script_perm.question) && has_not_only_debit) || - (script_perm.question == "JoinAnExperience")) + if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit) continue; + if (script_perm.question == "JoinAnExperience") + { // Some experience only permissions do not have an explicit permission bit. Add them here. + script_question += " " + LLTrans::getString("ForceSitAvatar") + "\n"; + } + script_question += " " + LLTrans::getString(script_perm.question) + "\n"; } } - script_question += "\n"; args["QUESTIONS"] = script_question; if (known_questions != questions) - { // This is in addition to the normal dialog. - LLSD payload; - payload["task_id"] = taskid; - payload["item_id"] = itemid; - payload["object_name"] = object_name; - - args["DOWNLOADURL"] = LLTrans::getString("ViewerDownloadURL"); - LLNotificationsUtil::add("UnknownScriptQuestion",args,payload); + { + // This is in addition to the normal dialog. + // Viewer got a request for not supported/implemented permission + LL_WARNS("Messaging") << "Object \"" << object_name << "\" requested " << script_question + << " permission. Permission is unknown and can't be granted. Item id: " << itemid + << " taskid:" << taskid << LL_ENDL; make_ui_sound("UISndScriptFloaterOpen"); // FIRE-16958: Incoming script permission request doesn't trigger a sound } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 39098d4385..d6bac141ac 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -139,6 +139,7 @@ BOOL LLViewerObject::sUseSharedDrawables(FALSE); // TRUE // sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime F64Seconds LLViewerObject::sMaxUpdateInterpolationTime(3.0); // For motion interpolation: after X seconds with no updates, don't predict object motion F64Seconds LLViewerObject::sPhaseOutUpdateInterpolationTime(2.0); // For motion interpolation: after Y seconds with no updates, taper off motion prediction +F64Seconds LLViewerObject::sMaxRegionCrossingInterpolationTime(1.0);// For motion interpolation: don't interpolate over this time on region crossing std::map LLViewerObject::sObjectDataMap; @@ -278,6 +279,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mLastInterpUpdateSecs(0.f), mLastMessageUpdateSecs(0.f), mLatestRecvPacketID(0), + mRegionCrossExpire(0), mData(NULL), mAudioSourcep(NULL), mAudioGain(1.f), @@ -2551,7 +2553,7 @@ void LLViewerObject::loadFlags(U32 flags) return; } -void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time) +void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &frame_time) { //static LLTrace::BlockTimerStatHandle ftm("Viewer Object"); //LL_RECORD_BLOCK_TIME(ftm); @@ -2562,19 +2564,19 @@ void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time) { // calculate dt from last update F32 time_dilation = mRegionp ? mRegionp->getTimeDilation() : 1.0f; - F32 dt_raw = ((F64Seconds)time - mLastInterpUpdateSecs).value(); + F32 dt_raw = ((F64Seconds)frame_time - mLastInterpUpdateSecs).value(); F32 dt = time_dilation * dt_raw; applyAngularVelocity(dt); if (isAttachment()) { - mLastInterpUpdateSecs = (F64Seconds)time; + mLastInterpUpdateSecs = (F64Seconds)frame_time; return; } else { // Move object based on it's velocity and rotation - interpolateLinearMotion(time, dt); + interpolateLinearMotion(frame_time, dt); } } @@ -2584,7 +2586,7 @@ void LLViewerObject::idleUpdate(LLAgent &agent, const F64 &time) // Move an object due to idle-time viewer side updates by interpolating motion -void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, const F32SecondsImplicit& dt_seconds) +void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& frame_time, const F32SecondsImplicit& dt_seconds) { // linear motion // PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object @@ -2596,7 +2598,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con // zeroing it out F32 dt = dt_seconds; - F64Seconds time_since_last_update = time - mLastMessageUpdateSecs; + F64Seconds time_since_last_update = frame_time - mLastMessageUpdateSecs; if (time_since_last_update <= (F64Seconds)0.0 || dt <= 0.f) { return; @@ -2644,7 +2646,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con (time_since_last_packet > sPhaseOutUpdateInterpolationTime)) { // Start to reduce motion interpolation since we haven't seen a server update in a while - F64Seconds time_since_last_interpolation = time - mLastInterpUpdateSecs; + F64Seconds time_since_last_interpolation = frame_time - mLastInterpUpdateSecs; F64 phase_out = 1.0; if (time_since_last_update > sMaxUpdateInterpolationTime) { // Past the time limit, so stop the object @@ -2703,7 +2705,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]); // Check to see if it's going off the region - LLVector3 temp(new_pos); + LLVector3 temp(new_pos.mV[VX], new_pos.mV[VY], 0.f); if (temp.clamp(0.f, mRegionp->getWidth())) { // Going off this region, so see if we might end up on another region LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion()); @@ -2738,21 +2740,47 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con // Clip the positions to known regions LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global); if (clip_pos_global != new_pos_global) - { // Was clipped, so this means we hit a edge where there is no region to enter - - //LL_INFOS() << "Hit empty region edge, clipped predicted position to " << mRegionp->getPosRegionFromGlobal(clip_pos_global) - // << " from " << new_pos << LL_ENDL; - new_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global); + { + // Was clipped, so this means we hit a edge where there is no region to enter + LLVector3 clip_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global); + LL_DEBUGS("Interpolate") << "Hit empty region edge, clipped predicted position to " + << clip_pos + << " from " << new_pos << LL_ENDL; + new_pos = clip_pos; // Stop motion and get server update for bouncing on the edge new_v.clear(); setAcceleration(LLVector3::zero); } else - { // Let predicted movement cross into another region - //LL_INFOS() << "Predicting region crossing to " << new_pos << LL_ENDL; + { + // Check for how long we are crossing. + // Note: theoretically we can find time from velocity, acceleration and + // distance from border to new position, but it is not going to work + // if 'phase_out' activates + if (mRegionCrossExpire == 0) + { + // Workaround: we can't accurately figure out time when we cross border + // so just write down time 'after the fact', it is far from optimal in + // case of lags, but for lags sMaxUpdateInterpolationTime will kick in first + LL_DEBUGS("Interpolate") << "Predicted region crossing, new position " << new_pos << LL_ENDL; + mRegionCrossExpire = frame_time + sMaxRegionCrossingInterpolationTime; + } + else if (frame_time > mRegionCrossExpire) + { + // Predicting crossing over 1s, stop motion + // Stop motion + LL_DEBUGS("Interpolate") << "Predicting region crossing for too long, stopping at " << new_pos << LL_ENDL; + new_v.clear(); + setAcceleration(LLVector3::zero); + mRegionCrossExpire = 0; + } } } + else + { + mRegionCrossExpire = 0; + } // Set new position and velocity setPositionRegion(new_pos); @@ -2763,7 +2791,7 @@ void LLViewerObject::interpolateLinearMotion(const F64SecondsImplicit& time, con } // Update the last time we did anything - mLastInterpUpdateSecs = time; + mLastInterpUpdateSecs = frame_time; } diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 1160158d6c..40dc7b2297 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -629,7 +629,7 @@ private: U32 checkMediaURL(const std::string &media_url); // Motion prediction between updates - void interpolateLinearMotion(const F64SecondsImplicit & time, const F32SecondsImplicit & dt); + void interpolateLinearMotion(const F64SecondsImplicit & frame_time, const F32SecondsImplicit & dt); static void initObjectDataMap(); @@ -789,6 +789,7 @@ protected: F64Seconds mLastInterpUpdateSecs; // Last update for purposes of interpolation F64Seconds mLastMessageUpdateSecs; // Last update from a message from the simulator TPACKETID mLatestRecvPacketID; // Latest time stamp on message from simulator + F64SecondsImplicit mRegionCrossExpire; // frame time we detected region crossing in + wait time // extra data sent from the sim...currently only used for tree species info U8* mData; @@ -868,6 +869,7 @@ protected: static void setPhaseOutUpdateInterpolationTime(F32 value) { sPhaseOutUpdateInterpolationTime = (F64Seconds) value; } static void setMaxUpdateInterpolationTime(F32 value) { sMaxUpdateInterpolationTime = (F64Seconds) value; } + static void setMaxRegionCrossingInterpolationTime(F32 value) { sMaxRegionCrossingInterpolationTime = (F64Seconds) value; } static void setVelocityInterpolate(BOOL value) { sVelocityInterpolate = value; } static void setPingInterpolate(BOOL value) { sPingInterpolate = value; } @@ -877,6 +879,7 @@ private: static F64Seconds sPhaseOutUpdateInterpolationTime; // For motion interpolation static F64Seconds sMaxUpdateInterpolationTime; // For motion interpolation + static F64Seconds sMaxRegionCrossingInterpolationTime; // For motion interpolation static BOOL sVelocityInterpolate; static BOOL sPingInterpolate; diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index fc16390586..7c4e2d062f 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -940,6 +940,7 @@ void LLViewerObjectList::update(LLAgent &agent) static LLCachedControl pingInterpolate(gSavedSettings, "PingInterpolate"); static LLCachedControl interpolationTime(gSavedSettings, "InterpolationTime"); static LLCachedControl interpolationPhaseOut(gSavedSettings, "InterpolationPhaseOut"); + static LLCachedControl regionCrossingInterpolationTime(gSavedSettings, "RegionCrossingInterpolationTime"); static LLCachedControl animateTextures(gSavedSettings, "AnimateTextures"); static LLCachedControl freezeTime(gSavedSettings, "FreezeTime"); // Speed up debug settings @@ -951,11 +952,13 @@ void LLViewerObjectList::update(LLAgent &agent) // //F32 interp_time = gSavedSettings.getF32("InterpolationTime"); //F32 phase_out_time = gSavedSettings.getF32("InterpolationPhaseOut"); + //F32 region_interp_time = llclamp(gSavedSettings.getF32("RegionCrossingInterpolationTime"), 0.5f, 5.f); LLViewerObject::setVelocityInterpolate(velocityInterpolate); LLViewerObject::setPingInterpolate(pingInterpolate); F32 interp_time = (F32)interpolationTime; F32 phase_out_time = (F32)interpolationPhaseOut; + F32 region_interp_time = llclamp(regionCrossingInterpolationTime(), 0.5f, 5.f); // Speed up debug settings if (interp_time < 0.0 || phase_out_time < 0.0 || @@ -967,6 +970,7 @@ void LLViewerObjectList::update(LLAgent &agent) } LLViewerObject::setPhaseOutUpdateInterpolationTime( interp_time ); LLViewerObject::setMaxUpdateInterpolationTime( phase_out_time ); + LLViewerObject::setMaxRegionCrossingInterpolationTime(region_interp_time); // Speed up debug settings //gAnimateTextures = gSavedSettings.getBOOL("AnimateTextures"); diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index aa33010285..2701ccbe03 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1039,7 +1039,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id) return; } - LL_INFOS() << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL; + LL_INFOS("ParcelMgr") << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL; // BUG: Only works for the region containing mWestSouthBottom LLVector3d east_north_region_check( mEastNorth ); @@ -1062,7 +1062,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id) return; } - LL_INFOS() << "Region " << region->getOriginGlobal() << LL_ENDL; + LL_INFOS("ParcelMgr") << "Region " << region->getOriginGlobal() << LL_ENDL; LLSD payload; payload["owner_id"] = owner_id; @@ -1202,8 +1202,8 @@ LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy( if (is_claim) { - LL_INFOS() << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL; - LL_INFOS() << "Region " << region->getOriginGlobal() << LL_ENDL; + LL_INFOS("ParcelMgr") << "Claiming " << mWestSouth << " to " << mEastNorth << LL_ENDL; + LL_INFOS("ParcelMgr") << "Region " << region->getOriginGlobal() << LL_ENDL; // BUG: Only works for the region containing mWestSouthBottom LLVector3d east_north_region_check( mEastNorth ); @@ -1383,8 +1383,6 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag if (!region) return; - //LL_INFOS() << "found region: " << region->getName() << LL_ENDL; - LLSD body; std::string url = region->getCapability("ParcelPropertiesUpdate"); if (!url.empty()) @@ -1393,7 +1391,7 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag U32 message_flags = 0x01; body["flags"] = ll_sd_from_U32(message_flags); parcel->packMessage(body); - LL_INFOS() << "Sending parcel properties update via capability to: " + LL_INFOS("ParcelMgr") << "Sending parcel properties update via capability to: " << url << LL_ENDL; LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, body, @@ -1422,22 +1420,18 @@ void LLViewerParcelMgr::sendParcelPropertiesUpdate(LLParcel* parcel, bool use_ag void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos) { static U32 last_west, last_south; - + static LLUUID last_region; // only request parcel info if position has changed outside of the // last parcel grid step - U32 west_parcel_step = (U32) floor( pos.mdV[VX] / PARCEL_GRID_STEP_METERS ); - U32 south_parcel_step = (U32) floor( pos.mdV[VY] / PARCEL_GRID_STEP_METERS ); - + const U32 west_parcel_step = (U32) floor( pos.mdV[VX] / PARCEL_GRID_STEP_METERS ); + const U32 south_parcel_step = (U32) floor( pos.mdV[VY] / PARCEL_GRID_STEP_METERS ); + if ((west_parcel_step == last_west) && (south_parcel_step == last_south)) { + // We are staying in same segment return; } - else - { - last_west = west_parcel_step; - last_south = south_parcel_step; - } LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( pos ); if (!region) @@ -1445,34 +1439,95 @@ void LLViewerParcelMgr::setHoverParcel(const LLVector3d& pos) return; } + LLUUID region_id = region->getRegionID(); + LLVector3 pos_in_region = region->getPosRegionFromGlobal(pos); - // Send a rectangle around the point. - // This means the parcel sent back is at least a rectangle around the point, - // which is more efficient for public land. Fewer requests are sent. JC - LLVector3 wsb_region = region->getPosRegionFromGlobal( pos ); + bool request_properties = false; + if (region_id != last_region) + { + request_properties = true; + } + else + { + // Check if new position is in same parcel. + // This check is not ideal, since it checks by way of straight lines. + // So sometimes (small parcel in the middle of large one) it can + // decide that parcel actually changed, but it still allows to + // reduce amount of requests significantly - F32 west = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VX] / PARCEL_GRID_STEP_METERS ); - F32 south = PARCEL_GRID_STEP_METERS * floor( wsb_region.mV[VY] / PARCEL_GRID_STEP_METERS ); + S32 west_parcel_local = (S32)(pos_in_region.mV[VX] / PARCEL_GRID_STEP_METERS); + S32 south_parcel_local = (S32)(pos_in_region.mV[VY] / PARCEL_GRID_STEP_METERS); - F32 east = west + PARCEL_GRID_STEP_METERS; - F32 north = south + PARCEL_GRID_STEP_METERS; + LLViewerParcelOverlay* overlay = region->getParcelOverlay(); + if (!overlay) + { + request_properties = true; + } + while (!request_properties && west_parcel_step < last_west) + { + S32 segment_shift = last_west - west_parcel_step; + request_properties = overlay->parcelLineFlags(south_parcel_local, west_parcel_local + segment_shift) & PARCEL_WEST_LINE; + last_west--; + } + while (!request_properties && south_parcel_step < last_south) + { + S32 segment_shift = last_south - south_parcel_step; + request_properties = overlay->parcelLineFlags(south_parcel_local + segment_shift, west_parcel_local) & PARCEL_SOUTH_LINE; + last_south--; + } + // Note: could have just swapped values, reused first two 'while' and set last_south, last_west separately, + // but this looks to be easier to understand/straightforward/less bulky + while (!request_properties && west_parcel_step > last_west) + { + S32 segment_shift = west_parcel_step - last_west; + request_properties = overlay->parcelLineFlags(south_parcel_local, west_parcel_local - segment_shift + 1) & PARCEL_WEST_LINE; + last_west++; + } + while (!request_properties && south_parcel_step > last_south) + { + S32 segment_shift = south_parcel_step - last_south; + request_properties = overlay->parcelLineFlags(south_parcel_local - segment_shift + 1, west_parcel_local) & PARCEL_SOUTH_LINE; + last_south++; + } - // Send request message - LLMessageSystem *msg = gMessageSystem; - msg->newMessageFast(_PREHASH_ParcelPropertiesRequest); - msg->nextBlockFast(_PREHASH_AgentData); - msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); - msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID() ); - msg->nextBlockFast(_PREHASH_ParcelData); - msg->addS32Fast(_PREHASH_SequenceID, HOVERED_PARCEL_SEQ_ID ); - msg->addF32Fast(_PREHASH_West, west ); - msg->addF32Fast(_PREHASH_South, south ); - msg->addF32Fast(_PREHASH_East, east ); - msg->addF32Fast(_PREHASH_North, north ); - msg->addBOOL("SnapSelection", FALSE ); - msg->sendReliable( region->getHost() ); + // if (!request_properties) last_south and last_west will be equal to new values + } - mHoverRequestResult = PARCEL_RESULT_NO_DATA; + if (request_properties) + { + last_west = west_parcel_step; + last_south = south_parcel_step; + last_region = region_id; + + LL_DEBUGS("ParcelMgr") << "Requesting parcel properties on hover, for " << pos << LL_ENDL; + + + // Send a rectangle around the point. + // This means the parcel sent back is at least a rectangle around the point, + // which is more efficient for public land. Fewer requests are sent. JC + F32 west = PARCEL_GRID_STEP_METERS * floor(pos_in_region.mV[VX] / PARCEL_GRID_STEP_METERS); + F32 south = PARCEL_GRID_STEP_METERS * floor(pos_in_region.mV[VY] / PARCEL_GRID_STEP_METERS); + + F32 east = west + PARCEL_GRID_STEP_METERS; + F32 north = south + PARCEL_GRID_STEP_METERS; + + // Send request message + LLMessageSystem *msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ParcelPropertiesRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ParcelData); + msg->addS32Fast(_PREHASH_SequenceID, HOVERED_PARCEL_SEQ_ID); + msg->addF32Fast(_PREHASH_West, west); + msg->addF32Fast(_PREHASH_South, south); + msg->addF32Fast(_PREHASH_East, east); + msg->addF32Fast(_PREHASH_North, north); + msg->addBOOL("SnapSelection", FALSE); + msg->sendReliable(region->getHost()); + + mHoverRequestResult = PARCEL_RESULT_NO_DATA; + } } @@ -1581,7 +1636,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use if (request_result == PARCEL_RESULT_NO_DATA) { // no valid parcel data - LL_INFOS() << "no valid parcel data" << LL_ENDL; + LL_INFOS("ParcelMgr") << "no valid parcel data" << LL_ENDL; return; } @@ -1613,7 +1668,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - LL_INFOS() << "out of order agent parcel sequence id " << sequence_id + LL_INFOS("ParcelMgr") << "out of order agent parcel sequence id " << sequence_id << " last good " << parcel_mgr.mAgentParcelSequenceID << LL_ENDL; return; @@ -1667,6 +1722,8 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use msg->getS32("ParcelData", "OtherCleanTime", other_clean_time ); + LL_DEBUGS("ParcelMgr") << "Processing parcel " << local_id << " update, target(sequence): " << sequence_id << LL_ENDL; + // Actually extract the data. if (parcel) { @@ -1931,7 +1988,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else { - LL_INFOS() << "Stopping parcel music (invalid audio stream URL)" << LL_ENDL; + LL_INFOS("ParcelMgr") << "Stopping parcel music (invalid audio stream URL)" << LL_ENDL; // clears the URL // null value causes fade out LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); @@ -1939,7 +1996,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use } else if (!gAudiop->getInternetStreamURL().empty()) { - LL_INFOS() << "Stopping parcel music (parcel stream URL is empty)" << LL_ENDL; + LL_INFOS("ParcelMgr") << "Stopping parcel music (parcel stream URL is empty)" << LL_ENDL; // null value causes fade out LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(LLStringUtil::null); } @@ -1980,7 +2037,7 @@ void LLViewerParcelMgr::optionally_start_music(const std::string& music_url) } else { - LL_INFOS() << "Starting parcel music " << music_url << LL_ENDL; + LL_INFOS("ParcelMgr") << "Starting parcel music " << music_url << LL_ENDL; LLViewerAudio::getInstance()->startInternetStreamWithAutoFade(music_url); } } @@ -2009,7 +2066,7 @@ void LLViewerParcelMgr::processParcelAccessListReply(LLMessageSystem *msg, void if (parcel_id != parcel->getLocalID()) { - LL_WARNS_ONCE("") << "processParcelAccessListReply for parcel " << parcel_id + LL_WARNS_ONCE("ParcelMgr") << "processParcelAccessListReply for parcel " << parcel_id << " which isn't the selected parcel " << parcel->getLocalID()<< LL_ENDL; return; } diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 6da85b5e96..da4ed99688 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -281,6 +281,23 @@ U8 LLViewerParcelOverlay::ownership( const LLVector3& pos) const return ownership(row, column); } +U8 LLViewerParcelOverlay::parcelLineFlags(const LLVector3& pos) const +{ + S32 row = S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS); + S32 column = S32(pos.mV[VX] / PARCEL_GRID_STEP_METERS); + return parcelLineFlags(row, column); +} +U8 LLViewerParcelOverlay::parcelLineFlags(S32 row, S32 col) const +{ + U8 flags = PARCEL_WEST_LINE | PARCEL_SOUTH_LINE; + if (row > mParcelGridsPerEdge || col > mParcelGridsPerEdge) + { + LL_WARNS() << "Attempted to get ownership out of region's overlay, row: " << row << " col: " << col << LL_ENDL; + return flags; + } + return mOwnership[row * mParcelGridsPerEdge + col] & flags; +} + F32 LLViewerParcelOverlay::getOwnedRatio() const { S32 size = mParcelGridsPerEdge * mParcelGridsPerEdge; diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h index 542e413b9d..2132ea6318 100644 --- a/indra/newview/llviewerparceloverlay.h +++ b/indra/newview/llviewerparceloverlay.h @@ -74,6 +74,8 @@ public: S32 renderPropertyLines(); U8 ownership( const LLVector3& pos) const; + U8 parcelLineFlags( const LLVector3& pos) const; + U8 parcelLineFlags(S32 row, S32 col) const; // MANIPULATE void uncompressLandOverlay(S32 chunk, U8 *compressed_overlay); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 1128eb429f..3886ecfa89 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -400,7 +400,8 @@ void LLViewerShaderMgr::setShaders() return; } - LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")), 1); + static LLCachedControl max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16); + LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) max_texture_index), 1); //NEVER use more than 16 texture channels (work around for prevalent driver bug) LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16); diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 70022e5594..1ea1ae834b 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -115,7 +115,7 @@ const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128; const S32 DEFAULT_ICON_DIMENTIONS = 32; U32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256. U32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA; -BOOL LLViewerTexture::sFreezeImageScalingDown = FALSE; +bool LLViewerTexture::sFreezeImageUpdates = false; F32 LLViewerTexture::sCurrentTime = 0.0f; F32 LLViewerTexture::sTexelPixelRatio = 1.0f; @@ -504,6 +504,7 @@ void LLViewerTexture::initClass() // tuning params const F32 discard_bias_delta = .25f; const F32 discard_delta_time = 0.5f; +const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f; // non-const (used externally F32 texmem_lower_bound_scale = 0.85f; F32 texmem_middle_bound_scale = 0.925f; @@ -513,60 +514,74 @@ static LLTrace::BlockTimerStatHandle FTM_TEXTURE_MEMORY_CHECK("Memory Check"); //static bool LLViewerTexture::isMemoryForTextureLow() { - const F32 WAIT_TIME = 1.0f; //second - static LLFrameTimer timer; + // Disable memory checking on request + static LLCachedControl FSDisableMemCheck(gSavedSettings, "FSDisableAMDTextureMemoryCheck"); + if (FSDisableMemCheck) + return false; + // - // Disable memory checking on request - static LLCachedControl FSDisableMemCheck(gSavedSettings, "FSDisableAMDTextureMemoryCheck"); + // Note: we need to figure out a better source for 'min' values, + // what is free for low end at minimal settings is 'nothing left' + // for higher end gpus at high settings. + const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20); + const S32Megabytes MIN_FREE_MAIN_MEMORY(100); - if( FSDisableMemCheck ) - return false; - // + S32Megabytes gpu; + S32Megabytes physical; + getGPUMemoryForTextures(gpu, physical); - if(timer.getElapsedTimeF32() < WAIT_TIME) //call this once per second. - { - return false; - } - timer.reset(); + return (gpu < MIN_FREE_TEXTURE_MEMORY) || (physical < MIN_FREE_MAIN_MEMORY); +} - LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK); +//static +bool LLViewerTexture::isMemoryForTextureSuficientlyFree() +{ + const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50); + const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200); - const S32Megabytes MIN_FREE_TEXTURE_MEMORY(20); //MB Changed to 20 MB per MAINT-6882 - const S32Megabytes MIN_FREE_MAIN_MEMORY(100); //MB + S32Megabytes gpu; + S32Megabytes physical; + getGPUMemoryForTextures(gpu, physical); - bool low_mem = false; - if (gGLManager.mHasATIMemInfo) - { - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); + return (gpu > DESIRED_FREE_TEXTURE_MEMORY) && (physical > DESIRED_FREE_MAIN_MEMORY); +} - if((S32Megabytes)meminfo[0] < MIN_FREE_TEXTURE_MEMORY) - { - low_mem = true; - } +//static +void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical) +{ + static LLFrameTimer timer; + static S32Megabytes gpu_res = S32Megabytes(S32_MAX); + static S32Megabytes physical_res = S32Megabytes(S32_MAX); - if(!low_mem) //check main memory, only works for windows. - { - LLMemory::updateMemoryInfo(); - if(LLMemory::getAvailableMemKB() < MIN_FREE_TEXTURE_MEMORY) - { - low_mem = true; - } - } - } - //Enabled this branch per MAINT-6882 - else if (gGLManager.mHasNVXMemInfo) - { - S32 free_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); - - if ((S32Megabytes)(free_memory / 1024) < MIN_FREE_TEXTURE_MEMORY) - { - low_mem = true; - } - } + if (timer.getElapsedTimeF32() < GPU_MEMORY_CHECK_WAIT_TIME) //call this once per second. + { + gpu = gpu_res; + physical = physical_res; + return; + } + timer.reset(); - return low_mem; + LL_RECORD_BLOCK_TIME(FTM_TEXTURE_MEMORY_CHECK); + + if (gGLManager.mHasATIMemInfo) + { + S32 meminfo[4]; + glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); + gpu_res = (S32Megabytes)meminfo[0]; + + //check main memory, only works for windows. + LLMemory::updateMemoryInfo(); + physical_res = LLMemory::getAvailableMemKB(); + } + else if (gGLManager.mHasNVXMemInfo) + { + S32 free_memory; + glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); + gpu_res = (S32Megabytes)(free_memory / 1024); + } + + gpu = gpu_res; + physical = physical_res; } static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UPDATE_MEDIA("Media"); @@ -622,22 +637,27 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity sEvaluationTimer.reset(); } } - else if(sEvaluationTimer.getElapsedTimeF32() > discard_delta_time && isMemoryForTextureLow()) + else if(isMemoryForTextureLow()) { - sDesiredDiscardBias += discard_bias_delta; + // Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to recheck + if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME) + { + sDesiredDiscardBias += discard_bias_delta; LL_DEBUGS() << "new bias " << sDesiredDiscardBias << LL_ENDL; - sEvaluationTimer.reset(); + sEvaluationTimer.reset(); + } } - else if (sDesiredDiscardBias > 0.0f && - sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale && + else if (sDesiredDiscardBias > 0.0f + && sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale // Link threshold factor for lowering bias based on total texture memory to the same value // textures will be destroyed - //sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale) - sTotalTextureMemory < sMaxTotalTextureMem * fsDestroyGLTexturesThreshold()) + //&& sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale + && sTotalTextureMemory < sMaxTotalTextureMem * fsDestroyGLTexturesThreshold() // - { + && isMemoryForTextureSuficientlyFree()) + { // If we are using less texture memory than we should, // scale down the desired discard level if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time) @@ -647,14 +667,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity } } sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max); - - F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed(); - F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); - sCameraMovingBias = llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1); - sCameraMovingDiscardBias = (S8)(sCameraMovingBias); - LLViewerTexture::sFreezeImageScalingDown = (sBoundTextureMemory < 0.75f * sMaxBoundTextureMemory * texmem_middle_bound_scale) && - (sTotalTextureMemory < 0.75f * sMaxTotalTextureMem * texmem_middle_bound_scale); + LLViewerTexture::sFreezeImageUpdates = sDesiredDiscardBias > (desired_discard_bias_max - 1.0f); } //end of static functions @@ -3277,9 +3291,9 @@ S8 LLViewerLODTexture::getType() const return LLViewerTexture::LOD_TEXTURE; } -BOOL LLViewerLODTexture::isUpdateFrozen() +bool LLViewerLODTexture::isUpdateFrozen() { - return LLViewerTexture::sFreezeImageScalingDown && !getDiscardLevel(); + return LLViewerTexture::sFreezeImageUpdates; } // This is gauranteed to get called periodically for every texture @@ -3405,9 +3419,16 @@ void LLViewerLODTexture::processTextureStats() (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) { scaleDown(); - } } + + if (isUpdateFrozen() // we are out of memory and nearing max allowed bias + && mBoostLevel < LLGLTexture::BOOST_SCULPTED + && mDesiredDiscardLevel < current_discard) + { + // stop requesting more + mDesiredDiscardLevel = current_discard; + } } if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h index fc8b1bacc7..49ad783fcf 100644 --- a/indra/newview/llviewertexture.h +++ b/indra/newview/llviewertexture.h @@ -131,7 +131,7 @@ public: virtual BOOL isMissingAsset() const ; virtual void dump(); // debug info to LL_INFOS() - virtual BOOL isViewerMediaTexture() const { return false; } + virtual bool isViewerMediaTexture() const { return false; } /*virtual*/ bool bindDefaultImage(const S32 stage = 0) ; /*virtual*/ bool bindDebugImage(const S32 stage = 0) ; @@ -196,6 +196,9 @@ private: virtual void switchToCachedImage(); static bool isMemoryForTextureLow() ; + static bool isMemoryForTextureSuficientlyFree(); + static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical); + protected: LLUUID mID; S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList @@ -244,7 +247,7 @@ public: static S32 sMaxSculptRez ; static U32 sMinLargeImageSize ; static U32 sMaxSmallImageSize ; - static BOOL sFreezeImageScalingDown ;//do not scale down image res if set. + static bool sFreezeImageUpdates; static F32 sCurrentTime ; static LLUUID sInvisiprimTexture1 ; static LLUUID sInvisiprimTexture2 ; @@ -590,7 +593,7 @@ public: /*virtual*/ S8 getType() const; // Process image stats to determine priority/quality requirements. /*virtual*/ void processTextureStats(); - BOOL isUpdateFrozen() ; + bool isUpdateFrozen() ; private: void init(bool firstinit) ; @@ -623,7 +626,7 @@ public: BOOL isPlaying() const {return mIsPlaying;} void setMediaImpl() ; - virtual BOOL isViewerMediaTexture() const { return true; } + virtual bool isViewerMediaTexture() const { return true; } void initVirtualSize() ; void invalidateMediaImpl() ; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 240b9d9d37..c59114f172 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -7804,13 +7804,34 @@ U32 LLVOAvatar::getNumAttachments() const return num_attachments; } +//----------------------------------------------------------------------------- +// getMaxAttachments() +//----------------------------------------------------------------------------- +S32 LLVOAvatar::getMaxAttachments() const +{ + const S32 MAX_AGENT_ATTACHMENTS = 38; + + S32 max_attach = MAX_AGENT_ATTACHMENTS; + + if (gAgent.getRegion()) + { + LLSD features; + gAgent.getRegion()->getSimulatorFeatures(features); + if (features.has("MaxAgentAttachments")) + { + max_attach = features["MaxAgentAttachments"].asInteger(); + } + } + return max_attach; +} + //----------------------------------------------------------------------------- // canAttachMoreObjects() // Returns true if we can attach more objects. //----------------------------------------------------------------------------- BOOL LLVOAvatar::canAttachMoreObjects(U32 n) const { - return (getNumAttachments() + n) <= MAX_AGENT_ATTACHMENTS; + return (getNumAttachments() + n) <= getMaxAttachments(); } //----------------------------------------------------------------------------- @@ -7838,7 +7859,7 @@ S32 LLVOAvatar::getMaxAnimatedObjectAttachments() const S32 max_attach = 0; if (gSavedSettings.getBOOL("AnimatedObjectsIgnoreLimits")) { - max_attach = MAX_AGENT_ATTACHMENTS; + max_attach = getMaxAttachments(); } else { diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 85f22c6c86..f65b6924c8 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -75,6 +75,8 @@ class LLTexGlobalColor; struct LLAppearanceMessageContents; class LLViewerJointMesh; +const F32 MAX_AVATAR_LOD_FACTOR = 1.0f; + //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // LLVOAvatar @@ -855,6 +857,7 @@ public: BOOL hasHUDAttachment() const; LLBBox getHUDBBox() const; void resetHUDAttachments(); + S32 getMaxAttachments() const; BOOL canAttachMoreObjects(U32 n=1) const; S32 getMaxAnimatedObjectAttachments() const; BOOL canAttachMoreAnimatedObjects(U32 n=1) const; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index eda6552feb..f4db0fb4bd 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1529,7 +1529,8 @@ BOOL LLVOVolume::calcLOD() mLODDistance = distance; mLODRadius = radius; - if (gSavedSettings.getBOOL("DebugObjectLODs")) + static LLCachedControl debug_lods(gSavedSettings, "DebugObjectLODs", false); + if (debug_lods) { if (getAvatar() && isRootEdit()) { @@ -4519,22 +4520,16 @@ F32 LLVOVolume::getBinRadius() F32 scale = 1.f; - // Use faster LLCachedControls for frequently visited locations - //S32 size_factor = llmax(gSavedSettings.getS32("OctreeStaticObjectSizeFactor"), 1); - //S32 attachment_size_factor = llmax(gSavedSettings.getS32("OctreeAttachmentSizeFactor"), 1); - //LLVector3 distance_factor = gSavedSettings.getVector3("OctreeDistanceFactor"); - //LLVector3 alpha_distance_factor = gSavedSettings.getVector3("OctreeAlphaDistanceFactor"); + static LLCachedControl octree_size_factor(gSavedSettings, "OctreeStaticObjectSizeFactor", 3); + static LLCachedControl octree_attachment_size_factor(gSavedSettings, "OctreeAttachmentSizeFactor", 4); + static LLCachedControl octree_distance_factor(gSavedSettings, "OctreeDistanceFactor", LLVector3(0.01f, 0.f, 0.f)); + static LLCachedControl octree_alpha_distance_factor(gSavedSettings, "OctreeAlphaDistanceFactor", LLVector3(0.1f, 0.f, 0.f)); - static LLCachedControl octreeStaticObjectSizeFactor(gSavedSettings, "OctreeStaticObjectSizeFactor"); - static LLCachedControl octreeAttachmentSizeFactor(gSavedSettings, "OctreeAttachmentSizeFactor"); - static LLCachedControl octreeDistanceFactor(gSavedSettings, "OctreeDistanceFactor"); - static LLCachedControl octreeAlphaDistanceFactor(gSavedSettings, "OctreeAlphaDistanceFactor"); + S32 size_factor = llmax((S32)octree_size_factor, 1); + S32 attachment_size_factor = llmax((S32)octree_attachment_size_factor, 1); + LLVector3 distance_factor = octree_distance_factor; + LLVector3 alpha_distance_factor = octree_alpha_distance_factor; - S32 size_factor = (S32)octreeStaticObjectSizeFactor; - S32 attachment_size_factor = (S32)octreeAttachmentSizeFactor; - LLVector3 distance_factor = (LLVector3)octreeDistanceFactor; - LLVector3 alpha_distance_factor = (LLVector3)octreeAlphaDistanceFactor; - // const LLVector4a* ext = mDrawable->getSpatialExtents(); BOOL shrink_wrap = mDrawable->isAnimating(); @@ -5648,18 +5643,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) U32 useage = group->getSpatialPartition()->mBufferUsage; - // replace frequent calls to saved settings with LLCachedControl - //U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - //U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - - static LLCachedControl< S32 > RenderMaxVBOSize( gSavedSettings, "RenderMaxVBOSize"); - static LLCachedControl< S32 > RenderMaxNodeSize( gSavedSettings, "RenderMaxNodeSize"); - - U32 max_vertices = (RenderMaxVBOSize*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - U32 max_total = (RenderMaxNodeSize*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - - // - + LLCachedControl max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); + LLCachedControl max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536); + U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); + U32 max_total = (max_node_size * 1024) / LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); U32 cur_total = 0; @@ -6462,14 +6449,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace #endif - // replace frequent calls to saved settings with LLCachedControl - //U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - - static LLCachedControl< S32 > RenderMaxVBOSize( gSavedSettings, "RenderMaxVBOSize"); - U32 max_vertices = (RenderMaxVBOSize*1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); - - // - + LLCachedControl max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); + U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); max_vertices = llmin(max_vertices, (U32) 65535); { @@ -6512,13 +6493,8 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels; } - // replace frequent calls to saved settings with LLCachedControl - // texture_index_channels = llmin(texture_index_channels, (S32) gSavedSettings.getU32("RenderMaxTextureIndex")); - - static LLCachedControl< U32 > RenderMaxTextureIndex( gSavedSettings, "RenderMaxTextureIndex"); - texture_index_channels = llmin(texture_index_channels, (S32) RenderMaxTextureIndex); - - // + static LLCachedControl max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16); + texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index); //NEVER use more than 16 texture index channels (workaround for prevalent driver bug) texture_index_channels = llmin(texture_index_channels, 16); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 79138cfe90..845c888d38 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -54,6 +54,10 @@ enum LLVolumeInterfaceType INTERFACE_FLEXIBLE = 1, }; +// Increase to allow temporary LOD factor of 8 +//const F32 MAX_LOD_FACTOR = 4.0f; +const F32 MAX_LOD_FACTOR = 8.0f; + class LLRiggedVolume : public LLVolume { diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index f9ab018db9..8fa096df4d 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -186,14 +186,8 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) } { - // < FS:ND> replace frequent calls to saved settings with LLCachedControl - - // const U32 max_buffer_bytes = gSavedSettings.getS32("RenderMaxVBOSize")*1024; - static LLCachedControl< S32 > RenderMaxVBOSize( gSavedSettings, "RenderMaxVBOSize"); - const U32 max_buffer_bytes = RenderMaxVBOSize*1024; - - // - + LLCachedControl max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); + const U32 max_buffer_bytes = max_vbo_size * 1024; const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; const U32 max_verts = max_buffer_bytes / LLVertexBuffer::calcVertexSize(data_mask); diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp index fe5570641b..ad57fd590b 100644 --- a/indra/newview/llwatchdog.cpp +++ b/indra/newview/llwatchdog.cpp @@ -162,7 +162,7 @@ void LLWatchdogTimeout::ping(const char *state) // LLWatchdog LLWatchdog::LLWatchdog() : - mSuspectsAccessMutex(NULL), + mSuspectsAccessMutex(), mTimer(NULL), mLastClockCount(0), mKillerCallback(&default_killer_callback) diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp index 47fe3384c1..00d87bdfd6 100644 --- a/indra/newview/llworldmapview.cpp +++ b/indra/newview/llworldmapview.cpp @@ -117,7 +117,6 @@ std::map LLWorldMapView::sStringsMap; const F32 DRAW_TEXT_THRESHOLD = 96.f; // Don't draw text under that resolution value (res = width region in meters) const S32 DRAW_SIMINFO_THRESHOLD = 3; // Max level for which we load or display sim level information (level in LLWorldMipmap sense) const S32 DRAW_LANDFORSALE_THRESHOLD = 2; // Max level for which we load or display land for sale picture data (level in LLWorldMipmap sense) -const S32 DRAW_MATURITY_THRESHOLD = 1; // Ansariel: Max level for which the maturity level will be shown (level in LLWorldMipmap sense) // When on, draw an outline for each mipmap tile gotten from S3 #define DEBUG_DRAW_TILE 0 @@ -543,9 +542,27 @@ void LLWorldMapView::draw() std::string mesg; { mesg = info->getName(); + } +// if (!mesg.empty()) +// [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5 + if ( (!mesg.empty()) && (RlvActions::canShowLocation()) ) +// [/RLVa:KB] + { + font->renderUTF8( + mesg, 0, + //llfloor(left + 3), llfloor(bottom + 2), + llfloor(left + 3.f), llfloor(bottom + (drawAdvancedRegionInfo ? 16.f : 2.f)), + LLColor4::white, + LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, + S32_MAX, //max_chars + sMapScale, //max_pixels + NULL, + TRUE); //use ellipses if (drawAdvancedRegionInfo) { + std::string advanced_info = "("; + // Only show agent count when region is online if (!info->isDown()) { @@ -557,38 +574,30 @@ void LLWorldMapView::draw() } if (agent_count > 0) { - mesg += llformat(" (%d)", agent_count); + advanced_info += llformat("%d - ", agent_count); } } - // Let the LLSimInfo instance do the translation; - // it knows everything needed for this, including - // offline status! - if (level <= DRAW_MATURITY_THRESHOLD) - { - mesg += llformat(" (%s)", info->getAccessString().c_str()); - } + advanced_info += llformat("%s)", info->getAccessString().c_str()); + + font->renderUTF8( + advanced_info, 0, + llfloor(left + 3.f), llfloor(bottom + 2.f), + LLColor4::white, + LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW, + S32_MAX, //max_chars + sMapScale, //max_pixels + NULL, + TRUE); //use ellipses } } -// if (!mesg.empty()) -// [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5 - if ( (!mesg.empty()) && (RlvActions::canShowLocation()) ) -// [/RLVa:KB] - { - font->renderUTF8( - mesg, 0, - llfloor(left + 3), llfloor(bottom + 2), - LLColor4::white, - LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); - } // Show the grid coordinates (in units of regions) if (sDrawRegionGridCoordinates) { LLVector3d origin = info->getGlobalOrigin(); std::ostringstream coords; coords << "(" << origin.mdV[VX] / REGION_WIDTH_METERS << "," << origin.mdV[VY] / REGION_WIDTH_METERS << ")"; - //mesg += coords.str(); - font->renderUTF8(coords.str(), 0, llfloor(left + 3), llfloor(bottom + 16), LLColor4::white, + font->renderUTF8(coords.str(), 0, llfloor(left + 3), llfloor(bottom + (drawAdvancedRegionInfo ? 30.f : 16.f)), LLColor4::white, LLFontGL::LEFT, LLFontGL::BASELINE, LLFontGL::NORMAL, LLFontGL::DROP_SHADOW); } // @@ -1933,9 +1942,12 @@ BOOL LLWorldMapView::handleDoubleClick( S32 x, S32 y, MASK mask ) { // Show parcel details instead of search with possible useless result //LLVector3d pos_global = viewPosToGlobal(x, y); - //LLSimInfo* info = LLWorldMap::getInstance()->simInfoFromPosGlobal(pos_global); - //LLFloaterReg::hideInstance("world_map"); - //LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", info->getName())); + //std::string sim_name; + //if (LLWorldMap::getInstance()->simNameFromPosGlobal(pos_global, sim_name)) + //{ + // LLFloaterReg::hideInstance("world_map"); + // LLFloaterReg::showInstance("search", LLSD().with("category", "land").with("query", sim_name)); + //} LLFloaterReg::hideInstance("world_map"); LLUrlAction::executeSLURL(LLSLURL("parcel", id, "about").getSLURLString()); // diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp index d48c0eb9b8..e18b42d025 100644 --- a/indra/newview/llxmlrpctransaction.cpp +++ b/indra/newview/llxmlrpctransaction.cpp @@ -362,6 +362,10 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const { httpOpts->setRetries(httpParams["retries"].asInteger()); } + if (httpParams.has("DNSCacheTimeout")) + { + httpOpts->setDNSCacheTimeout(httpParams["DNSCacheTimeout"].asInteger()); + } bool vefifySSLCert = !gSavedSettings.getBOOL("NoVerifySSLCert"); mCertStore = gSavedSettings.getString("CertStore"); @@ -483,38 +487,24 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status) { CURLcode code = static_cast(status.toULong()); std::string message; - std::string uri = "http://secondlife.com/community/support.php"; + std::string uri = "http://support.secondlife.com"; LLURI failuri(mURI); - + LLStringUtil::format_map_t args; switch (code) { case CURLE_COULDNT_RESOLVE_HOST: - message = - std::string("DNS could not resolve the host name(") + failuri.hostName() + ").\n" - "Please verify that you can connect to the www.secondlife.com\n" - "web site. If you can, but continue to receive this error,\n" - "please go to the support section and report this problem."; + args["[HOSTNAME]"] = failuri.hostName(); + message = LLTrans::getString("couldnt_resolve_host", args); break; case CURLE_SSL_PEER_CERTIFICATE: - message = - "The login server couldn't verify itself via SSL.\n" - "If you continue to receive this error, please go\n" - "to the Support section of the SecondLife.com web site\n" - "and report the problem."; + message = LLTrans::getString("ssl_peer_certificate"); break; case CURLE_SSL_CACERT: - case CURLE_SSL_CONNECT_ERROR: - message = - "Often this means that your computer\'s clock is set incorrectly.\n" - "Please go to Control Panels and make sure the time and date\n" - "are set correctly.\n" - "Also check that your network and firewall are set up correctly.\n" - "If you continue to receive this error, please go\n" - "to the Support section of the SecondLife.com web site\n" - "and report the problem."; + case CURLE_SSL_CONNECT_ERROR: + message = LLTrans::getString("ssl_connect_error"); break; default: diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1265bc5c36..a7b35f9ead 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4218,7 +4218,12 @@ void LLPipeline::renderHighlights() glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - + + if (canUseVertexShaders()) + { + gHighlightProgram.bind(); + } + gGL.setColorMask(false, false); if (LLGLSLShader::sNoFixedFunction) @@ -10163,6 +10168,11 @@ void LLPipeline::generateHighlight(LLCamera& camera) gGL.setColorMask(true, true); mHighlight.clear(); + if (canUseVertexShaders()) + { + gHighlightProgram.bind(); + } + if (LLGLSLShader::sNoFixedFunction) { gHighlightProgram.bind(); diff --git a/indra/newview/skins/default/default_languages.xml b/indra/newview/skins/default/default_languages.xml new file mode 100644 index 0000000000..357930e1c5 --- /dev/null +++ b/indra/newview/skins/default/default_languages.xml @@ -0,0 +1,39 @@ + + + diff --git a/indra/newview/skins/default/xui/da/panel_preferences_general.xml b/indra/newview/skins/default/xui/da/panel_preferences_general.xml index fb67dadd85..dc013053c2 100644 --- a/indra/newview/skins/default/xui/da/panel_preferences_general.xml +++ b/indra/newview/skins/default/xui/da/panel_preferences_general.xml @@ -4,7 +4,6 @@ Sprog: - diff --git a/indra/newview/skins/default/xui/de/floater_bulk_perms.xml b/indra/newview/skins/default/xui/de/floater_bulk_perms.xml index 76c84df21c..0d9811e3a0 100644 --- a/indra/newview/skins/default/xui/de/floater_bulk_perms.xml +++ b/indra/newview/skins/default/xui/de/floater_bulk_perms.xml @@ -38,17 +38,17 @@ Gruppe: - + Jeder: - + Nächster Eigent.: - - - + + + - -