diff options
Diffstat (limited to 'indra')
170 files changed, 2331 insertions, 3066 deletions
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake index e72475cbc4..3c87e69e5f 100644 --- a/indra/cmake/Variables.cmake +++ b/indra/cmake/Variables.cmake @@ -60,7 +60,7 @@ if (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake) set(INSTALL_PROPRIETARY ON CACHE BOOL "Install proprietary binaries") endif (EXISTS ${CMAKE_SOURCE_DIR}/Server.cmake) set(TEMPLATE_VERIFIER_OPTIONS "" CACHE STRING "Options for scripts/template_verifier.py") -set(TEMPLATE_VERIFIER_MASTER_URL "https://bitbucket.org/lindenlab/master-message-template-git/raw/master/message_template.msg" CACHE STRING "Location of the master message template") +set(TEMPLATE_VERIFIER_MASTER_URL "https://github.com/secondlife/master-message-template/raw/master/message_template.msg" CACHE STRING "Location of the master message template") if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING @@ -194,9 +194,15 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # development must be done after the build as we do in viewer_manifest.py for # released builds # https://stackoverflow.com/a/54296008 + # With Xcode 14.1, apparently you must take drastic steps to prevent + # implicit signing. + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED NO) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED NO) # "-" represents "Sign to Run Locally" and empty string represents "Do Not Sign" set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "") - + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGN_ENTITLEMENTS "") + set(CMAKE_XCODE_ATTRIBUTE_DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING YES) + set(CMAKE_XCODE_ATTRIBUTE_GCC_WARN_64_TO_32_BIT_CONVERSION NO) set(CMAKE_OSX_ARCHITECTURES "${ARCH}") string(REPLACE "i686" "i386" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") string(REPLACE "AMD64" "x86_64" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}") diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index df65828d02..108149b5f7 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -108,7 +108,6 @@ set(llcommon_SOURCE_FILES llsys.cpp lltempredirect.cpp llthread.cpp - llthreadlocalstorage.cpp llthreadsafequeue.cpp lltimer.cpp lltrace.cpp diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp index 8ddd132793..c658075a31 100644 --- a/indra/llcommon/llapp.cpp +++ b/indra/llcommon/llapp.cpp @@ -905,14 +905,14 @@ bool unix_post_minidump_callback(const char *dump_dir, // heap allocations in a crash handler. // path format: <dump_dir>/<minidump_id>.dmp - int dirPathLength = strlen(dump_dir); - int idLength = strlen(minidump_id); + auto dirPathLength = strlen(dump_dir); + auto idLength = strlen(minidump_id); // The path must not be truncated. llassert((dirPathLength + idLength + 5) <= LLApp::MAX_MINDUMP_PATH_LENGTH); char * path = LLApp::instance()->getMiniDumpFilename(); - S32 remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; + auto remaining = LLApp::MAX_MINDUMP_PATH_LENGTH; strncpy(path, dump_dir, remaining); remaining -= dirPathLength; path += dirPathLength; diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp index db94765871..435531f86f 100644 --- a/indra/llcommon/llapr.cpp +++ b/indra/llcommon/llapr.cpp @@ -30,7 +30,6 @@ #include "llapr.h" #include "llmutex.h" #include "apr_dso.h" -#include "llthreadlocalstorage.h" apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool. @@ -54,7 +53,6 @@ void ll_init_apr() LLAPRFile::sAPRFilePoolp = new LLVolatileAPRPool(FALSE) ; } - LLThreadLocalPointerBase::initAllThreadLocalStorage(); gAPRInitialized = true; } @@ -70,8 +68,6 @@ void ll_cleanup_apr() LL_DEBUGS("APR") << "Cleaning up APR" << LL_ENDL; - LLThreadLocalPointerBase::destroyAllThreadLocalStorage(); - if (gAPRPoolp) { apr_pool_destroy(gAPRPoolp); diff --git a/indra/llcommon/llbase64.cpp b/indra/llcommon/llbase64.cpp index 4e82cf7f20..bb85fe32a3 100644 --- a/indra/llcommon/llbase64.cpp +++ b/indra/llcommon/llbase64.cpp @@ -42,7 +42,7 @@ std::string LLBase64::encode(const U8* input, size_t input_size) && input_size > 0) { // Yes, it returns int. - int b64_buffer_length = apr_base64_encode_len(input_size); + int b64_buffer_length = apr_base64_encode_len(narrow(input_size)); char* b64_buffer = new char[b64_buffer_length]; // This is faster than apr_base64_encode() if you know @@ -52,7 +52,7 @@ std::string LLBase64::encode(const U8* input, size_t input_size) b64_buffer_length = apr_base64_encode_binary( b64_buffer, input, - input_size); + narrow(input_size)); output.assign(b64_buffer); delete[] b64_buffer; } diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h index 5a4b8325f4..5c46f6a796 100644 --- a/indra/llcommon/lldefs.h +++ b/indra/llcommon/lldefs.h @@ -28,6 +28,7 @@ #define LL_LLDEFS_H #include "stdtypes.h" +#include <type_traits> // Often used array indices const U32 VX = 0; @@ -168,80 +169,79 @@ const U32 MAXADDRSTR = 17; // 123.567.901.345 = 15 chars + \0 + 1 for good luc // llclampb(a) // clamps a to [0 .. 255] // -template <class LLDATATYPE> -inline LLDATATYPE llmax(const LLDATATYPE& d1, const LLDATATYPE& d2) +template <typename T1, typename T2> +inline auto llmax(T1 d1, T2 d2) { return (d1 > d2) ? d1 : d2; } -template <class LLDATATYPE> -inline LLDATATYPE llmax(const LLDATATYPE& d1, const LLDATATYPE& d2, const LLDATATYPE& d3) +template <typename T1, typename T2, typename T3> +inline auto llmax(T1 d1, T2 d2, T3 d3) { - LLDATATYPE r = llmax(d1,d2); + auto r = llmax(d1,d2); return llmax(r, d3); } -template <class LLDATATYPE> -inline LLDATATYPE llmax(const LLDATATYPE& d1, const LLDATATYPE& d2, const LLDATATYPE& d3, const LLDATATYPE& d4) +template <typename T1, typename T2, typename T3, typename T4> +inline auto llmax(T1 d1, T2 d2, T3 d3, T4 d4) { - LLDATATYPE r1 = llmax(d1,d2); - LLDATATYPE r2 = llmax(d3,d4); + auto r1 = llmax(d1,d2); + auto r2 = llmax(d3,d4); return llmax(r1, r2); } -template <class LLDATATYPE> -inline LLDATATYPE llmin(const LLDATATYPE& d1, const LLDATATYPE& d2) +template <typename T1, typename T2> +inline auto llmin(T1 d1, T2 d2) { return (d1 < d2) ? d1 : d2; } -template <class LLDATATYPE> -inline LLDATATYPE llmin(const LLDATATYPE& d1, const LLDATATYPE& d2, const LLDATATYPE& d3) +template <typename T1, typename T2, typename T3> +inline auto llmin(T1 d1, T2 d2, T3 d3) { - LLDATATYPE r = llmin(d1,d2); + auto r = llmin(d1,d2); return (r < d3 ? r : d3); } -template <class LLDATATYPE> -inline LLDATATYPE llmin(const LLDATATYPE& d1, const LLDATATYPE& d2, const LLDATATYPE& d3, const LLDATATYPE& d4) +template <typename T1, typename T2, typename T3, typename T4> +inline auto llmin(T1 d1, T2 d2, T3 d3, T4 d4) { - LLDATATYPE r1 = llmin(d1,d2); - LLDATATYPE r2 = llmin(d3,d4); + auto r1 = llmin(d1,d2); + auto r2 = llmin(d3,d4); return llmin(r1, r2); } -template <class LLDATATYPE> -inline LLDATATYPE llclamp(const LLDATATYPE& a, const LLDATATYPE& minval, const LLDATATYPE& maxval) +template <typename A, typename MIN, typename MAX> +inline A llclamp(A a, MIN minval, MAX maxval) { - if ( a < minval ) + A aminval{ static_cast<A>(minval) }, amaxval{ static_cast<A>(maxval) }; + if ( a < aminval ) { - return minval; + return aminval; } - else if ( a > maxval ) + else if ( a > amaxval ) { - return maxval; + return amaxval; } return a; } template <class LLDATATYPE> -inline LLDATATYPE llclampf(const LLDATATYPE& a) +inline LLDATATYPE llclampf(LLDATATYPE a) { - return llmin(llmax(a, (LLDATATYPE)0), (LLDATATYPE)1); + return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(1)); } template <class LLDATATYPE> -inline LLDATATYPE llclampb(const LLDATATYPE& a) +inline LLDATATYPE llclampb(LLDATATYPE a) { - return llmin(llmax(a, (LLDATATYPE)0), (LLDATATYPE)255); + return llmin(llmax(a, LLDATATYPE(0)), LLDATATYPE(255)); } template <class LLDATATYPE> inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs) { - LLDATATYPE tmp = lhs; - lhs = rhs; - rhs = tmp; + std::swap(lhs, rhs); } #endif // LL_LLDEFS_H diff --git a/indra/llcommon/lldependencies.cpp b/indra/llcommon/lldependencies.cpp index 0d5757effd..db546c5c3b 100644 --- a/indra/llcommon/lldependencies.cpp +++ b/indra/llcommon/lldependencies.cpp @@ -42,7 +42,7 @@ // other Linden headers #include "llexception.h" -LLDependenciesBase::VertexList LLDependenciesBase::topo_sort(int vertices, const EdgeList& edges) const +LLDependenciesBase::VertexList LLDependenciesBase::topo_sort(size_t vertices, const EdgeList& edges) const { // Construct a Boost Graph Library graph according to the constraints // we've collected. It seems as though we ought to be able to capture diff --git a/indra/llcommon/lldependencies.h b/indra/llcommon/lldependencies.h index db2bbab8b0..950af4a4ad 100644 --- a/indra/llcommon/lldependencies.h +++ b/indra/llcommon/lldependencies.h @@ -126,7 +126,7 @@ public: protected: typedef std::vector< std::pair<std::size_t, std::size_t> > EdgeList; typedef std::vector<std::size_t> VertexList; - VertexList topo_sort(int vertices, const EdgeList& edges) const; + VertexList topo_sort(size_t vertices, const EdgeList& edges) const; /** * refpair is specifically intended to capture a pair of references. This @@ -539,7 +539,7 @@ public: for (typename DepNodeMap::const_iterator nmi = mNodes.begin(), nmend = mNodes.end(); nmi != nmend; ++nmi) { - int thisnode = vmap[nmi->first]; + auto thisnode = vmap[nmi->first]; // after dependencies: build edges from the named node to this one for (typename DepNode::dep_set::const_iterator ai = nmi->second.after.begin(), aend = nmi->second.after.end(); diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 919d2dabc4..519426e9d1 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -1514,7 +1514,7 @@ namespace LLError const size_t BUF_SIZE = 64; char time_str[BUF_SIZE]; /* Flawfinder: ignore */ - int chars = strftime(time_str, BUF_SIZE, + auto chars = strftime(time_str, BUF_SIZE, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now)); diff --git a/indra/llcommon/lleventdispatcher.cpp b/indra/llcommon/lleventdispatcher.cpp index 5b6d4efbe9..cd0ab6bc29 100644 --- a/indra/llcommon/lleventdispatcher.cpp +++ b/indra/llcommon/lleventdispatcher.cpp @@ -178,7 +178,7 @@ private: // store it as a map from name string to position index. Of course that's // easy to generate from the incoming names array, but why do it more than // once? - typedef std::map<LLSD::String, LLSD::Integer> IndexMap; + typedef std::map<LLSD::String, size_t> IndexMap; IndexMap _indexes; // Generated array of default values, aligned with the array of param names. LLSD _defaults; @@ -197,9 +197,9 @@ LLSDArgsMapper::LLSDArgsMapper(const std::string& function, { LL_ERRS("LLSDArgsMapper") << function << " names must be an array, not " << names << LL_ENDL; } - LLSD::Integer nparams(_names.size()); + auto nparams(_names.size()); // From _names generate _indexes. - for (LLSD::Integer ni = 0, nend = _names.size(); ni < nend; ++ni) + for (size_t ni = 0, nend = _names.size(); ni < nend; ++ni) { _indexes[_names[ni]] = ni; } @@ -214,7 +214,7 @@ LLSDArgsMapper::LLSDArgsMapper(const std::string& function, if (defaults.isUndefined() || defaults.isArray()) { - LLSD::Integer ndefaults = defaults.size(); + auto ndefaults = defaults.size(); // defaults is a (possibly empty) array. Right-align it with names. if (ndefaults > nparams) { @@ -224,10 +224,10 @@ LLSDArgsMapper::LLSDArgsMapper(const std::string& function, // Offset by which we slide defaults array right to right-align with // _names array - LLSD::Integer offset = nparams - ndefaults; + auto offset = nparams - ndefaults; // Fill rightmost _defaults entries from defaults, and mark them as // filled - for (LLSD::Integer i = 0, iend = ndefaults; i < iend; ++i) + for (size_t i = 0, iend = ndefaults; i < iend; ++i) { _defaults[i + offset] = defaults[i]; _has_dft[i + offset] = 1; @@ -247,7 +247,7 @@ LLSDArgsMapper::LLSDArgsMapper(const std::string& function, continue; } - LLSD::Integer pos = ixit->second; + auto pos = ixit->second; // Store default value at that position in the _defaults array. _defaults[pos] = mi->second; // Don't forget to record the fact that we've filled this @@ -301,7 +301,7 @@ LLSD LLSDArgsMapper::map(const LLSD& argsmap) const { // Fill args from array. If there are too many args in passed array, // ignore the rest. - LLSD::Integer size(argsmap.size()); + auto size(argsmap.size()); if (size > args.size()) { // We don't just use std::min() because we want to sneak in this @@ -338,7 +338,7 @@ LLSD LLSDArgsMapper::map(const LLSD& argsmap) const << mi->first << "=" << mi->second << LL_ENDL; continue; } - LLSD::Integer pos = ixit->second; + auto pos = ixit->second; // Store the value at that position in the args array. args[pos] = mi->second; // Don't forget to record the fact that we've filled this @@ -349,7 +349,7 @@ LLSD LLSDArgsMapper::map(const LLSD& argsmap) const // Fill any remaining holes from _defaults. LLSD unfilled(LLSD::emptyArray()); - for (LLSD::Integer i = 0, iend = args.size(); i < iend; ++i) + for (size_t i = 0, iend = args.size(); i < iend; ++i) { if (! filled[i]) { @@ -503,9 +503,9 @@ struct LLEventDispatcher::MapParamsDispatchEntry: public LLEventDispatcher::Para if (defaults.isArray() || defaults.isUndefined()) { // Right-align the params and defaults arrays. - LLSD::Integer offset = params.size() - defaults.size(); + auto offset = params.size() - defaults.size(); // Now the name of every defaults[i] is at params[i + offset]. - for (LLSD::Integer i(0), iend(defaults.size()); i < iend; ++i) + for (size_t i(0), iend(defaults.size()); i < iend; ++i) { // Erase this optional param from mRequired. mRequired.erase(params[i + offset].asString()); diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h index 02535a59e7..34f2a5985a 100644 --- a/indra/llcommon/llinstancetracker.h +++ b/indra/llcommon/llinstancetracker.h @@ -99,7 +99,7 @@ public: return mSelf; } - static S32 instanceCount() + static size_t instanceCount() { return LockStatic()->mMap.size(); } @@ -363,7 +363,7 @@ public: return mSelf; } - static S32 instanceCount() + static size_t instanceCount() { return LockStatic()->mSet.size(); } diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp index 38696c2258..12e57ae94b 100644 --- a/indra/llcommon/llkeybind.cpp +++ b/indra/llcommon/llkeybind.cpp @@ -30,6 +30,7 @@ #include "llsd.h" #include "llsdutil.h" +#include <algorithm> LLKeyData::LLKeyData() : @@ -180,10 +181,10 @@ LLKeyBind::LLKeyBind(const LLSD &key_bind) bool LLKeyBind::operator==(const LLKeyBind& rhs) { - U32 size = mData.size(); + auto size = mData.size(); if (size != rhs.mData.size()) return false; - for (U32 i = 0; i < size; i++) + for (size_t i = 0; i < size; i++) { if (mData[i] != rhs.mData[i]) return false; } @@ -193,7 +194,7 @@ bool LLKeyBind::operator==(const LLKeyBind& rhs) bool LLKeyBind::operator!=(const LLKeyBind& rhs) { - U32 size = mData.size(); + auto size = mData.size(); if (size != rhs.mData.size()) return true; for (U32 i = 0; i < size; i++) @@ -213,19 +214,23 @@ bool LLKeyBind::isEmpty() const return true; } -LLSD LLKeyBind::asLLSD() const +LLKeyBind::data_vector_t::const_iterator LLKeyBind::endNonEmpty() const { - S32 last = mData.size() - 1; - while (mData[last].empty()) - { - last--; - } + // search backwards for last non-empty entry, then turn back into forwards + // iterator (.base() call) + return std::find_if_not(mData.rbegin(), mData.rend(), + [](const auto& kdata){ return kdata.empty(); }).base(); +} +LLSD LLKeyBind::asLLSD() const +{ LLSD data; - for (S32 i = 0; i <= last; ++i) + auto end{ endNonEmpty() }; + for (auto it = mData.begin(); it < end; ++it) { - // append even if empty to not affect visual representation - data.append(mData[i].asLLSD()); + // append intermediate entries even if empty to not affect visual + // representation + data.append(it->asLLSD()); } return data; } @@ -380,16 +385,10 @@ void LLKeyBind::resetKeyData(S32 index) void LLKeyBind::trimEmpty() { - S32 last = mData.size() - 1; - while (last >= 0 && mData[last].empty()) - { - mData.erase(mData.begin() + last); - last--; - } + mData.erase(endNonEmpty(), mData.end()); } -U32 LLKeyBind::getDataCount() +size_t LLKeyBind::getDataCount() { return mData.size(); } - diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h index c6b4bd970f..488f509411 100644 --- a/indra/llcommon/llkeybind.h +++ b/indra/llcommon/llkeybind.h @@ -95,11 +95,13 @@ public: void clear() { mData.clear(); } // if there any empty LLKeyData in the end of the array, remove them void trimEmpty(); - U32 getDataCount(); + size_t getDataCount(); private: typedef std::vector<LLKeyData> data_vector_t; data_vector_t mData; + + data_vector_t::const_iterator endNonEmpty() const; }; diff --git a/indra/llcommon/llleap.cpp b/indra/llcommon/llleap.cpp index 2704f8b6de..c87c0758fe 100644 --- a/indra/llcommon/llleap.cpp +++ b/indra/llcommon/llleap.cpp @@ -231,7 +231,8 @@ public: } |*==========================================================================*/ - LL_DEBUGS("EventHost") << "Sending: " << buffer.tellp() << ':'; + LL_DEBUGS("EventHost") << "Sending: " + << static_cast<U64>(buffer.tellp()) << ':'; std::string::size_type truncate(80); if (buffer.tellp() <= truncate) { @@ -244,7 +245,8 @@ public: LL_CONT << LL_ENDL; LLProcess::WritePipe& childin(mChild->getWritePipe(LLProcess::STDIN)); - childin.get_ostream() << buffer.tellp() << ':' << buffer.str() << std::flush; + childin.get_ostream() << static_cast<U64>(buffer.tellp()) + << ':' << buffer.str() << std::flush; return false; } diff --git a/indra/llcommon/llmd5.cpp b/indra/llcommon/llmd5.cpp index f942a976b7..9b2a2bab60 100644 --- a/indra/llcommon/llmd5.cpp +++ b/indra/llcommon/llmd5.cpp @@ -96,10 +96,10 @@ LLMD5::LLMD5() // operation, processing another message block, and updating the // context. -void LLMD5::update (const uint1 *input, const uint4 input_length) { +void LLMD5::update (const uint1 *input, const size_t input_length) { - uint4 input_index, buffer_index; - uint4 buffer_space; // how much space is left in buffer + size_t input_index, buffer_index; + size_t buffer_space; // how much space is left in buffer if (finalized){ // so we can't update! std::cerr << "LLMD5::update: Can't update a finalized digest!" << std::endl; @@ -107,14 +107,10 @@ void LLMD5::update (const uint1 *input, const uint4 input_length) { } // Compute number of bytes mod 64 - buffer_index = (unsigned int)((count[0] >> 3) & 0x3F); + buffer_index = size_t((count >> 3) & 0x3F); // Update number of bits - if ( (count[0] += ((uint4) input_length << 3))<((uint4) input_length << 3) ) - count[1]++; - - count[1] += ((uint4)input_length >> 29); - + count += input_length << 3; buffer_space = 64 - buffer_index; // how much space is left in buffer @@ -192,7 +188,7 @@ void LLMD5::update(const std::string& s) void LLMD5::finalize (){ unsigned char bits[8]; /* Flawfinder: ignore */ - unsigned int index, padLen; + size_t index, padLen; static uint1 PADDING[64]={ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -204,11 +200,12 @@ void LLMD5::finalize (){ return; } - // Save number of bits - encode (bits, count, 8); + // Save number of bits. + // Treat count, a uint64_t, as uint4[2]. + encode (bits, reinterpret_cast<uint4*>(&count), 8); // Pad out to 56 mod 64. - index = (uint4) ((count[0] >> 3) & 0x3f); + index = size_t((count >> 3) & 0x3f); padLen = (index < 56) ? (56 - index) : (120 - index); update (PADDING, padLen); @@ -340,8 +337,7 @@ void LLMD5::init(){ finalized=0; // we just started! // Nothing counted, so count=0 - count[0] = 0; - count[1] = 0; + count = 0; // Load magic initialization constants. state[0] = 0x67452301; @@ -508,9 +504,9 @@ void LLMD5::transform (const U8 block[64]){ // Encodes input (UINT4) into output (unsigned char). Assumes len is // a multiple of 4. -void LLMD5::encode (uint1 *output, const uint4 *input, const uint4 len) { +void LLMD5::encode (uint1 *output, const uint4 *input, const size_t len) { - unsigned int i, j; + size_t i, j; for (i = 0, j = 0; j < len; i++, j += 4) { output[j] = (uint1) (input[i] & 0xff); @@ -525,9 +521,9 @@ void LLMD5::encode (uint1 *output, const uint4 *input, const uint4 len) { // Decodes input (unsigned char) into output (UINT4). Assumes len is // a multiple of 4. -void LLMD5::decode (uint4 *output, const uint1 *input, const uint4 len){ +void LLMD5::decode (uint4 *output, const uint1 *input, const size_t len){ - unsigned int i, j; + size_t i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((uint4)input[j]) | (((uint4)input[j+1]) << 8) | diff --git a/indra/llcommon/llmd5.h b/indra/llcommon/llmd5.h index 1526e6ac3c..8530dc0389 100644 --- a/indra/llcommon/llmd5.h +++ b/indra/llcommon/llmd5.h @@ -86,7 +86,7 @@ class LL_COMMON_API LLMD5 { public: // methods for controlled operation: LLMD5 (); // simple initializer - void update (const uint1 *input, const uint4 input_length); + void update (const uint1 *input, const size_t input_length); void update (std::istream& stream); void update (FILE *file); void update (const std::string& str); @@ -110,7 +110,7 @@ private: // next, the private data: uint4 state[4]; - uint4 count[2]; // number of *bits*, mod 2^64 + uint64_t count; // number of *bits*, mod 2^64 uint1 buffer[64]; // input buffer uint1 digest[16]; uint1 finalized; @@ -120,8 +120,8 @@ private: void transform (const uint1 *buffer); // does the real update work. Note // that length is implied to be 64. - static void encode (uint1 *dest, const uint4 *src, const uint4 length); - static void decode (uint4 *dest, const uint1 *src, const uint4 length); + static void encode (uint1 *dest, const uint4 *src, const size_t length); + static void decode (uint4 *dest, const uint1 *src, const size_t length); }; diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp index 100eb57555..864ecf650b 100644 --- a/indra/llcommon/llmetricperformancetester.cpp +++ b/indra/llcommon/llmetricperformancetester.cpp @@ -111,8 +111,8 @@ LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& i { ret[label]["Name"] = iter->second["Name"] ; - S32 num_of_metrics = tester->getNumberOfMetrics() ; - for(S32 index = 0 ; index < num_of_metrics ; index++) + auto num_of_metrics = tester->getNumberOfMetrics() ; + for(size_t index = 0 ; index < num_of_metrics ; index++) { ret[label][ tester->getMetricName(index) ] = iter->second[ tester->getMetricName(index) ] ; } diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h index 2e99ed979d..6561a78f03 100644 --- a/indra/llcommon/llmetricperformancetester.h +++ b/indra/llcommon/llmetricperformancetester.h @@ -67,12 +67,12 @@ public: /** * @return Returns the number of the test metrics in this tester instance. */ - S32 getNumberOfMetrics() const { return mMetricStrings.size() ;} + auto getNumberOfMetrics() const { return mMetricStrings.size() ;} /** * @return Returns the metric name at index * @param[in] index - Index on the list of metrics managed by this tester instance. */ - std::string getMetricName(S32 index) const { return mMetricStrings[index] ;} + std::string getMetricName(size_t index) const { return mMetricStrings[index] ;} protected: /** diff --git a/indra/llcommon/llmortician.cpp b/indra/llcommon/llmortician.cpp index 93c7d520f2..b6ad40c2af 100644 --- a/indra/llcommon/llmortician.cpp +++ b/indra/llcommon/llmortician.cpp @@ -37,9 +37,9 @@ LLMortician::~LLMortician() sGraveyard.remove(this); } -U32 LLMortician::logClass(std::stringstream &str) +size_t LLMortician::logClass(std::stringstream &str) { - U32 size = sGraveyard.size(); + auto size = sGraveyard.size(); str << "Mortician graveyard count: " << size; str << " Zealous: " << (sDestroyImmediate ? "True" : "False"); if (size == 0) diff --git a/indra/llcommon/llmortician.h b/indra/llcommon/llmortician.h index 41cb49fab1..f92c5a11db 100644 --- a/indra/llcommon/llmortician.h +++ b/indra/llcommon/llmortician.h @@ -34,8 +34,8 @@ class LL_COMMON_API LLMortician { public: LLMortician() { mIsDead = FALSE; } - static U32 graveyardCount() { return sGraveyard.size(); }; - static U32 logClass(std::stringstream &str); + static auto graveyardCount() { return sGraveyard.size(); }; + static size_t logClass(std::stringstream &str); static void updateClass(); virtual ~LLMortician(); void die(); diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp index 8cef4293cd..b06fee0ec2 100644 --- a/indra/llcommon/llqueuedthread.cpp +++ b/indra/llcommon/llqueuedthread.cpp @@ -110,7 +110,7 @@ void LLQueuedThread::shutdown() // MAIN THREAD // virtual -S32 LLQueuedThread::update(F32 max_time_ms) +size_t LLQueuedThread::update(F32 max_time_ms) { if (!mStarted) { @@ -123,11 +123,11 @@ S32 LLQueuedThread::update(F32 max_time_ms) return updateQueue(max_time_ms); } -S32 LLQueuedThread::updateQueue(F32 max_time_ms) +size_t LLQueuedThread::updateQueue(F32 max_time_ms) { F64 max_time = (F64)max_time_ms * .001; LLTimer timer; - S32 pending = 1; + size_t pending = 1; // Frame Update if (mThreaded) @@ -164,9 +164,9 @@ void LLQueuedThread::incQueue() //virtual // May be called from any thread -S32 LLQueuedThread::getPending() +size_t LLQueuedThread::getPending() { - S32 res; + size_t res; lockData(); res = mRequestQueue.size(); unlockData(); @@ -399,7 +399,7 @@ bool LLQueuedThread::check() //============================================================================ // Runs on its OWN thread -S32 LLQueuedThread::processNextRequest() +size_t LLQueuedThread::processNextRequest() { QueuedRequest *req; // Get next request from pool @@ -473,8 +473,7 @@ S32 LLQueuedThread::processNextRequest() LLTrace::get_thread_recorder()->pushToParent(); } - S32 pending = getPending(); - return pending; + return getPending(); } // virtual @@ -511,7 +510,7 @@ void LLQueuedThread::run() threadedUpdate(); - int pending_work = processNextRequest(); + auto pending_work = processNextRequest(); if (pending_work == 0) { diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h index 5d3f873646..90fce3dc5d 100644 --- a/indra/llcommon/llqueuedthread.h +++ b/indra/llcommon/llqueuedthread.h @@ -167,19 +167,19 @@ private: protected: handle_t generateHandle(); bool addRequest(QueuedRequest* req); - S32 processNextRequest(void); + size_t processNextRequest(void); void incQueue(); public: bool waitForResult(handle_t handle, bool auto_complete = true); - virtual S32 update(F32 max_time_ms); - S32 updateQueue(F32 max_time_ms); - + virtual size_t update(F32 max_time_ms); + size_t updateQueue(F32 max_time_ms); + void waitOnPending(); void printQueueStats(); - virtual S32 getPending(); + virtual size_t getPending(); bool getThreaded() { return mThreaded ? true : false; } // Request accessors diff --git a/indra/llcommon/llrun.cpp b/indra/llcommon/llrun.cpp index f5d3f302fa..a3b3fccf4b 100644 --- a/indra/llcommon/llrun.cpp +++ b/indra/llcommon/llrun.cpp @@ -47,7 +47,7 @@ LLRunner::~LLRunner() mRunEvery.clear(); } -S32 LLRunner::run() +size_t LLRunner::run() { // We collect all of the runnables which should be run. Since the // runnables are allowed to adjust the run list, we need to copy diff --git a/indra/llcommon/llrun.h b/indra/llcommon/llrun.h index a117405366..d610f86234 100644 --- a/indra/llcommon/llrun.h +++ b/indra/llcommon/llrun.h @@ -85,7 +85,7 @@ public: * * @return Returns the number of runnables run. */ - S32 run(); + size_t run(); /** * @brief Add a runnable to the run list. diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp index 807b3d13f8..a645e624f8 100644 --- a/indra/llcommon/llsd.cpp +++ b/indra/llcommon/llsd.cpp @@ -36,6 +36,18 @@ #include "llsdserialize.h" #include "stringize.h" +#include <limits> + +// Defend against a caller forcibly passing a negative number into an unsigned +// size_t index param +inline +bool was_negative(size_t i) +{ + return (i > std::numeric_limits<int>::max()); +} +#define NEGATIVE_EXIT(i) if (was_negative(i)) return +#define NEGATIVE_RETURN(i, result) NEGATIVE_EXIT(i) (result) + #ifndef LL_RELEASE_FOR_DOWNLOAD #define NAME_UNNAMED_NAMESPACE #endif @@ -136,10 +148,10 @@ public: virtual void erase(const String&) { } virtual const LLSD& ref(const String&) const{ return undef(); } - virtual int size() const { return 0; } - virtual LLSD get(Integer) const { return LLSD(); } - virtual void erase(Integer) { } - virtual const LLSD& ref(Integer) const { return undef(); } + virtual size_t size() const { return 0; } + virtual LLSD get(size_t) const { return LLSD(); } + virtual void erase(size_t) { } + virtual const LLSD& ref(size_t) const { return undef(); } virtual LLSD::map_const_iterator beginMap() const { return endMap(); } virtual LLSD::map_const_iterator endMap() const { static const std::map<String, LLSD> empty; return empty.end(); } @@ -272,7 +284,7 @@ namespace virtual LLSD::UUID asUUID() const { return LLUUID(mValue); } virtual LLSD::Date asDate() const { return LLDate(mValue); } virtual LLSD::URI asURI() const { return LLURI(mValue); } - virtual int size() const { return mValue.size(); } + virtual size_t size() const { return mValue.size(); } virtual const LLSD::String& asStringRef() const { return mValue; } }; @@ -377,9 +389,9 @@ namespace virtual bool has(const LLSD::String&) const; - using LLSD::Impl::get; // Unhiding get(LLSD::Integer) - using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer) - using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer) + using LLSD::Impl::get; // Unhiding get(size_t) + using LLSD::Impl::erase; // Unhiding erase(size_t) + using LLSD::Impl::ref; // Unhiding ref(size_t) virtual LLSD get(const LLSD::String&) const; virtual LLSD getKeys() const; void insert(const LLSD::String& k, const LLSD& v); @@ -387,7 +399,7 @@ namespace LLSD& ref(const LLSD::String&); virtual const LLSD& ref(const LLSD::String&) const; - virtual int size() const { return mData.size(); } + virtual size_t size() const { return mData.size(); } LLSD::map_iterator beginMap() { return mData.begin(); } LLSD::map_iterator endMap() { return mData.end(); } @@ -518,14 +530,14 @@ namespace using LLSD::Impl::get; // Unhiding get(LLSD::String) using LLSD::Impl::erase; // Unhiding erase(LLSD::String) using LLSD::Impl::ref; // Unhiding ref(LLSD::String) - virtual int size() const; - virtual LLSD get(LLSD::Integer) const; - void set(LLSD::Integer, const LLSD&); - void insert(LLSD::Integer, const LLSD&); + virtual size_t size() const; + virtual LLSD get(size_t) const; + void set(size_t, const LLSD&); + void insert(size_t, const LLSD&); LLSD& append(const LLSD&); - virtual void erase(LLSD::Integer); - LLSD& ref(LLSD::Integer); - virtual const LLSD& ref(LLSD::Integer) const; + virtual void erase(size_t); + LLSD& ref(size_t); + virtual const LLSD& ref(size_t) const; LLSD::array_iterator beginArray() { return mData.begin(); } LLSD::array_iterator endArray() { return mData.end(); } @@ -550,85 +562,82 @@ namespace return *this; } } - - int ImplArray::size() const { return mData.size(); } - - LLSD ImplArray::get(LLSD::Integer i) const + + size_t ImplArray::size() const { return mData.size(); } + + LLSD ImplArray::get(size_t i) const { - if (i < 0) { return LLSD(); } + NEGATIVE_RETURN(i, LLSD()); DataVector::size_type index = i; - + return (index < mData.size()) ? mData[index] : LLSD(); } - - void ImplArray::set(LLSD::Integer i, const LLSD& v) + + void ImplArray::set(size_t i, const LLSD& v) { - if (i < 0) { return; } + NEGATIVE_EXIT(i); DataVector::size_type index = i; - + if (index >= mData.size()) { mData.resize(index + 1); } - + mData[index] = v; } - - void ImplArray::insert(LLSD::Integer i, const LLSD& v) + + void ImplArray::insert(size_t i, const LLSD& v) { - if (i < 0) - { - return; - } + NEGATIVE_EXIT(i); DataVector::size_type index = i; - + if (index >= mData.size()) // tbd - sanity check limit for index ? { mData.resize(index + 1); } - + mData.insert(mData.begin() + index, v); } - + LLSD& ImplArray::append(const LLSD& v) { mData.push_back(v); return mData.back(); } - - void ImplArray::erase(LLSD::Integer i) + + void ImplArray::erase(size_t i) { - if (i < 0) { return; } + NEGATIVE_EXIT(i); DataVector::size_type index = i; - + if (index < mData.size()) { mData.erase(mData.begin() + index); } } - - LLSD& ImplArray::ref(LLSD::Integer i) + + LLSD& ImplArray::ref(size_t i) { - DataVector::size_type index = i >= 0 ? i : 0; - + DataVector::size_type index = was_negative(i)? 0 : i; + if (index >= mData.size()) { mData.resize(i + 1); } - + return mData[index]; } - const LLSD& ImplArray::ref(LLSD::Integer i) const + const LLSD& ImplArray::ref(size_t i) const { - if (i < 0) { return undef(); } + NEGATIVE_RETURN(i, undef()); DataVector::size_type index = i; - + if (index >= mData.size()) { return undef(); } - + return mData[index]; } @@ -841,9 +850,6 @@ LLSD::LLSD(const Date& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const URI& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } LLSD::LLSD(const Binary& v) : impl(0) { ALLOC_LLSD_OBJECT; assign(v); } -// Convenience Constructors -LLSD::LLSD(F32 v) : impl(0) { ALLOC_LLSD_OBJECT; assign((Real)v); } - // Scalar Assignment void LLSD::assign(Boolean v) { safe(impl).assign(impl, v); } void LLSD::assign(Integer v) { safe(impl).assign(impl, v); } @@ -912,7 +918,7 @@ LLSD LLSD::emptyArray() return v; } -int LLSD::size() const { return safe(impl).size(); } +size_t LLSD::size() const { return safe(impl).size(); } LLSD LLSD::get(Integer i) const { return safe(impl).get(i); } void LLSD::set(Integer i, const LLSD& v){ makeArray(impl).set(i, v); } @@ -926,12 +932,12 @@ LLSD& LLSD::with(Integer i, const LLSD& v) LLSD& LLSD::append(const LLSD& v) { return makeArray(impl).append(v); } void LLSD::erase(Integer i) { makeArray(impl).erase(i); } -LLSD& LLSD::operator[](Integer i) +LLSD& LLSD::operator[](size_t i) { LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; return makeArray(impl).ref(i); } -const LLSD& LLSD::operator[](Integer i) const +const LLSD& LLSD::operator[](size_t i) const { LL_PROFILE_ZONE_SCOPED_CATEGORY_LLSD; return safe(impl).ref(i); @@ -956,7 +962,7 @@ static const char *llsd_dump(const LLSD &llsd, bool useXMLFormat) out << LLSDNotationStreamer(llsd); out_string = out.str(); } - int len = out_string.length(); + auto len = out_string.length(); sStorage = new char[len + 1]; memcpy(sStorage, out_string.c_str(), len); sStorage[len] = '\0'; diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h index 24cb9bbce1..c1406cf73f 100644 --- a/indra/llcommon/llsd.h +++ b/indra/llcommon/llsd.h @@ -30,6 +30,7 @@ #include <map> #include <string> #include <vector> +#include <type_traits> #include "stdtypes.h" @@ -192,7 +193,17 @@ public: /** @name Convenience Constructors */ //@{ - LLSD(F32); // F32 -> Real + // support construction from size_t et al. + template <typename VALUE, + typename std::enable_if<std::is_integral<VALUE>::value && + ! std::is_same<VALUE, Boolean>::value, + bool>::type = true> + LLSD(VALUE v): LLSD(Integer(narrow(v))) {} + // support construction from F32 et al. + template <typename VALUE, + typename std::enable_if<std::is_floating_point<VALUE>::value, + bool>::type = true> + LLSD(VALUE v): LLSD(Real(narrow(v))) {} //@} /** @name Scalar Assignment */ @@ -205,15 +216,21 @@ public: void assign(const Date&); void assign(const URI&); void assign(const Binary&); - - LLSD& operator=(Boolean v) { assign(v); return *this; } - LLSD& operator=(Integer v) { assign(v); return *this; } - LLSD& operator=(Real v) { assign(v); return *this; } - LLSD& operator=(const String& v) { assign(v); return *this; } - LLSD& operator=(const UUID& v) { assign(v); return *this; } - LLSD& operator=(const Date& v) { assign(v); return *this; } - LLSD& operator=(const URI& v) { assign(v); return *this; } - LLSD& operator=(const Binary& v) { assign(v); return *this; } + + // support assignment from size_t et al. + template <typename VALUE, + typename std::enable_if<std::is_integral<VALUE>::value && + ! std::is_same<VALUE, Boolean>::value, + bool>::type = true> + void assign(VALUE v) { assign(Integer(narrow(v))); } + // support assignment from F32 et al. + template <typename VALUE, + typename std::enable_if<std::is_floating_point<VALUE>::value, + bool>::type = true> + void assign(VALUE v) { assign(Real(narrow(v))); } + + template <typename VALUE> + LLSD& operator=(VALUE v) { assign(v); return *this; } //@} /** @@ -275,7 +292,6 @@ public: //@{ LLSD(const char*); void assign(const char*); - LLSD& operator=(const char* v) { assign(v); return *this; } //@} /** @name Map Values */ @@ -313,14 +329,24 @@ public: LLSD& append(const LLSD&); void erase(Integer); LLSD& with(Integer, const LLSD&); - - const LLSD& operator[](Integer) const; - LLSD& operator[](Integer); + + // accept size_t so we can index relative to size() + const LLSD& operator[](size_t) const; + LLSD& operator[](size_t); + // template overloads to support int literals, U32 et al. + template <typename IDX, + typename std::enable_if<std::is_convertible<IDX, size_t>::value, + bool>::type = true> + const LLSD& operator[](IDX i) const { return (*this)[size_t(i)]; } + template <typename IDX, + typename std::enable_if<std::is_convertible<IDX, size_t>::value, + bool>::type = true> + LLSD& operator[](IDX i) { return (*this)[size_t(i)]; } //@} /** @name Iterators */ //@{ - int size() const; + size_t size() const; typedef std::map<String, LLSD>::iterator map_iterator; typedef std::map<String, LLSD>::const_iterator map_const_iterator; diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 8b4a0ee6d8..af57f4ac5e 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -50,7 +50,7 @@ #include "lluri.h" // File constants -static const int MAX_HDR_LEN = 20; +static const size_t MAX_HDR_LEN = 20; static const S32 UNZIP_LLSD_MAX_DEPTH = 96; static const char LEGACY_NON_HEADER[] = "<llsd>"; const std::string LLSD_BINARY_HEADER("LLSD/Binary"); @@ -99,7 +99,7 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize } // static -bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes) +bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, llssize max_bytes) { LLPointer<LLSDParser> p = NULL; char hdr_buf[MAX_HDR_LEN + 1] = ""; /* Flawfinder: ignore */ @@ -252,7 +252,7 @@ F64 ll_ntohd(F64 netdouble) * @return Returns number of bytes read off of the stream. Returns * PARSE_FAILURE (-1) on failure. */ -int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes); +llssize deserialize_string(std::istream& istr, std::string& value, llssize max_bytes); /** * @brief Parse a delimited string. @@ -263,7 +263,7 @@ int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes); * @return Returns number of bytes read off of the stream. Returns * PARSE_FAILURE (-1) on failure. */ -int deserialize_string_delim(std::istream& istr, std::string& value, char d); +llssize deserialize_string_delim(std::istream& istr, std::string& value, char d); /** * @brief Read a raw string off the stream. @@ -277,10 +277,10 @@ int deserialize_string_delim(std::istream& istr, std::string& value, char d); * @return Returns number of bytes read off of the stream. Returns * PARSE_FAILURE (-1) on failure. */ -int deserialize_string_raw( +llssize deserialize_string_raw( std::istream& istr, std::string& value, - S32 max_bytes); + llssize max_bytes); /** * @brief helper method for dealing with the different notation boolean format. @@ -292,7 +292,7 @@ int deserialize_string_raw( * @return Returns number of bytes read off of the stream. Returns * PARSE_FAILURE (-1) on failure. */ -int deserialize_boolean( +llssize deserialize_boolean( std::istream& istr, LLSD& data, const std::string& compare, @@ -329,7 +329,7 @@ LLSDParser::LLSDParser() LLSDParser::~LLSDParser() { } -S32 LLSDParser::parse(std::istream& istr, LLSD& data, S32 max_bytes, S32 max_depth) +S32 LLSDParser::parse(std::istream& istr, LLSD& data, llssize max_bytes, S32 max_depth) { mCheckLimits = (LLSDSerialize::SIZE_UNLIMITED == max_bytes) ? false : true; mMaxBytesLeft = max_bytes; @@ -359,7 +359,7 @@ std::istream& LLSDParser::get( char delim) const { istr.get(s, n, delim); - if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); + if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); return istr; } @@ -369,7 +369,7 @@ std::istream& LLSDParser::get( char delim) const { istr.get(sb, delim); - if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); + if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); return istr; } @@ -393,11 +393,11 @@ std::istream& LLSDParser::read( std::streamsize n) const { istr.read(s, n); - if(mCheckLimits) mMaxBytesLeft -= (int)istr.gcount(); + if(mCheckLimits) mMaxBytesLeft -= istr.gcount(); return istr; } -void LLSDParser::account(S32 bytes) const +void LLSDParser::account(llssize bytes) const { if(mCheckLimits) mMaxBytesLeft -= bytes; } @@ -502,7 +502,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c c = istr.peek(); if(isalpha(c)) { - int cnt = deserialize_boolean( + auto cnt = deserialize_boolean( istr, data, NOTATION_FALSE_SERIAL, @@ -532,7 +532,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c c = istr.peek(); if(isalpha(c)) { - int cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true); + auto cnt = deserialize_boolean(istr,data,NOTATION_TRUE_SERIAL,true); if(PARSE_FAILURE == cnt) parse_count = cnt; else account(cnt); } @@ -608,7 +608,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c c = get(istr); // pop the 'l' c = get(istr); // pop the delimiter std::string str; - int cnt = deserialize_string_delim(istr, str, c); + auto cnt = deserialize_string_delim(istr, str, c); if(PARSE_FAILURE == cnt) { parse_count = PARSE_FAILURE; @@ -631,7 +631,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c c = get(istr); // pop the 'd' c = get(istr); // pop the delimiter std::string str; - int cnt = deserialize_string_delim(istr, str, c); + auto cnt = deserialize_string_delim(istr, str, c); if(PARSE_FAILURE == cnt) { parse_count = PARSE_FAILURE; @@ -663,7 +663,7 @@ S32 LLSDNotationParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) c default: parse_count = PARSE_FAILURE; - LL_INFOS() << "Unrecognized character while parsing: int(" << (int)c + LL_INFOS() << "Unrecognized character while parsing: int(" << int(c) << ")" << LL_ENDL; break; } @@ -694,7 +694,7 @@ S32 LLSDNotationParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) c { putback(istr, c); found_name = true; - int count = deserialize_string(istr, name, mMaxBytesLeft); + auto count = deserialize_string(istr, name, mMaxBytesLeft); if(PARSE_FAILURE == count) return PARSE_FAILURE; account(count); } @@ -776,7 +776,7 @@ S32 LLSDNotationParser::parseArray(std::istream& istr, LLSD& array, S32 max_dept bool LLSDNotationParser::parseString(std::istream& istr, LLSD& data) const { std::string value; - int count = deserialize_string(istr, value, mMaxBytesLeft); + auto count = deserialize_string(istr, value, mMaxBytesLeft); if(PARSE_FAILURE == count) return false; account(count); data = value; @@ -803,13 +803,13 @@ bool LLSDNotationParser::parseBinary(std::istream& istr, LLSD& data) const { // We probably have a valid raw binary stream. determine // the size, and read it. - S32 len = strtol(buf + 2, NULL, 0); + auto len = strtol(buf + 2, NULL, 0); if(mCheckLimits && (len > mMaxBytesLeft)) return false; std::vector<U8> value; if(len) { value.resize(len); - account((int)fullread(istr, (char *)&value[0], len)); + account(fullread(istr, (char *)&value[0], len)); } c = get(istr); // strip off the trailing double-quote data = value; @@ -1006,7 +1006,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) con case '"': { std::string value; - int cnt = deserialize_string_delim(istr, value, c); + auto cnt = deserialize_string_delim(istr, value, c); if(PARSE_FAILURE == cnt) { parse_count = PARSE_FAILURE; @@ -1093,7 +1093,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) con if(size > 0) { value.resize(size); - account((int)fullread(istr, (char*)&value[0], size)); + account(fullread(istr, (char*)&value[0], size)); } data = value; } @@ -1107,7 +1107,7 @@ S32 LLSDBinaryParser::doParse(std::istream& istr, LLSD& data, S32 max_depth) con default: parse_count = PARSE_FAILURE; - LL_INFOS() << "Unrecognized character while parsing: int(" << (int)c + LL_INFOS() << "Unrecognized character while parsing: int(" << int(c) << ")" << LL_ENDL; break; } @@ -1141,7 +1141,7 @@ S32 LLSDBinaryParser::parseMap(std::istream& istr, LLSD& map, S32 max_depth) con case '\'': case '"': { - int cnt = deserialize_string_delim(istr, name, c); + auto cnt = deserialize_string_delim(istr, name, c); if(PARSE_FAILURE == cnt) return PARSE_FAILURE; account(cnt); break; @@ -1225,7 +1225,7 @@ bool LLSDBinaryParser::parseString( if(size) { buf.resize(size); - account((int)fullread(istr, &buf[0], size)); + account(fullread(istr, &buf[0], size)); value.assign(buf.begin(), buf.end()); } return true; @@ -1429,7 +1429,7 @@ S32 LLSDNotationFormatter::format_impl(const LLSD& data, std::ostream& ostr, ostr << std::uppercase; auto oldfill(ostr.fill('0')); auto oldwidth(ostr.width()); - for (int i = 0; i < buffer.size(); i++) + for (size_t i = 0; i < buffer.size(); i++) { // have to restate setw() before every conversion ostr << std::setw(2) << (int) buffer[i]; @@ -1592,7 +1592,7 @@ void LLSDBinaryFormatter::formatString( /** * local functions */ -int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes) +llssize deserialize_string(std::istream& istr, std::string& value, llssize max_bytes) { int c = istr.get(); if(istr.fail()) @@ -1602,7 +1602,7 @@ int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes) return LLSDParser::PARSE_FAILURE; } - int rv = LLSDParser::PARSE_FAILURE; + llssize rv = LLSDParser::PARSE_FAILURE; switch(c) { case '\'': @@ -1622,7 +1622,7 @@ int deserialize_string(std::istream& istr, std::string& value, S32 max_bytes) return rv + 1; // account for the character grabbed at the top. } -int deserialize_string_delim( +llssize deserialize_string_delim( std::istream& istr, std::string& value, char delim) @@ -1632,7 +1632,7 @@ int deserialize_string_delim( bool found_hex = false; bool found_digit = false; U8 byte = 0; - int count = 0; + llssize count = 0; while (true) { @@ -1647,7 +1647,7 @@ int deserialize_string_delim( } char next_char = (char)next_byte; // Now that we know it's not EOF - + if(found_escape) { // next character(s) is a special sequence. @@ -1725,16 +1725,16 @@ int deserialize_string_delim( return count; } -int deserialize_string_raw( +llssize deserialize_string_raw( std::istream& istr, std::string& value, - S32 max_bytes) + llssize max_bytes) { - int count = 0; + llssize count = 0; const S32 BUF_LEN = 20; char buf[BUF_LEN]; /* Flawfinder: ignore */ istr.get(buf, BUF_LEN - 1, ')'); - count += (int)istr.gcount(); + count += istr.gcount(); int c = istr.get(); c = istr.get(); count += 2; @@ -1743,13 +1743,13 @@ int deserialize_string_raw( // We probably have a valid raw string. determine // the size, and read it. // *FIX: This is memory inefficient. - S32 len = strtol(buf + 1, NULL, 0); + auto len = strtol(buf + 1, NULL, 0); if((max_bytes>0)&&(len>max_bytes)) return LLSDParser::PARSE_FAILURE; std::vector<char> buf; if(len) { buf.resize(len); - count += (int)fullread(istr, (char *)&buf[0], len); + count += fullread(istr, (char *)&buf[0], len); value.assign(buf.begin(), buf.end()); } c = istr.get(); @@ -2038,7 +2038,7 @@ void serialize_string(const std::string& value, std::ostream& str) } } -int deserialize_boolean( +llssize deserialize_boolean( std::istream& istr, LLSD& data, const std::string& compare, @@ -2055,7 +2055,7 @@ int deserialize_boolean( // * set data to LLSD::null // * return LLSDParser::PARSE_FAILURE (-1) // - int bytes_read = 0; + llssize bytes_read = 0; std::string::size_type ii = 0; char c = istr.peek(); while((++ii < compare.size()) @@ -2110,7 +2110,7 @@ std::string zip_llsd(LLSD& data) U8 out[CHUNK]; - strm.avail_in = source.size(); + strm.avail_in = narrow(source.size()); strm.next_in = (U8*) source.data(); U8* output = NULL; @@ -2173,7 +2173,7 @@ std::string zip_llsd(LLSD& data) LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size) { U8* result = NULL; - U32 cur_size = 0; + llssize cur_size = 0; z_stream strm; const U32 CHUNK = 65536; @@ -2294,7 +2294,7 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, //This unzip function will only work with a gzip header and trailer - while the contents //of the actual compressed data is the same for either format (gzip vs zlib ), the headers //and trailers are different for the formats. -U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 size ) +U8* unzip_llsdNavMesh( bool& valid, size_t& outsize, std::istream& is, S32 size ) { if (size == 0) { diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index d6079fd9fa..bd5ef668c0 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -77,7 +77,7 @@ public: * @return Returns the number of LLSD objects parsed into * data. Returns PARSE_FAILURE (-1) on parse failure. */ - S32 parse(std::istream& istr, LLSD& data, S32 max_bytes, S32 max_depth = -1); + S32 parse(std::istream& istr, LLSD& data, llssize max_bytes, S32 max_depth = -1); /** Like parse(), but uses a different call (istream.getline()) to read by lines * This API is better suited for XML, where the parse cannot tell @@ -194,7 +194,7 @@ protected: * Conceptually const since it only modifies mutable members. * @param bytes The number of bytes read. */ - void account(S32 bytes) const; + void account(llssize bytes) const; protected: /** @@ -205,7 +205,7 @@ protected: /** * @brief The maximum number of bytes left to be parsed. */ - mutable S32 mMaxBytesLeft; + mutable llssize mMaxBytesLeft; /** * @brief Use line-based reading to get text @@ -336,7 +336,7 @@ private: class Impl; Impl& impl; - void parsePart(const char* buf, int len); + void parsePart(const char* buf, llssize len); friend class LLSDSerialize; }; @@ -756,7 +756,7 @@ public: * @param max_bytes the maximum number of bytes to parse * @return Returns true if the stream appears to contain valid data */ - static bool deserialize(LLSD& sd, std::istream& str, S32 max_bytes); + static bool deserialize(LLSD& sd, std::istream& str, llssize max_bytes); /* * Notation Methods @@ -778,12 +778,12 @@ public: LLSDFormatter::EFormatterOptions(LLSDFormatter::OPTIONS_PRETTY | LLSDFormatter::OPTIONS_PRETTY_BINARY)); } - static S32 fromNotation(LLSD& sd, std::istream& str, S32 max_bytes) + static S32 fromNotation(LLSD& sd, std::istream& str, llssize max_bytes) { LLPointer<LLSDNotationParser> p = new LLSDNotationParser; return p->parse(str, sd, max_bytes); } - static LLSD fromNotation(std::istream& str, S32 max_bytes) + static LLSD fromNotation(std::istream& str, llssize max_bytes) { LLPointer<LLSDNotationParser> p = new LLSDNotationParser; LLSD sd; @@ -834,12 +834,12 @@ public: LLPointer<LLSDBinaryFormatter> f = new LLSDBinaryFormatter; return f->format(sd, str, LLSDFormatter::OPTIONS_NONE); } - static S32 fromBinary(LLSD& sd, std::istream& str, S32 max_bytes, S32 max_depth = -1) + static S32 fromBinary(LLSD& sd, std::istream& str, llssize max_bytes, S32 max_depth = -1) { LLPointer<LLSDBinaryParser> p = new LLSDBinaryParser; return p->parse(str, sd, max_bytes, max_depth); } - static LLSD fromBinary(std::istream& str, S32 max_bytes, S32 max_depth = -1) + static LLSD fromBinary(std::istream& str, llssize max_bytes, S32 max_depth = -1) { LLPointer<LLSDBinaryParser> p = new LLSDBinaryParser; LLSD sd; @@ -867,5 +867,5 @@ public: LL_COMMON_API std::string zip_llsd(LLSD& data); -LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize,std::istream& is, S32 size); +LL_COMMON_API U8* unzip_llsdNavMesh( bool& valid, size_t& outsize,std::istream& is, S32 size); #endif // LL_LLSDSERIALIZE_H diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp index 0da824d694..ac128c9f86 100644 --- a/indra/llcommon/llsdserialize_xml.cpp +++ b/indra/llcommon/llsdserialize_xml.cpp @@ -196,12 +196,12 @@ S32 LLSDXMLFormatter::format_impl(const LLSD& data, std::ostream& ostr, // *FIX: memory inefficient. // *TODO: convert to use LLBase64 ostr << pre << "<binary encoding=\"base64\">"; - int b64_buffer_length = apr_base64_encode_len(buffer.size()); + int b64_buffer_length = apr_base64_encode_len(narrow(buffer.size())); char* b64_buffer = new char[b64_buffer_length]; b64_buffer_length = apr_base64_encode_binary( b64_buffer, &buffer[0], - buffer.size()); + narrow(buffer.size())); ostr.write(b64_buffer, b64_buffer_length - 1); delete[] b64_buffer; ostr << "</binary>" << post; @@ -260,7 +260,7 @@ public: S32 parse(std::istream& input, LLSD& data); S32 parseLines(std::istream& input, LLSD& data); - void parsePart(const char *buf, int len); + void parsePart(const char *buf, llssize len); void reset(); @@ -542,7 +542,7 @@ LLSDXMLParser::Impl::findAttribute(const XML_Char* name, const XML_Char** pairs) return NULL; } -void LLSDXMLParser::Impl::parsePart(const char* buf, int len) +void LLSDXMLParser::Impl::parsePart(const char* buf, llssize len) { if ( buf != NULL && len > 0 ) @@ -915,7 +915,7 @@ LLSDXMLParser::~LLSDXMLParser() delete &impl; } -void LLSDXMLParser::parsePart(const char *buf, int len) +void LLSDXMLParser::parsePart(const char *buf, llssize len) { impl.parsePart(buf, len); } diff --git a/indra/llcommon/llstreamtools.cpp b/indra/llcommon/llstreamtools.cpp index d7a6f47932..1ff15fcf89 100644 --- a/indra/llcommon/llstreamtools.cpp +++ b/indra/llcommon/llstreamtools.cpp @@ -118,7 +118,7 @@ bool skip_to_next_word(std::istream& input_stream) bool skip_to_end_of_next_keyword(const char* keyword, std::istream& input_stream) { - int key_length = strlen(keyword); /*Flawfinder: ignore*/ + auto key_length = strlen(keyword); /*Flawfinder: ignore*/ if (0 == key_length) { return false; @@ -315,7 +315,7 @@ bool unget_line(const std::string& line, std::istream& input_stream) // returns true if removed last char bool remove_last_char(char c, std::string& line) { - int line_size = line.size(); + auto line_size = line.size(); if (line_size > 1 && c == line[line_size - 1]) { @@ -330,9 +330,8 @@ bool remove_last_char(char c, std::string& line) // "\\n" ---> '\n' (backslash n becomes carriage return) void unescape_string(std::string& line) { - int line_size = line.size(); - int index = 0; - while (index < line_size - 1) + auto line_size = line.size(); + for (size_t index = 0; line_size >= 1 && index < line_size - 1; ++index) { if ('\\' == line[index]) { @@ -347,7 +346,6 @@ void unescape_string(std::string& line) line_size--; } } - index++; } } @@ -356,9 +354,8 @@ void unescape_string(std::string& line) // '\n' ---> "\\n" (carriage return becomes backslash n) void escape_string(std::string& line) { - int line_size = line.size(); - int index = 0; - while (index < line_size) + auto line_size = line.size(); + for (size_t index = 0; index < line_size; ++index) { if ('\\' == line[index]) { @@ -372,31 +369,27 @@ void escape_string(std::string& line) line_size++; index++; } - index++; } } // removes '\n' characters void replace_newlines_with_whitespace(std::string& line) { - int line_size = line.size(); - int index = 0; - while (index < line_size) + auto line_size = line.size(); + for (size_t index = 0; index < line_size; ++index) { if ('\n' == line[index]) { line.replace(index, 1, " "); } - index++; } } // erases any double-quote characters in 'line' void remove_double_quotes(std::string& line) { - int index = 0; - int line_size = line.size(); - while (index < line_size) + auto line_size = line.size(); + for (size_t index = 0; index < line_size; ) { if ('"' == line[index]) { @@ -424,22 +417,21 @@ void get_keyword_and_value(std::string& keyword, const std::string& line) { // skip initial whitespace - int line_size = line.size(); - int line_index = 0; + auto line_size = line.size(); + size_t line_index = 0; char c; - while (line_index < line_size) + for ( ; line_index < line_size; ++line_index) { c = line[line_index]; if (!LLStringOps::isSpace(c)) { break; } - line_index++; } // get the keyword keyword.clear(); - while (line_index < line_size) + for ( ; line_index < line_size; ++line_index) { c = line[line_index]; if (LLStringOps::isSpace(c) || '\r' == c || '\n' == c) @@ -447,7 +439,6 @@ void get_keyword_and_value(std::string& keyword, break; } keyword += c; - line_index++; } // get the value @@ -465,7 +456,7 @@ void get_keyword_and_value(std::string& keyword, line_index++; } - while (line_index < line_size) + for ( ; line_index < line_size; ++line_index) { c = line[line_index]; if ('\r' == c || '\n' == c) @@ -473,7 +464,6 @@ void get_keyword_and_value(std::string& keyword, break; } value += c; - line_index++; } } } diff --git a/indra/llcommon/llstring.cpp b/indra/llcommon/llstring.cpp index 7f501f2e77..f6629803ee 100644 --- a/indra/llcommon/llstring.cpp +++ b/indra/llcommon/llstring.cpp @@ -141,7 +141,7 @@ std::string rawstr_to_utf8(const std::string& raw) return wstring_to_utf8str(wstr); } -S32 wchar_to_utf8chars(llwchar in_char, char* outchars) +std::ptrdiff_t wchar_to_utf8chars(llwchar in_char, char* outchars) { U32 cur_char = (U32)in_char; char* base = outchars; @@ -192,7 +192,7 @@ S32 wchar_to_utf8chars(llwchar in_char, char* outchars) return outchars - base; } -S32 utf16chars_to_wchar(const U16* inchars, llwchar* outchar) +auto utf16chars_to_wchar(const U16* inchars, llwchar* outchar) { const U16* base = inchars; U16 cur_char = *inchars++; @@ -310,7 +310,7 @@ S32 wstring_utf16_length(const LLWString &wstr, const S32 woffset, const S32 wle // and whose equivalent utf-16 string does not exceeds the given utf16_length. S32 wstring_wstring_length_from_utf16_length(const LLWString & wstr, const S32 woffset, const S32 utf16_length, BOOL *unaligned) { - const S32 end = wstr.length(); + const auto end = wstr.length(); BOOL u = FALSE; S32 n = woffset + utf16_length; S32 i = woffset; @@ -426,7 +426,7 @@ LLWString utf8str_to_wstring(const char* utf8str, size_t len) } // Check that this character doesn't go past the end of the string - S32 end = (len < (i + cont_bytes)) ? len : (i + cont_bytes); + auto end = (len < (i + cont_bytes)) ? len : (i + cont_bytes); do { ++i; @@ -471,7 +471,7 @@ std::string wstring_to_utf8str(const llwchar* utf32str, size_t len) while (i < len) { char tchars[8]; /* Flawfinder: ignore */ - S32 n = wchar_to_utf8chars(utf32str[i], tchars); + auto n = wchar_to_utf8chars(utf32str[i], tchars); tchars[n] = 0; out += tchars; i++; diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h index d94f549480..1fd6cac14a 100644 --- a/indra/llcommon/llstring.h +++ b/indra/llcommon/llstring.h @@ -664,7 +664,7 @@ ll_convert_forms(ll_convert_alias, LLWString, std::string, utf8str_to_ // Same function, better name. JC inline LLWString utf8string_to_wstring(const std::string& utf8_string) { return utf8str_to_wstring(utf8_string); } -LL_COMMON_API S32 wchar_to_utf8chars(llwchar inchar, char* outchars); +LL_COMMON_API std::ptrdiff_t wchar_to_utf8chars(llwchar inchar, char* outchars); ll_convert_forms(ll_convert_alias, std::string, LLWString, wstring_to_utf8str); ll_convert_forms(ll_convert_u16_alias, std::string, llutf16string, utf16str_to_utf8str); diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp index a8b5c7b3a8..91cb65b815 100644 --- a/indra/llcommon/llsys.cpp +++ b/indra/llcommon/llsys.cpp @@ -273,7 +273,7 @@ LLOSInfo::LLOSInfo() : { const char * DARWIN_PRODUCT_NAME = "Mac OS X"; - S32 major_version, minor_version, bugfix_version = 0; + int64_t major_version, minor_version, bugfix_version = 0; if (LLGetDarwinOSInfo(major_version, minor_version, bugfix_version)) { @@ -454,14 +454,14 @@ LLOSInfo::LLOSInfo() : #ifndef LL_WINDOWS // static -S32 LLOSInfo::getMaxOpenFiles() +long LLOSInfo::getMaxOpenFiles() { - const S32 OPEN_MAX_GUESS = 256; + const long OPEN_MAX_GUESS = 256; #ifdef OPEN_MAX - static S32 open_max = OPEN_MAX; + static long open_max = OPEN_MAX; #else - static S32 open_max = 0; + static long open_max = 0; #endif if (0 == open_max) @@ -909,7 +909,7 @@ void LLMemoryInfo::stream(std::ostream& s) const // Now stream stats BOOST_FOREACH(const MapEntry& pair, inMap(mStatsMap)) { - s << pfx << std::setw(key_width+1) << (pair.first + ':') << ' '; + s << pfx << std::setw(narrow(key_width+1)) << (pair.first + ':') << ' '; LLSD value(pair.second); if (value.isInteger()) s << std::setw(12) << value.asInteger(); @@ -1280,7 +1280,7 @@ public: << " seconds "; } - S32 precision = LL_CONT.precision(); + auto precision = LL_CONT.precision(); LL_CONT << std::fixed << std::setprecision(1) << framerate << '\n' << LLMemoryInfo(); diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h index 5ffbf5a732..70a03810c5 100644 --- a/indra/llcommon/llsys.h +++ b/indra/llcommon/llsys.h @@ -59,7 +59,7 @@ public: S32 mBuild; #ifndef LL_WINDOWS - static S32 getMaxOpenFiles(); + static long getMaxOpenFiles(); #endif static bool is64Bit(); diff --git a/indra/llcommon/llsys_objc.h b/indra/llcommon/llsys_objc.h index 35599a574b..b48ff97bdb 100644 --- a/indra/llcommon/llsys_objc.h +++ b/indra/llcommon/llsys_objc.h @@ -27,7 +27,11 @@ #ifndef LL_LLSYS_OBJC_H #define LL_LLSYS_OBJC_H -bool LLGetDarwinOSInfo(int &major, int &minor, int &patch); +#include <cstdint> + +// C++ land doesn't define NSInteger, and we don't want to introduce that for +// this one case, so use int64_t instead (which is equivalent). +bool LLGetDarwinOSInfo(int64_t &major, int64_t &minor, int64_t &patch); #endif // LL_LLSYS_OBJC_H diff --git a/indra/llcommon/llsys_objc.mm b/indra/llcommon/llsys_objc.mm index cdb1e320d5..3fd85fb1c9 100644 --- a/indra/llcommon/llsys_objc.mm +++ b/indra/llcommon/llsys_objc.mm @@ -27,12 +27,12 @@ #import "llsys_objc.h" #import <AppKit/AppKit.h> -static int intAtStringIndex(NSArray *array, int index) +static auto intAtStringIndex(NSArray *array, int index) { return [(NSString *)[array objectAtIndex:index] integerValue]; } -bool LLGetDarwinOSInfo(int &major, int &minor, int &patch) +bool LLGetDarwinOSInfo(int64_t &major, int64_t &minor, int64_t &patch) { if (NSAppKitVersionNumber > NSAppKitVersionNumber10_8) { diff --git a/indra/llcommon/llthreadlocalstorage.cpp b/indra/llcommon/llthreadlocalstorage.cpp deleted file mode 100644 index d8a063e8d5..0000000000 --- a/indra/llcommon/llthreadlocalstorage.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file llthreadlocalstorage.cpp - * @author Richard - * @date 2013-1-11 - * @brief implementation of thread local storage utility classes - * - * $LicenseInfo:firstyear=2013&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "linden_common.h" -#include "llthreadlocalstorage.h" -#include "llapr.h" - -// -//LLThreadLocalPointerBase -// -bool LLThreadLocalPointerBase::sInitialized = false; - -void LLThreadLocalPointerBase::set( void* value ) -{ - llassert(sInitialized && mThreadKey); - - apr_status_t result = apr_threadkey_private_set((void*)value, mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to set thread local data" << LL_ENDL; - } -} - -void* LLThreadLocalPointerBase::get() const -{ - // llassert(sInitialized); - void* ptr; - apr_status_t result = - apr_threadkey_private_get(&ptr, mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to get thread local data" << LL_ENDL; - } - return ptr; -} - - -void LLThreadLocalPointerBase::initStorage( ) -{ - apr_status_t result = apr_threadkey_private_create(&mThreadKey, NULL, gAPRPoolp); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to allocate thread local data" << LL_ENDL; - } -} - -void LLThreadLocalPointerBase::destroyStorage() -{ - if (sInitialized) - { - if (mThreadKey) - { - apr_status_t result = apr_threadkey_private_delete(mThreadKey); - if (result != APR_SUCCESS) - { - ll_apr_warn_status(result); - LL_ERRS() << "Failed to delete thread local data" << LL_ENDL; - } - } - } -} - -//static -void LLThreadLocalPointerBase::initAllThreadLocalStorage() -{ - if (!sInitialized) - { - for (auto& base : instance_snapshot()) - { - base.initStorage(); - } - sInitialized = true; - } -} - -//static -void LLThreadLocalPointerBase::destroyAllThreadLocalStorage() -{ - if (sInitialized) - { - //for (auto& base : instance_snapshot()) - //{ - // base.destroyStorage(); - //} - sInitialized = false; - } -} diff --git a/indra/llcommon/llthreadlocalstorage.h b/indra/llcommon/llthreadlocalstorage.h index 3b5786023f..bdd28ec865 100644 --- a/indra/llcommon/llthreadlocalstorage.h +++ b/indra/llcommon/llthreadlocalstorage.h @@ -30,100 +30,6 @@ #include "llinstancetracker.h" -class LLThreadLocalPointerBase : public LLInstanceTracker<LLThreadLocalPointerBase> -{ -public: - LLThreadLocalPointerBase() - : mThreadKey(NULL) - { - if (sInitialized) - { - initStorage(); - } - } - - LLThreadLocalPointerBase( const LLThreadLocalPointerBase& other) - : mThreadKey(NULL) - { - if (sInitialized) - { - initStorage(); - } - } - - ~LLThreadLocalPointerBase() - { - destroyStorage(); - } - - static void initAllThreadLocalStorage(); - static void destroyAllThreadLocalStorage(); - -protected: - void set(void* value); - - void* get() const; - - void initStorage(); - void destroyStorage(); - -protected: - struct apr_threadkey_t* mThreadKey; - static bool sInitialized; -}; - -template <typename T> -class LLThreadLocalPointer : public LLThreadLocalPointerBase -{ -public: - - LLThreadLocalPointer() - {} - - explicit LLThreadLocalPointer(T* value) - { - set(value); - } - - - LLThreadLocalPointer(const LLThreadLocalPointer<T>& other) - : LLThreadLocalPointerBase(other) - { - set(other.get()); - } - - LL_FORCE_INLINE T* get() const - { - return (T*)LLThreadLocalPointerBase::get(); - } - - T* operator -> () const - { - return (T*)get(); - } - - T& operator*() const - { - return *(T*)get(); - } - - LLThreadLocalPointer<T>& operator = (T* value) - { - set((void*)value); - return *this; - } - - bool operator ==(const T* other) const - { - if (!sInitialized) return false; - return get() == other; - } - - bool isNull() const { return !sInitialized || get() == NULL; } - - bool notNull() const { return sInitialized && get() != NULL; } -}; - template<typename DERIVED_TYPE> class LLThreadLocalSingletonPointer { @@ -139,10 +45,10 @@ public: } private: - static LL_THREAD_LOCAL DERIVED_TYPE* sInstance; + static thread_local DERIVED_TYPE* sInstance; }; template<typename DERIVED_TYPE> -LL_THREAD_LOCAL DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL; +thread_local DERIVED_TYPE* LLThreadLocalSingletonPointer<DERIVED_TYPE>::sInstance = NULL; #endif // LL_LLTHREADLOCALSTORAGE_H diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h index 68d79cdd12..f396a71e6f 100644 --- a/indra/llcommon/llthreadsafequeue.h +++ b/indra/llcommon/llthreadsafequeue.h @@ -82,7 +82,7 @@ public: // Limiting the number of pending items prevents unbounded growth of the // underlying queue. - LLThreadSafeQueue(U32 capacity = 1024); + LLThreadSafeQueue(size_t capacity = 1024); virtual ~LLThreadSafeQueue() {} // Add an element to the queue (will block if the queue has reached @@ -179,7 +179,7 @@ public: protected: typedef QueueT queue_type; QueueT mStorage; - U32 mCapacity; + size_t mCapacity; bool mClosed; boost::fibers::timed_mutex mLock; @@ -262,7 +262,7 @@ namespace LL * LLThreadSafeQueue implementation *****************************************************************************/ template<typename ElementT, typename QueueT> -LLThreadSafeQueue<ElementT, QueueT>::LLThreadSafeQueue(U32 capacity) : +LLThreadSafeQueue<ElementT, QueueT>::LLThreadSafeQueue(size_t capacity) : mCapacity(capacity), mClosed(false) { diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp index aaa6df325c..74ec62d347 100644 --- a/indra/llcommon/lltimer.cpp +++ b/indra/llcommon/lltimer.cpp @@ -123,7 +123,7 @@ U32 micro_sleep(U64 us, U32 max_yields) // interrupts at 250 Hz (every 4,000 microseconds). const U64 KERNEL_SLEEP_INTERVAL_US = 4000; - S32 num_sleep_intervals = (us - (KERNEL_SLEEP_INTERVAL_US >> 1)) / KERNEL_SLEEP_INTERVAL_US; + auto num_sleep_intervals = (us - (KERNEL_SLEEP_INTERVAL_US >> 1)) / KERNEL_SLEEP_INTERVAL_US; if (num_sleep_intervals > 0) { U64 sleep_time = (num_sleep_intervals * KERNEL_SLEEP_INTERVAL_US) - (KERNEL_SLEEP_INTERVAL_US >> 1); diff --git a/indra/llcommon/lltrace.cpp b/indra/llcommon/lltrace.cpp index f59b207ded..ff671a8370 100644 --- a/indra/llcommon/lltrace.cpp +++ b/indra/llcommon/lltrace.cpp @@ -40,7 +40,7 @@ StatBase::StatBase( const char* name, const char* description ) mDescription(description ? description : "") { #ifndef LL_RELEASE_FOR_DOWNLOAD - if (LLTrace::get_thread_recorder().notNull()) + if (LLTrace::get_thread_recorder() != NULL) { LL_ERRS() << "Attempting to declare trace object after program initialization. Trace objects should be statically initialized." << LL_ENDL; } @@ -65,7 +65,7 @@ void TimeBlockTreeNode::setParent( BlockTimerStatHandle* parent ) llassert_always(parent != mBlock); llassert_always(parent != NULL); - TimeBlockTreeNode* parent_tree_node = get_thread_recorder()->getTimeBlockTreeNode(parent->getIndex()); + TimeBlockTreeNode* parent_tree_node = get_thread_recorder()->getTimeBlockTreeNode(narrow(parent->getIndex())); if (!parent_tree_node) return; if (mParent) diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h index fcd8753f75..580cf0a5fd 100644 --- a/indra/llcommon/lltrace.h +++ b/indra/llcommon/lltrace.h @@ -340,7 +340,7 @@ inline void claim_alloc(MemStatHandle& measurement, const T& value) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; #if LL_TRACE_ENABLED - S32 size = MeasureMem<T>::measureFootprint(value); + auto size = MeasureMem<T>::measureFootprint(value); if(size == 0) return; MemAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() + (F64)size : (F64)size); @@ -353,7 +353,7 @@ inline void disclaim_alloc(MemStatHandle& measurement, const T& value) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; #if LL_TRACE_ENABLED - S32 size = MeasureMem<T>::measureFootprint(value); + auto size = MeasureMem<T>::measureFootprint(value); if(size == 0) return; MemAccumulator& accumulator = measurement.getCurrentAccumulator(); accumulator.mSize.sample(accumulator.mSize.hasValue() ? accumulator.mSize.getLastValue() - (F64)size : -(F64)size); diff --git a/indra/llcommon/lltraceaccumulators.cpp b/indra/llcommon/lltraceaccumulators.cpp index 34299f5a29..6bd886ae98 100644 --- a/indra/llcommon/lltraceaccumulators.cpp +++ b/indra/llcommon/lltraceaccumulators.cpp @@ -93,12 +93,12 @@ void AccumulatorBufferGroup::makeCurrent() mStackTimers.makeCurrent(); mMemStats.makeCurrent(); - ThreadRecorder* thread_recorder = get_thread_recorder().get(); + ThreadRecorder* thread_recorder = get_thread_recorder(); AccumulatorBuffer<TimeBlockAccumulator>& timer_accumulator_buffer = mStackTimers; // update stacktimer parent pointers - for (S32 i = 0, end_i = mStackTimers.size(); i < end_i; i++) + for (size_t i = 0, end_i = mStackTimers.size(); i < end_i; i++) { - TimeBlockTreeNode* tree_node = thread_recorder->getTimeBlockTreeNode(i); + TimeBlockTreeNode* tree_node = thread_recorder->getTimeBlockTreeNode(narrow(i)); if (tree_node) { timer_accumulator_buffer[i].mParent = tree_node->mParent; diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp index 1613af1dcf..dd148dd08a 100644 --- a/indra/llcommon/lltracerecording.cpp +++ b/indra/llcommon/lltracerecording.cpp @@ -95,7 +95,7 @@ Recording::~Recording() // allow recording destruction without thread recorder running, // otherwise thread shutdown could crash if a recording outlives the thread recorder // besides, recording construction and destruction is fine without a recorder...just don't attempt to start one - if (isStarted() && LLTrace::get_thread_recorder().notNull()) + if (isStarted() && LLTrace::get_thread_recorder() != NULL) { LLTrace::get_thread_recorder()->deactivate(mBuffers.write()); } @@ -112,9 +112,9 @@ void Recording::update() // must have llassert(mActiveBuffers != NULL - && LLTrace::get_thread_recorder().notNull()); + && LLTrace::get_thread_recorder() != NULL); - if(!mActiveBuffers->isCurrent()) + if(!mActiveBuffers->isCurrent() && LLTrace::get_thread_recorder() != NULL) { AccumulatorBufferGroup* buffers = mBuffers.write(); LLTrace::get_thread_recorder()->deactivate(buffers); @@ -144,7 +144,7 @@ void Recording::handleStart() mSamplingTimer.reset(); mBuffers.setStayUnique(true); // must have thread recorder running on this thread - llassert(LLTrace::get_thread_recorder().notNull()); + llassert(LLTrace::get_thread_recorder() != NULL); mActiveBuffers = LLTrace::get_thread_recorder()->activate(mBuffers.write()); #endif } @@ -155,7 +155,7 @@ void Recording::handleStop() #if LL_TRACE_ENABLED mElapsedSeconds += mSamplingTimer.getElapsedTimeF64(); // must have thread recorder running on this thread - llassert(LLTrace::get_thread_recorder().notNull()); + llassert(LLTrace::get_thread_recorder() != NULL); LLTrace::get_thread_recorder()->deactivate(mBuffers.write()); mActiveBuffers = NULL; mBuffers.setStayUnique(false); @@ -606,7 +606,8 @@ void PeriodicRecording::nextPeriod() mCurPeriod = (mCurPeriod + 1) % mRecordingPeriods.size(); old_recording.splitTo(getCurRecording()); - mNumRecordedPeriods = llmin((S32)mRecordingPeriods.size() - 1, mNumRecordedPeriods + 1); + mNumRecordedPeriods = mRecordingPeriods.empty()? 0 : + llmin(mRecordingPeriods.size() - 1, mNumRecordedPeriods + 1); } void PeriodicRecording::appendRecording(Recording& recording) @@ -625,21 +626,21 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) getCurRecording().update(); other.getCurRecording().update(); - const S32 other_recording_slots = other.mRecordingPeriods.size(); - const S32 other_num_recordings = other.getNumRecordedPeriods(); - const S32 other_current_recording_index = other.mCurPeriod; - const S32 other_oldest_recording_index = (other_current_recording_index + other_recording_slots - other_num_recordings) % other_recording_slots; + const auto other_recording_slots = other.mRecordingPeriods.size(); + const auto other_num_recordings = other.getNumRecordedPeriods(); + const auto other_current_recording_index = other.mCurPeriod; + const auto other_oldest_recording_index = (other_current_recording_index + other_recording_slots - other_num_recordings) % other_recording_slots; // append first recording into our current slot getCurRecording().appendRecording(other.mRecordingPeriods[other_oldest_recording_index]); // from now on, add new recordings for everything after the first - S32 other_index = (other_oldest_recording_index + 1) % other_recording_slots; + auto other_index = (other_oldest_recording_index + 1) % other_recording_slots; if (mAutoResize) { // push back recordings for everything in the middle - S32 other_index = (other_oldest_recording_index + 1) % other_recording_slots; + auto other_index = (other_oldest_recording_index + 1) % other_recording_slots; while (other_index != other_current_recording_index) { mRecordingPeriods.push_back(other.mRecordingPeriods[other_index]); @@ -652,8 +653,8 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) mRecordingPeriods.push_back(other.mRecordingPeriods[other_current_recording_index]); } - mCurPeriod = mRecordingPeriods.size() - 1; - mNumRecordedPeriods = mRecordingPeriods.size() - 1; + mCurPeriod = mRecordingPeriods.empty()? 0 : mRecordingPeriods.size() - 1; + mNumRecordedPeriods = mCurPeriod; } else { @@ -682,7 +683,7 @@ void PeriodicRecording::appendPeriodicRecording( PeriodicRecording& other ) llassert(num_to_copy >= 1); // advance to last recording period copied, and make that our current period mCurPeriod = (mCurPeriod + num_to_copy - 1) % mRecordingPeriods.size(); - mNumRecordedPeriods = llmin((S32)mRecordingPeriods.size() - 1, mNumRecordedPeriods + num_to_copy - 1); + mNumRecordedPeriods = llmin(mRecordingPeriods.size() - 1, mNumRecordedPeriods + num_to_copy - 1); } // end with fresh period, otherwise next appendPeriodicRecording() will merge the first @@ -695,10 +696,10 @@ F64Seconds PeriodicRecording::getDuration() const { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; F64Seconds duration; - S32 num_periods = mRecordingPeriods.size(); - for (S32 i = 1; i <= num_periods; i++) + auto num_periods = mRecordingPeriods.size(); + for (size_t i = 1; i <= num_periods; i++) { - S32 index = (mCurPeriod + num_periods - i) % num_periods; + auto index = (mCurPeriod + num_periods - i) % num_periods; duration += mRecordingPeriods[index].getDuration(); } return duration; @@ -734,16 +735,16 @@ const Recording& PeriodicRecording::getCurRecording() const return mRecordingPeriods[mCurPeriod]; } -Recording& PeriodicRecording::getPrevRecording( S32 offset ) +Recording& PeriodicRecording::getPrevRecording( size_t offset ) { - S32 num_periods = mRecordingPeriods.size(); + auto num_periods = mRecordingPeriods.size(); offset = llclamp(offset, 0, num_periods - 1); return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods]; } -const Recording& PeriodicRecording::getPrevRecording( S32 offset ) const +const Recording& PeriodicRecording::getPrevRecording( size_t offset ) const { - S32 num_periods = mRecordingPeriods.size(); + auto num_periods = mRecordingPeriods.size(); offset = llclamp(offset, 0, num_periods - 1); return mRecordingPeriods[(mCurPeriod + num_periods - offset) % num_periods]; } @@ -790,7 +791,7 @@ void PeriodicRecording::handleSplitTo(PeriodicRecording& other) getCurRecording().splitTo(other.getCurRecording()); } -F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -812,7 +813,7 @@ F64 PeriodicRecording::getPeriodMin( const StatType<EventAccumulator>& stat, S32 : NaN; } -F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -835,7 +836,7 @@ F64 PeriodicRecording::getPeriodMax( const StatType<EventAccumulator>& stat, S32 } // calculates means using aggregates per period -F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -858,7 +859,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<EventAccumulator>& stat, S3 : NaN; } -F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -883,7 +884,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<EventAccumulat : NaN; } -F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -905,7 +906,7 @@ F64 PeriodicRecording::getPeriodMin( const StatType<SampleAccumulator>& stat, S3 : NaN; } -F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/) +F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -928,7 +929,7 @@ F64 PeriodicRecording::getPeriodMax(const StatType<SampleAccumulator>& stat, S32 } -F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -951,7 +952,7 @@ F64 PeriodicRecording::getPeriodMean( const StatType<SampleAccumulator>& stat, S : NaN; } -F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -977,7 +978,7 @@ F64 PeriodicRecording::getPeriodMedian( const StatType<SampleAccumulator>& stat, return F64((buf.size() % 2 == 0) ? (buf[buf.size() / 2 - 1] + buf[buf.size() / 2]) / 2 : buf[buf.size() / 2]); } -F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -1003,7 +1004,7 @@ F64 PeriodicRecording::getPeriodStandardDeviation( const StatType<SampleAccumula } -F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -1018,12 +1019,12 @@ F64Kilobytes PeriodicRecording::getPeriodMin( const StatType<MemAccumulator>& st return min_val; } -F64Kilobytes PeriodicRecording::getPeriodMin(const MemStatHandle& stat, S32 num_periods) +F64Kilobytes PeriodicRecording::getPeriodMin(const MemStatHandle& stat, size_t num_periods) { return getPeriodMin(static_cast<const StatType<MemAccumulator>&>(stat), num_periods); } -F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/) +F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -1038,12 +1039,12 @@ F64Kilobytes PeriodicRecording::getPeriodMax(const StatType<MemAccumulator>& sta return max_val; } -F64Kilobytes PeriodicRecording::getPeriodMax(const MemStatHandle& stat, S32 num_periods) +F64Kilobytes PeriodicRecording::getPeriodMax(const MemStatHandle& stat, size_t num_periods) { return getPeriodMax(static_cast<const StatType<MemAccumulator>&>(stat), num_periods); } -F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -1059,12 +1060,12 @@ F64Kilobytes PeriodicRecording::getPeriodMean( const StatType<MemAccumulator>& s return mean / F64(num_periods); } -F64Kilobytes PeriodicRecording::getPeriodMean(const MemStatHandle& stat, S32 num_periods) +F64Kilobytes PeriodicRecording::getPeriodMean(const MemStatHandle& stat, size_t num_periods) { return getPeriodMean(static_cast<const StatType<MemAccumulator>&>(stat), num_periods); } -F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, S32 num_periods /*= S32_MAX*/ ) +F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAccumulator>& stat, size_t num_periods /*= S32_MAX*/ ) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -1089,7 +1090,7 @@ F64Kilobytes PeriodicRecording::getPeriodStandardDeviation( const StatType<MemAc : NaN); } -F64Kilobytes PeriodicRecording::getPeriodStandardDeviation(const MemStatHandle& stat, S32 num_periods) +F64Kilobytes PeriodicRecording::getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods) { return getPeriodStandardDeviation(static_cast<const StatType<MemAccumulator>&>(stat), num_periods); } @@ -1181,8 +1182,8 @@ void ExtendablePeriodicRecording::handleSplitTo(ExtendablePeriodicRecording& oth PeriodicRecording& get_frame_recording() { - static LLThreadLocalPointer<PeriodicRecording> sRecording(new PeriodicRecording(200, PeriodicRecording::STARTED)); - return *sRecording; + static thread_local PeriodicRecording sRecording(200, PeriodicRecording::STARTED); + return sRecording; } } diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h index 556b7470cf..8b56721f42 100644 --- a/indra/llcommon/lltracerecording.h +++ b/indra/llcommon/lltracerecording.h @@ -334,7 +334,7 @@ namespace LLTrace ~PeriodicRecording(); void nextPeriod(); - S32 getNumRecordedPeriods() + auto getNumRecordedPeriods() { // current period counts if not active return mNumRecordedPeriods + (isStarted() ? 0 : 1); @@ -348,24 +348,24 @@ namespace LLTrace const Recording& getLastRecording() const; Recording& getCurRecording(); const Recording& getCurRecording() const; - Recording& getPrevRecording(S32 offset); - const Recording& getPrevRecording(S32 offset) const; + Recording& getPrevRecording(size_t offset); + const Recording& getPrevRecording(size_t offset) const; Recording snapshotCurRecording() const; template <typename T> - S32 getSampleCount(const StatType<T>& stat, S32 num_periods = S32_MAX) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; + auto getSampleCount(const StatType<T>& stat, size_t num_periods = S32_MAX) + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); - S32 num_samples = 0; - for (S32 i = 1; i <= num_periods; i++) + size_t num_samples = 0; + for (size_t i = 1; i <= num_periods; i++) { Recording& recording = getPrevRecording(i); num_samples += recording.getSampleCount(stat); } return num_samples; - } + } // // PERIODIC MIN @@ -373,7 +373,7 @@ namespace LLTrace // catch all for stats that have a defined sum template <typename T> - typename T::value_t getPeriodMin(const StatType<T>& stat, S32 num_periods = S32_MAX) + typename T::value_t getPeriodMin(const StatType<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -396,33 +396,33 @@ namespace LLTrace } template<typename T> - T getPeriodMin(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) + T getPeriodMin(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMin(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } - F64 getPeriodMin(const StatType<SampleAccumulator>& stat, S32 num_periods = S32_MAX); + F64 getPeriodMin(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); template<typename T> - T getPeriodMin(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX) + T getPeriodMin(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMin(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } - F64 getPeriodMin(const StatType<EventAccumulator>& stat, S32 num_periods = S32_MAX); + F64 getPeriodMin(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX); template<typename T> - T getPeriodMin(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX) + T getPeriodMin(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMin(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } - F64Kilobytes getPeriodMin(const StatType<MemAccumulator>& stat, S32 num_periods = S32_MAX); - F64Kilobytes getPeriodMin(const MemStatHandle& stat, S32 num_periods = S32_MAX); + F64Kilobytes getPeriodMin(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX); + F64Kilobytes getPeriodMin(const MemStatHandle& stat, size_t num_periods = S32_MAX); template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMinPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -437,7 +437,7 @@ namespace LLTrace } template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMinPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMinPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); @@ -449,7 +449,7 @@ namespace LLTrace // catch all for stats that have a defined sum template <typename T> - typename T::value_t getPeriodMax(const StatType<T>& stat, S32 num_periods = S32_MAX) + typename T::value_t getPeriodMax(const StatType<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -472,33 +472,33 @@ namespace LLTrace } template<typename T> - T getPeriodMax(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) + T getPeriodMax(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMax(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } - F64 getPeriodMax(const StatType<SampleAccumulator>& stat, S32 num_periods = S32_MAX); + F64 getPeriodMax(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); template<typename T> - T getPeriodMax(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX) + T getPeriodMax(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMax(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } - F64 getPeriodMax(const StatType<EventAccumulator>& stat, S32 num_periods = S32_MAX); + F64 getPeriodMax(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX); template<typename T> - T getPeriodMax(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX) + T getPeriodMax(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return T(getPeriodMax(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } - F64Kilobytes getPeriodMax(const StatType<MemAccumulator>& stat, S32 num_periods = S32_MAX); - F64Kilobytes getPeriodMax(const MemStatHandle& stat, S32 num_periods = S32_MAX); + F64Kilobytes getPeriodMax(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX); + F64Kilobytes getPeriodMax(const MemStatHandle& stat, size_t num_periods = S32_MAX); template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMaxPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -513,7 +513,7 @@ namespace LLTrace } template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMaxPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMaxPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); @@ -525,7 +525,7 @@ namespace LLTrace // catch all for stats that have a defined sum template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMean(const StatType<T >& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -546,32 +546,32 @@ namespace LLTrace } template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMean(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } - F64 getPeriodMean(const StatType<SampleAccumulator>& stat, S32 num_periods = S32_MAX); + F64 getPeriodMean(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMean(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } - F64 getPeriodMean(const StatType<EventAccumulator>& stat, S32 num_periods = S32_MAX); + F64 getPeriodMean(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX); template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMean(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMean(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } - F64Kilobytes getPeriodMean(const StatType<MemAccumulator>& stat, S32 num_periods = S32_MAX); - F64Kilobytes getPeriodMean(const MemStatHandle& stat, S32 num_periods = S32_MAX); + F64Kilobytes getPeriodMean(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX); + F64Kilobytes getPeriodMean(const MemStatHandle& stat, size_t num_periods = S32_MAX); template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMeanPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -593,16 +593,16 @@ namespace LLTrace } template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMeanPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMeanPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); } - F64 getPeriodMedian( const StatType<SampleAccumulator>& stat, S32 num_periods = S32_MAX); + F64 getPeriodMedian( const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); template <typename T> - typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMedianPerSec(const StatType<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<typename T::value_t>::fractional_t getPeriodMedianPerSec(const StatType<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; num_periods = llmin(num_periods, getNumRecordedPeriods()); @@ -622,7 +622,7 @@ namespace LLTrace } template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodMedianPerSec(const CountStatHandle<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodMedianPerSec(const CountStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodMedianPerSec(static_cast<const StatType<CountAccumulator>&>(stat), num_periods)); @@ -632,25 +632,25 @@ namespace LLTrace // PERIODIC STANDARD DEVIATION // - F64 getPeriodStandardDeviation(const StatType<SampleAccumulator>& stat, S32 num_periods = S32_MAX); + F64 getPeriodStandardDeviation(const StatType<SampleAccumulator>& stat, size_t num_periods = S32_MAX); template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const SampleStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<SampleAccumulator>&>(stat), num_periods)); } - F64 getPeriodStandardDeviation(const StatType<EventAccumulator>& stat, S32 num_periods = S32_MAX); + F64 getPeriodStandardDeviation(const StatType<EventAccumulator>& stat, size_t num_periods = S32_MAX); template<typename T> - typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, S32 num_periods = S32_MAX) + typename RelatedTypes<T>::fractional_t getPeriodStandardDeviation(const EventStatHandle<T>& stat, size_t num_periods = S32_MAX) { LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS; return typename RelatedTypes<T>::fractional_t(getPeriodStandardDeviation(static_cast<const StatType<EventAccumulator>&>(stat), num_periods)); } - F64Kilobytes getPeriodStandardDeviation(const StatType<MemAccumulator>& stat, S32 num_periods = S32_MAX); - F64Kilobytes getPeriodStandardDeviation(const MemStatHandle& stat, S32 num_periods = S32_MAX); + F64Kilobytes getPeriodStandardDeviation(const StatType<MemAccumulator>& stat, size_t num_periods = S32_MAX); + F64Kilobytes getPeriodStandardDeviation(const MemStatHandle& stat, size_t num_periods = S32_MAX); private: // implementation for LLStopWatchControlsMixin @@ -662,8 +662,8 @@ namespace LLTrace private: std::vector<Recording> mRecordingPeriods; const bool mAutoResize; - S32 mCurPeriod; - S32 mNumRecordedPeriods; + size_t mCurPeriod; + size_t mNumRecordedPeriods; }; PeriodicRecording& get_frame_recording(); diff --git a/indra/llcommon/lltracethreadrecorder.cpp b/indra/llcommon/lltracethreadrecorder.cpp index 090d3297a0..4028a5ce97 100644 --- a/indra/llcommon/lltracethreadrecorder.cpp +++ b/indra/llcommon/lltracethreadrecorder.cpp @@ -125,7 +125,7 @@ ThreadRecorder::~ThreadRecorder() #endif } -TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode( S32 index ) +TimeBlockTreeNode* ThreadRecorder::getTimeBlockTreeNode( size_t index ) { #if LL_TRACE_ENABLED if (0 <= index && index < mNumTimeBlockTreeNodes) @@ -308,13 +308,13 @@ ThreadRecorder* get_master_thread_recorder() return sMasterThreadRecorder; } -LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder_ptr() +ThreadRecorder*& get_thread_recorder_ptr() { - static LLThreadLocalPointer<ThreadRecorder> s_thread_recorder; + static thread_local ThreadRecorder* s_thread_recorder; return s_thread_recorder; } -const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder() +ThreadRecorder* get_thread_recorder() { return get_thread_recorder_ptr(); } diff --git a/indra/llcommon/lltracethreadrecorder.h b/indra/llcommon/lltracethreadrecorder.h index a797c6687e..8ee6729ac6 100644 --- a/indra/llcommon/lltracethreadrecorder.h +++ b/indra/llcommon/lltracethreadrecorder.h @@ -32,7 +32,6 @@ #include "llmutex.h" #include "lltraceaccumulators.h" -#include "llthreadlocalstorage.h" namespace LLTrace { @@ -58,7 +57,7 @@ namespace LLTrace void pullFromChildren(); void pushToParent(); - TimeBlockTreeNode* getTimeBlockTreeNode(S32 index); + TimeBlockTreeNode* getTimeBlockTreeNode(size_t index); protected: void init(); @@ -92,7 +91,7 @@ namespace LLTrace }; - const LLThreadLocalPointer<ThreadRecorder>& get_thread_recorder(); + ThreadRecorder* get_thread_recorder(); void set_thread_recorder(ThreadRecorder*); void set_master_thread_recorder(ThreadRecorder*); diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp index 4b91b2caca..97838e296e 100644 --- a/indra/llcommon/llworkerthread.cpp +++ b/indra/llcommon/llworkerthread.cpp @@ -81,9 +81,9 @@ void LLWorkerThread::clearDeleteList() } // virtual -S32 LLWorkerThread::update(F32 max_time_ms) +size_t LLWorkerThread::update(F32 max_time_ms) { - S32 res = LLQueuedThread::update(max_time_ms); + auto res = LLQueuedThread::update(max_time_ms); // Delete scheduled workers std::vector<LLWorkerClass*> delete_list; std::vector<LLWorkerClass*> abort_list; diff --git a/indra/llcommon/llworkerthread.h b/indra/llcommon/llworkerthread.h index 0387e75c65..e3004d7242 100644 --- a/indra/llcommon/llworkerthread.h +++ b/indra/llcommon/llworkerthread.h @@ -88,7 +88,7 @@ public: LLWorkerThread(const std::string& name, bool threaded = true, bool should_pause = false); ~LLWorkerThread(); - /*virtual*/ S32 update(F32 max_time_ms); + /*virtual*/ size_t update(F32 max_time_ms); handle_t addWorkRequest(LLWorkerClass* workerclass, S32 param, U32 priority = PRIORITY_NORMAL); diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h index b07805b628..da8512169c 100644 --- a/indra/llcommon/stdtypes.h +++ b/indra/llcommon/stdtypes.h @@ -26,16 +26,23 @@ #ifndef LL_STDTYPES_H #define LL_STDTYPES_H +#include <cassert> #include <cfloat> #include <climits> +#include <limits> +#include <type_traits> -typedef signed char S8; +typedef signed char S8; typedef unsigned char U8; typedef signed short S16; typedef unsigned short U16; -typedef signed int S32; +typedef signed int S32; typedef unsigned int U32; +// to express an index that might go negative +// (ssize_t is provided by SOME compilers, don't collide) +typedef typename std::make_signed<size_t>::type llssize; + #if LL_WINDOWS // https://docs.microsoft.com/en-us/cpp/build/reference/zc-wchar-t-wchar-t-is-native-type // https://docs.microsoft.com/en-us/cpp/cpp/fundamental-types-cpp @@ -45,7 +52,7 @@ typedef unsigned int U32; // The version of clang available with VS 2019 also defines wchar_t as __wchar_t // which is also 16 bits. // In any case, llwchar should be a UTF-32 type. -typedef U32 llwchar; +typedef U32 llwchar; #else typedef wchar_t llwchar; // What we'd actually want is a simple module-scope 'if constexpr' to test @@ -76,7 +83,7 @@ typedef double F64; typedef S32 BOOL; typedef U8 KEY; typedef U32 MASK; -typedef U32 TPACKETID; +typedef U32 TPACKETID; // Use #define instead of consts to avoid conversion headaches #define S8_MAX (SCHAR_MAX) @@ -118,4 +125,95 @@ typedef U8 LLPCode; typedef int intptr_t; #endif +/***************************************************************************** +* Narrowing +*****************************************************************************/ +/** + * narrow() is used to cast a wider type to a narrower type with validation. + * + * In many cases we take the size() of a container and try to pass it to an + * S32 or a U32 parameter. We used to be able to assume that the size of + * anything we could fit into memory could be expressed as a 32-bit int. With + * 64-bit viewers, though, size_t as returned by size() and length() and so + * forth is 64 bits, and the compiler is unhappy about stuffing such values + * into 32-bit types. + * + * It works to force the compiler to truncate, e.g. static_cast<S32>(len) or + * S32(len) or (S32)len, but we can do better. + * + * For: + * @code + * std::vector<Object> container; + * void somefunc(S32 size); + * @endcode + * call: + * @code + * somefunc(narrow(container.size())); + * @endcode + * + * narrow() truncates but, in RelWithDebInfo builds, it validates (using + * assert()) that the passed value can validly be expressed by the destination + * type. + */ +// narrow_holder is a struct that accepts the passed value as its original +// type and provides templated conversion functions to other types. Once we're +// building with compilers that support Class Template Argument Deduction, we +// can rename this class template 'narrow' and eliminate the narrow() factory +// function below. +template <typename FROM> +class narrow_holder +{ +private: + FROM mValue; + +public: + narrow_holder(FROM value): mValue(value) {} + + /*---------------------- Narrowing unsigned to signed ----------------------*/ + template <typename TO, + typename std::enable_if<std::is_unsigned<FROM>::value && + std::is_signed<TO>::value, + bool>::type = true> + inline + operator TO() const + { + // The reason we skip the + // assert(value >= std::numeric_limits<TO>::lowest()); + // like the overload below is that to perform the above comparison, + // the compiler promotes the signed lowest() to the unsigned FROM + // type, making it hugely positive -- so a reasonable 'value' will + // always fail the assert(). + assert(mValue <= std::numeric_limits<TO>::max()); + return static_cast<TO>(mValue); + } + + /*----------------------- Narrowing all other cases ------------------------*/ + template <typename TO, + typename std::enable_if<! (std::is_unsigned<FROM>::value && + std::is_signed<TO>::value), + bool>::type = true> + inline + operator TO() const + { + // two different assert()s so we can tell which condition failed + assert(mValue <= std::numeric_limits<TO>::max()); + // Funny, with floating point types min() is "positive epsilon" rather + // than "largest negative" -- that's lowest(). + assert(mValue >= std::numeric_limits<TO>::lowest()); + // Do we really expect to use this with floating point types? + // If so, does it matter if a very small value truncates to zero? + //assert(fabs(mValue) >= std::numeric_limits<TO>::min()); + return static_cast<TO>(mValue); + } +}; + +/// narrow() factory function returns a narrow_holder<FROM>(), which can be +/// implicitly converted to the target type. +template <typename FROM> +inline +narrow_holder<FROM> narrow(FROM value) +{ + return { value }; +} + #endif diff --git a/indra/llcommon/tests/lleventdispatcher_test.cpp b/indra/llcommon/tests/lleventdispatcher_test.cpp index 9da1ecfd67..966dc2c5aa 100644 --- a/indra/llcommon/tests/lleventdispatcher_test.cpp +++ b/indra/llcommon/tests/lleventdispatcher_test.cpp @@ -335,7 +335,7 @@ namespace tut // Full, partial defaults arrays for params for freena(), freenb() LLSD dft_array_full, dft_array_partial; // Start index of partial defaults arrays - const LLSD::Integer partial_offset; + const size_t partial_offset; // Full, partial defaults maps for params for freena(), freenb() LLSD dft_map_full, dft_map_partial; // Most of the above are indexed by "a" or "b". Useful to have an diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h index 3e0da94c02..2d82d6a15e 100644 --- a/indra/llcommon/threadsafeschedule.h +++ b/indra/llcommon/threadsafeschedule.h @@ -82,7 +82,7 @@ namespace LL using TimePoint = ThreadSafeSchedulePrivate::TimePoint; using Clock = TimePoint::clock; - ThreadSafeSchedule(U32 capacity=1024): + ThreadSafeSchedule(size_t capacity=1024): super(capacity) {} diff --git a/indra/llcorehttp/bufferarray.cpp b/indra/llcorehttp/bufferarray.cpp index e0b2876a00..8d2e7c6a63 100644 --- a/indra/llcorehttp/bufferarray.cpp +++ b/indra/llcorehttp/bufferarray.cpp @@ -196,7 +196,7 @@ size_t BufferArray::read(size_t pos, void * dst, size_t len) return 0; size_t result(0), offset(0); - const int block_limit(mBlocks.size()); + const auto block_limit(mBlocks.size()); int block_start(findBlock(pos, &offset)); if (block_start < 0) return 0; @@ -228,7 +228,7 @@ size_t BufferArray::write(size_t pos, const void * src, size_t len) return 0; size_t result(0), offset(0); - const int block_limit(mBlocks.size()); + const auto block_limit(mBlocks.size()); int block_start(findBlock(pos, &offset)); if (block_start >= 0) @@ -288,7 +288,7 @@ int BufferArray::findBlock(size_t pos, size_t * ret_offset) if (pos >= mLen) return -1; // Doesn't exist - const int block_limit(mBlocks.size()); + const int block_limit(narrow(mBlocks.size())); for (int i(0); i < block_limit; ++i) { if (pos < mBlocks[i]->mUsed) diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp index 0dbb744bcf..ff4336d2de 100644 --- a/indra/llimage/llimageworker.cpp +++ b/indra/llimage/llimageworker.cpp @@ -46,7 +46,7 @@ LLImageDecodeThread::~LLImageDecodeThread() // MAIN THREAD // virtual -S32 LLImageDecodeThread::update(F32 max_time_ms) +size_t LLImageDecodeThread::update(F32 max_time_ms) { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLMutexLock lock(mCreationMutex); diff --git a/indra/llimage/llimageworker.h b/indra/llimage/llimageworker.h index 1bfb0ddfd3..54814c24c5 100644 --- a/indra/llimage/llimageworker.h +++ b/indra/llimage/llimageworker.h @@ -78,7 +78,7 @@ public: handle_t decodeImage(LLImageFormatted* image, U32 priority, S32 discard, BOOL needs_aux, Responder* responder); - S32 update(F32 max_time_ms); + size_t update(F32 max_time_ms); // Used by unit tests to check the consistency of the thread instance S32 tut_size(); diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index f43d07ce5e..ed5334d31b 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2398,7 +2398,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) mVolumeFaces.resize(face_count); - for (U32 i = 0; i < face_count; ++i) + for (size_t i = 0; i < face_count; ++i) { LLVolumeFace& face = mVolumeFaces[i]; @@ -5013,6 +5013,17 @@ void LLVolumeFace::optimize(F32 angle_cutoff) { U16 index = mIndices[i]; + if (index >= mNumVertices) + { + // invalid index + // replace with a valid index to avoid crashes + index = mNumVertices - 1; + mIndices[i] = index; + + // Needs better logging + LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL; + } + LLVolumeFace::VertexData cv; getVertexData(index, cv); @@ -5385,6 +5396,17 @@ bool LLVolumeFace::cacheOptimize() U16 idx = mIndices[i]; U32 tri_idx = i / 3; + if (idx >= mNumVertices) + { + // invalid index + // replace with a valid index to avoid crashes + idx = mNumVertices - 1; + mIndices[i] = idx; + + // Needs better logging + LL_DEBUGS_ONCE("LLVOLUME") << "Invalid index, substituting" << LL_ENDL; + } + vertex_data[idx].mTriangles.push_back(&(triangle_data[tri_idx])); vertex_data[idx].mIdx = idx; triangle_data[tri_idx].mVertex[i % 3] = &(vertex_data[idx]); diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp index be014e7b1e..d310cefd1e 100644 --- a/indra/llmessage/llcoproceduremanager.cpp +++ b/indra/llmessage/llcoproceduremanager.cpp @@ -47,7 +47,10 @@ static const std::map<std::string, U32> DefaultPoolSizes{ }; static const U32 DEFAULT_POOL_SIZE = 5; -const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 4096; +// SL-14399: When we teleport to a brand-new simulator, the coprocedure queue +// gets absolutely slammed with fetch requests. Make this queue effectively +// unlimited. +const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 1024*1024; //========================================================================= class LLCoprocedurePool: private boost::noncopyable diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 35dcbe3836..57ea954054 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -666,7 +666,6 @@ char const* const _PREHASH_GroupRolesCount = LLMessageStringTable::getInstance() char const* const _PREHASH_SimulatorBlock = LLMessageStringTable::getInstance()->getString("SimulatorBlock"); char const* const _PREHASH_GroupID = LLMessageStringTable::getInstance()->getString("GroupID"); char const* const _PREHASH_AgentVel = LLMessageStringTable::getInstance()->getString("AgentVel"); -char const* const _PREHASH_RequestImage = LLMessageStringTable::getInstance()->getString("RequestImage"); char const* const _PREHASH_NetStats = LLMessageStringTable::getInstance()->getString("NetStats"); char const* const _PREHASH_AgentPos = LLMessageStringTable::getInstance()->getString("AgentPos"); char const* const _PREHASH_AgentSit = LLMessageStringTable::getInstance()->getString("AgentSit"); @@ -1047,7 +1046,6 @@ char const* const _PREHASH_SortOrder = LLMessageStringTable::getInstance()->getS char const* const _PREHASH_Hunter = LLMessageStringTable::getInstance()->getString("Hunter"); char const* const _PREHASH_SunAngVelocity = LLMessageStringTable::getInstance()->getString("SunAngVelocity"); char const* const _PREHASH_BinaryBucket = LLMessageStringTable::getInstance()->getString("BinaryBucket"); -char const* const _PREHASH_ImagePacket = LLMessageStringTable::getInstance()->getString("ImagePacket"); char const* const _PREHASH_StartGroupProposal = LLMessageStringTable::getInstance()->getString("StartGroupProposal"); char const* const _PREHASH_EnergyLevel = LLMessageStringTable::getInstance()->getString("EnergyLevel"); char const* const _PREHASH_PriceForListing = LLMessageStringTable::getInstance()->getString("PriceForListing"); @@ -1236,7 +1234,6 @@ char const* const _PREHASH_ForceScriptControlRelease = LLMessageStringTable::get char const* const _PREHASH_ParcelRelease = LLMessageStringTable::getInstance()->getString("ParcelRelease"); char const* const _PREHASH_VFileType = LLMessageStringTable::getInstance()->getString("VFileType"); char const* const _PREHASH_EjectGroupMemberReply = LLMessageStringTable::getInstance()->getString("EjectGroupMemberReply"); -char const* const _PREHASH_ImageData = LLMessageStringTable::getInstance()->getString("ImageData"); char const* const _PREHASH_SimulatorViewerTimeMessage = LLMessageStringTable::getInstance()->getString("SimulatorViewerTimeMessage"); char const* const _PREHASH_Rotation = LLMessageStringTable::getInstance()->getString("Rotation"); char const* const _PREHASH_Selection = LLMessageStringTable::getInstance()->getString("Selection"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 3015f438b5..572dadd408 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -666,7 +666,6 @@ extern char const* const _PREHASH_GroupRolesCount; extern char const* const _PREHASH_SimulatorBlock; extern char const* const _PREHASH_GroupID; extern char const* const _PREHASH_AgentVel; -extern char const* const _PREHASH_RequestImage; extern char const* const _PREHASH_NetStats; extern char const* const _PREHASH_AgentPos; extern char const* const _PREHASH_AgentSit; @@ -1047,7 +1046,6 @@ extern char const* const _PREHASH_SortOrder; extern char const* const _PREHASH_Hunter; extern char const* const _PREHASH_SunAngVelocity; extern char const* const _PREHASH_BinaryBucket; -extern char const* const _PREHASH_ImagePacket; extern char const* const _PREHASH_StartGroupProposal; extern char const* const _PREHASH_EnergyLevel; extern char const* const _PREHASH_PriceForListing; diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 68654486a4..752a850d42 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -330,7 +330,10 @@ LLModel::EModelStatus load_face_from_dom_triangles( // VFExtents change face.mExtents[0].set(v[0], v[1], v[2]); face.mExtents[1].set(v[0], v[1], v[2]); - point_map.clear(); + + verts.clear(); + indices.clear(); + point_map.clear(); } } diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index a6ab96ab18..2aaaa4e8c1 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -57,6 +57,8 @@ public: mutable std::vector<S32> mJointNums; typedef std::vector<LLMatrix4a, boost::alignment::aligned_allocator<LLMatrix4a, 16>> matrix_list_t; matrix_list_t mInvBindMatrix; + + // bones/joints position overrides matrix_list_t mAlternateBindMatrix; LL_ALIGN_16(LLMatrix4a mBindShapeMatrix); diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h index c39e44200c..b4fd5f60aa 100644 --- a/indra/llui/llchat.h +++ b/indra/llui/llchat.h @@ -38,7 +38,8 @@ typedef enum e_chat_source_type CHAT_SOURCE_AGENT = 1, CHAT_SOURCE_OBJECT = 2, CHAT_SOURCE_TELEPORT = 3, - CHAT_SOURCE_UNKNOWN = 4 + CHAT_SOURCE_UNKNOWN = 4, + CHAT_SOURCE_REGION = 5, } EChatSourceType; typedef enum e_chat_type diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp index 08da599ef2..362fe0c19e 100644 --- a/indra/llui/llcheckboxctrl.cpp +++ b/indra/llui/llcheckboxctrl.cpp @@ -203,11 +203,9 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent) // it will work fine in case of decrease of space, but if we get more space or text // becomes longer, label will fail to grow so reinit label's dimentions. - static LLUICachedControl<S32> llcheckboxctrl_hpad("UICheckboxctrlHPad", 0); LLRect label_rect = mLabel->getRect(); - S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad; - label_rect.mRight = label_rect.mLeft + new_width; - mLabel->setRect(label_rect); + S32 new_width = rect.getWidth() - label_rect.mLeft; + mLabel->reshape(new_width, label_rect.getHeight(), TRUE); S32 label_top = label_rect.mTop; mLabel->reshapeToFitText(TRUE); diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h index 093e213be3..618169a8fe 100644 --- a/indra/llui/llfolderviewmodel.h +++ b/indra/llui/llfolderviewmodel.h @@ -172,7 +172,7 @@ public: virtual BOOL removeItem() = 0; virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0; - virtual BOOL isItemCopyable() const = 0; + virtual bool isItemCopyable(bool can_copy_as_link = true) const = 0; virtual BOOL copyToClipboard() const = 0; virtual BOOL cutToClipboard() = 0; virtual bool isCutToClipboard() { return false; }; diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp index 65c7b420ce..88c1bdc0d5 100644 --- a/indra/llui/llscrolllistctrl.cpp +++ b/indra/llui/llscrolllistctrl.cpp @@ -3395,3 +3395,42 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien } return mIsFriendSignal->connect(cb); } + +bool LLScrollListCtrl::highlightMatchingItems(const std::string& filter_str) +{ + if (filter_str == "" || filter_str == " ") + { + clearHighlightedItems(); + return false; + } + + bool res = false; + + setHighlightedColor(LLUIColorTable::instance().getColor("SearchableControlHighlightColor", LLColor4::red)); + + std::string filter_str_lc(filter_str); + LLStringUtil::toLower(filter_str_lc); + + std::vector<LLScrollListItem*> data = getAllData(); + std::vector<LLScrollListItem*>::iterator iter = data.begin(); + while (iter != data.end()) + { + LLScrollListCell* cell = (*iter)->getColumn(0); + if (cell) + { + std::string value = cell->getValue().asString(); + LLStringUtil::toLower(value); + if (value.find(filter_str_lc) == std::string::npos) + { + (*iter)->setHighlighted(false); + } + else + { + (*iter)->setHighlighted(true); + res = true; + } + } + iter++; + } + return res; +} diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h index 77d10fdec7..11ee012185 100644 --- a/indra/llui/llscrolllistctrl.h +++ b/indra/llui/llscrolllistctrl.h @@ -419,6 +419,8 @@ public: void setNeedsSort(bool val = true) { mSorted = !val; } void dirtyColumns(); // some operation has potentially affected column layout or ordering + bool highlightMatchingItems(const std::string& filter_str); + boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb ) { if (!mSortCallback) mSortCallback = new sort_signal_t(); diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index ef7c8ec012..c411aafb1a 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -101,7 +101,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) // Spin buttons LLButton::Params up_button_params(p.up_button); up_button_params.rect = LLRect(btn_left, getRect().getHeight(), btn_right, getRect().getHeight() - spinctrl_btn_height); - up_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); + // Click callback starts within the button and ends within the button, + // but LLSpinCtrl handles the action continuosly so subsribers needs to + // be informed about click ending even if outside view, use 'up' instead + up_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onUpBtn, this, _2)); up_button_params.commit_on_capture_lost = true; @@ -110,7 +113,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) LLButton::Params down_button_params(p.down_button); down_button_params.rect = LLRect(btn_left, getRect().getHeight() - spinctrl_btn_height, btn_right, getRect().getHeight() - 2 * spinctrl_btn_height); - down_button_params.click_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); + down_button_params.mouse_up_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.mouse_held_callback.function(boost::bind(&LLSpinCtrl::onDownBtn, this, _2)); down_button_params.commit_on_capture_lost = true; mDownBtn = LLUICtrlFactory::create<LLButton>(down_button_params); diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index 7e4aaa53bf..8effd866e0 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -355,95 +355,113 @@ void LLTextBase::onValueChange(S32 start, S32 end) { } - -// Draws the black box behind the selected text -void LLTextBase::drawSelectionBackground() +std::vector<LLRect> LLTextBase::getSelctionRects() { - // Draw selection even if we don't have keyboard focus for search/replace - if( hasSelection() && !mLineInfoList.empty()) - { - std::vector<LLRect> selection_rects; + // Nor supposed to be called without selection + llassert(hasSelection()); + llassert(!mLineInfoList.empty()); - S32 selection_left = llmin( mSelectionStart, mSelectionEnd ); - S32 selection_right = llmax( mSelectionStart, mSelectionEnd ); + std::vector<LLRect> selection_rects; - // Skip through the lines we aren't drawing. - LLRect content_display_rect = getVisibleDocumentRect(); + S32 selection_left = llmin(mSelectionStart, mSelectionEnd); + S32 selection_right = llmax(mSelectionStart, mSelectionEnd); - // binary search for line that starts before top of visible buffer - line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); - line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top()); + // Skip through the lines we aren't drawing. + LLRect content_display_rect = getVisibleDocumentRect(); - bool done = false; + // binary search for line that starts before top of visible buffer + line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, compare_bottom()); + line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, compare_top()); - // Find the coordinates of the selected area - for (;line_iter != end_iter && !done; ++line_iter) - { - // is selection visible on this line? - if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right) - { - segment_set_t::iterator segment_iter; - S32 segment_offset; - getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); - - LLRect selection_rect; - selection_rect.mLeft = line_iter->mRect.mLeft; - selection_rect.mRight = line_iter->mRect.mLeft; - selection_rect.mBottom = line_iter->mRect.mBottom; - selection_rect.mTop = line_iter->mRect.mTop; - - for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) - { - LLTextSegmentPtr segmentp = *segment_iter; + bool done = false; - S32 segment_line_start = segmentp->getStart() + segment_offset; - S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); + // Find the coordinates of the selected area + for (; line_iter != end_iter && !done; ++line_iter) + { + // is selection visible on this line? + if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right) + { + segment_set_t::iterator segment_iter; + S32 segment_offset; + getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); - if (segment_line_start > segment_line_end) break; + // Use F32 otherwise a string of multiple segments + // will accumulate a large error + F32 left_precise = line_iter->mRect.mLeft; + F32 right_precise = line_iter->mRect.mLeft; - S32 segment_width = 0; - S32 segment_height = 0; + for (; segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) + { + LLTextSegmentPtr segmentp = *segment_iter; - // if selection after beginning of segment - if(selection_left >= segment_line_start) - { - S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mLeft += segment_width; - } + S32 segment_line_start = segmentp->getStart() + segment_offset; + S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); - // if selection_right == segment_line_end then that means we are the first character of the next segment - // or first character of the next line, in either case we want to add the length of the current segment - // to the selection rectangle and continue. - // if selection right > segment_line_end then selection spans end of current segment... - if (selection_right >= segment_line_end) - { - // extend selection slightly beyond end of line - // to indicate selection of newline character (use "n" character to determine width) - S32 num_chars = segment_line_end - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mRight += segment_width; - } - // else if selection ends on current segment... - else - { - S32 num_chars = selection_right - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mRight += segment_width; + if (segment_line_start > segment_line_end) break; - break; - } - } - selection_rects.push_back(selection_rect); - } - } + F32 segment_width = 0; + S32 segment_height = 0; + + // if selection after beginning of segment + if (selection_left >= segment_line_start) + { + S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + left_precise += segment_width; + } + + // if selection_right == segment_line_end then that means we are the first character of the next segment + // or first character of the next line, in either case we want to add the length of the current segment + // to the selection rectangle and continue. + // if selection right > segment_line_end then selection spans end of current segment... + if (selection_right >= segment_line_end) + { + // extend selection slightly beyond end of line + // to indicate selection of newline character (use "n" character to determine width) + S32 num_chars = segment_line_end - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + right_precise += segment_width; + } + // else if selection ends on current segment... + else + { + S32 num_chars = selection_right - segment_line_start; + segmentp->getDimensionsF32(segment_offset, num_chars, segment_width, segment_height); + right_precise += segment_width; + + break; + } + } + + LLRect selection_rect; + selection_rect.mLeft = left_precise; + selection_rect.mRight = right_precise; + selection_rect.mBottom = line_iter->mRect.mBottom; + selection_rect.mTop = line_iter->mRect.mTop; + + selection_rects.push_back(selection_rect); + } + } + + return selection_rects; +} + +// Draws the black box behind the selected text +void LLTextBase::drawSelectionBackground() +{ + // Draw selection even if we don't have keyboard focus for search/replace + if (hasSelection() && !mLineInfoList.empty()) + { + std::vector<LLRect> selection_rects = getSelctionRects(); // Draw the selection box (we're using a box instead of reversing the colors on the selected text). gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); const LLColor4& color = mSelectedBGColor; F32 alpha = hasFocus() ? 0.7f : 0.3f; alpha *= getDrawContext().mAlpha; + LLColor4 selection_color(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], alpha); + LLRect content_display_rect = getVisibleDocumentRect(); for (std::vector<LLRect>::iterator rect_it = selection_rects.begin(); rect_it != selection_rects.end(); @@ -2551,7 +2569,7 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, } S32 pos = getLength(); - S32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft; + F32 start_x = line_iter->mRect.mLeft + doc_rect.mLeft; segment_set_t::iterator line_seg_iter; S32 line_seg_offset; @@ -2563,8 +2581,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, S32 segment_line_start = segmentp->getStart() + line_seg_offset; S32 segment_line_length = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd) - segment_line_start; - S32 text_width, text_height; - bool newline = segmentp->getDimensions(line_seg_offset, segment_line_length, text_width, text_height); + F32 text_width; + S32 text_height; + bool newline = segmentp->getDimensionsF32(line_seg_offset, segment_line_length, text_width, text_height); if(newline) { @@ -2584,8 +2603,9 @@ S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, S32 offset; if (!segmentp->canEdit()) { - S32 segment_width, segment_height; - segmentp->getDimensions(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height); + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(0, segmentp->getEnd() - segmentp->getStart(), segment_width, segment_height); if (round && local_x - start_x > segment_width / 2) { offset = segment_line_length; @@ -2632,17 +2652,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const return LLRect(); } - LLRect doc_rect; - // clamp pos to valid values pos = llclamp(pos, 0, mLineInfoList.back().mDocIndexEnd - 1); line_list_t::const_iterator line_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), pos, line_end_compare()); - doc_rect.mLeft = line_iter->mRect.mLeft; - doc_rect.mBottom = line_iter->mRect.mBottom; - doc_rect.mTop = line_iter->mRect.mTop; - segment_set_t::iterator line_seg_iter; S32 line_seg_offset; segment_set_t::iterator cursor_seg_iter; @@ -2650,6 +2664,8 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const getSegmentAndOffset(line_iter->mDocIndexStart, &line_seg_iter, &line_seg_offset); getSegmentAndOffset(pos, &cursor_seg_iter, &cursor_seg_offset); + F32 doc_left_precise = line_iter->mRect.mLeft; + while(line_seg_iter != mSegments.end()) { const LLTextSegmentPtr segmentp = *line_seg_iter; @@ -2657,18 +2673,20 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const if (line_seg_iter == cursor_seg_iter) { // cursor advanced to right based on difference in offset of cursor to start of line - S32 segment_width, segment_height; - segmentp->getDimensions(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height); - doc_rect.mLeft += segment_width; + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(line_seg_offset, cursor_seg_offset - line_seg_offset, segment_width, segment_height); + doc_left_precise += segment_width; break; } else { // add remainder of current text segment to cursor position - S32 segment_width, segment_height; - segmentp->getDimensions(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height); - doc_rect.mLeft += segment_width; + F32 segment_width; + S32 segment_height; + segmentp->getDimensionsF32(line_seg_offset, (segmentp->getEnd() - segmentp->getStart()) - line_seg_offset, segment_width, segment_height); + doc_left_precise += segment_width; // offset will be 0 for all segments after the first line_seg_offset = 0; // go to next text segment on this line @@ -2676,6 +2694,11 @@ LLRect LLTextBase::getDocRectFromDocIndex(S32 pos) const } } + LLRect doc_rect; + doc_rect.mLeft = doc_left_precise; + doc_rect.mBottom = line_iter->mRect.mBottom; + doc_rect.mTop = line_iter->mRect.mTop; + // set rect to 0 width doc_rect.mRight = doc_rect.mLeft; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 25f8fa1c2b..e3cf56a5ee 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -638,6 +638,8 @@ protected: return mLabel.getString() + getToolTip(); } + std::vector<LLRect> getSelctionRects(); + protected: // text segmentation and flow segment_set_t mSegments; diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index c487877caf..41f3042ace 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -3067,18 +3067,54 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_ { LLMutexLock lock(&window_imp->mRawMouseMutex); - S32 speed; - const S32 DEFAULT_SPEED(10); - SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0); - if (speed == DEFAULT_SPEED) + bool absolute_coordinates = (raw->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE); + + if (absolute_coordinates) { - window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX; - window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY; + static S32 prev_absolute_x = 0; + static S32 prev_absolute_y = 0; + S32 absolute_x; + S32 absolute_y; + + if ((raw->data.mouse.usFlags & 0x10) == 0x10) // touch screen? touch? Not defined in header + { + // touch screen spams (0,0) coordinates in a number of situations + // (0,0) might need to be filtered + absolute_x = raw->data.mouse.lLastX; + absolute_y = raw->data.mouse.lLastY; + } + else + { + bool v_desktop = (raw->data.mouse.usFlags & MOUSE_VIRTUAL_DESKTOP) == MOUSE_VIRTUAL_DESKTOP; + + S32 width = GetSystemMetrics(v_desktop ? SM_CXVIRTUALSCREEN : SM_CXSCREEN); + S32 height = GetSystemMetrics(v_desktop ? SM_CYVIRTUALSCREEN : SM_CYSCREEN); + + absolute_x = (raw->data.mouse.lLastX / 65535.0f) * width; + absolute_y = (raw->data.mouse.lLastY / 65535.0f) * height; + } + + window_imp->mRawMouseDelta.mX += absolute_x - prev_absolute_x; + window_imp->mRawMouseDelta.mY -= absolute_y - prev_absolute_y; + + prev_absolute_x = absolute_x; + prev_absolute_y = absolute_y; } else { - window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED); - window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED); + S32 speed; + const S32 DEFAULT_SPEED(10); + SystemParametersInfo(SPI_GETMOUSESPEED, 0, &speed, 0); + if (speed == DEFAULT_SPEED) + { + window_imp->mRawMouseDelta.mX += raw->data.mouse.lLastX; + window_imp->mRawMouseDelta.mY -= raw->data.mouse.lLastY; + } + else + { + window_imp->mRawMouseDelta.mX += round((F32)raw->data.mouse.lLastX * (F32)speed / DEFAULT_SPEED); + window_imp->mRawMouseDelta.mY -= round((F32)raw->data.mouse.lLastY * (F32)speed / DEFAULT_SPEED); + } } } } @@ -4215,7 +4251,10 @@ void LLWindowWin32::handleCompositionMessage(const U32 indexes) if (needs_update) { - mPreeditor->resetPreedit(); + if (preedit_string.length() != 0 || result_string.length() != 0) + { + mPreeditor->resetPreedit(); + } if (result_string.length() > 0) { diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 7d78ec9e3c..9eee5338ec 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -287,9 +287,9 @@ set(viewer_SOURCE_FILES llfloaternotificationsconsole.cpp llfloaternotificationstabbed.cpp llfloateroutfitphotopreview.cpp - llfloateroutfitsnapshot.cpp llfloaterobjectweights.cpp llfloateropenobject.cpp + llfloatersimpleoutfitsnapshot.cpp llfloaterpathfindingcharacters.cpp llfloaterpathfindingconsole.cpp llfloaterpathfindinglinksets.cpp @@ -929,9 +929,9 @@ set(viewer_HEADER_FILES llfloaternotificationsconsole.h llfloaternotificationstabbed.h llfloateroutfitphotopreview.h - llfloateroutfitsnapshot.h llfloaterobjectweights.h llfloateropenobject.h + llfloatersimpleoutfitsnapshot.h llfloaterpathfindingcharacters.h llfloaterpathfindingconsole.h llfloaterpathfindinglinksets.h diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6861153d43..6789e71e41 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -4747,7 +4747,7 @@ <key>Type</key> <string>String</string> <key>Value</key> - <string>https://search.[GRID]/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> + <string>https://search.[GRID]/viewer/?query_term=[QUERY]&search_type=[TYPE][COLLECTION]&maturity=[MATURITY]&lang=[LANGUAGE]&g=[GODLIKE]&sid=[SESSION_ID]&rid=[REGION_ID]&pid=[PARCEL_ID]&channel=[CHANNEL]&version=[VERSION]&major=[VERSION_MAJOR]&minor=[VERSION_MINOR]&patch=[VERSION_PATCH]&build=[VERSION_BUILD]</string> </map> <key>GuidebookURL</key> <map> @@ -14634,6 +14634,17 @@ <key>Value</key> <integer>0</integer> </map> + <key>MediaSoundsEarLocation</key> + <map> + <key>Comment</key> + <string>Location of the virtual ear for media and sounds</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>S32</string> + <key>Value</key> + <integer>0</integer> + </map> <key>VoiceHost</key> <map> <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index b26194f278..b30d7655db 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -202,7 +202,7 @@ VARYING vec2 vary_texcoord2; uniform float env_intensity; uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha -#ifdef HAS_ALPHA_MASK +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) uniform float minimum_alpha; #endif @@ -227,12 +227,11 @@ void main() vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); diffcol.rgb *= vertex_color.rgb; -#ifdef HAS_ALPHA_MASK -#if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND - if (diffcol.a*vertex_color.a < minimum_alpha) -#else - if (diffcol.a < minimum_alpha) -#endif +#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK) + + // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points + float bias = 0.001953125; // 1/512, or half an 8-bit quantization (SL-18637) + if (diffcol.a < minimum_alpha-bias) { discard; } diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 1ccde98283..93dd5e7e70 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 350000 -RenderAvatarVP 1 1 RenderAutoMuteSurfaceAreaLimit 1 1000.0 RenderCubeMap 1 1 RenderDelayVBUpdate 1 0 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 5542eee6ca..66197e6484 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 350000 -RenderAvatarVP 1 1 RenderAutoMuteSurfaceAreaLimit 1 1000.0 RenderCubeMap 1 1 RenderDelayVBUpdate 1 0 @@ -80,7 +79,6 @@ RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 RenderAvatarMaxComplexity 1 25000 -RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0 RenderGlowResolutionPow 1 8 @@ -111,7 +109,6 @@ RenderAvatarLODFactor 1 0 RenderAvatarPhysicsLODFactor 1 0 RenderAvatarMaxNonImpostors 1 3 RenderAvatarMaxComplexity 1 35000 -RenderAvatarVP 1 0 RenderFarClip 1 64 RenderFlexTimeFactor 1 0 RenderGlowResolutionPow 1 8 @@ -141,7 +138,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 0.5 RenderAvatarMaxComplexity 1 100000 RenderAvatarPhysicsLODFactor 1 0.75 -RenderAvatarVP 1 1 RenderFarClip 1 96 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 8 @@ -171,7 +167,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 200000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 @@ -201,7 +196,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 250000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 @@ -231,7 +225,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 300000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 @@ -261,7 +254,6 @@ RenderAvatarCloth 1 0 RenderAvatarLODFactor 1 1.0 RenderAvatarMaxComplexity 1 350000 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 128 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 @@ -290,7 +282,6 @@ RenderAnisotropic 1 1 RenderAvatarCloth 1 1 RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 -RenderAvatarVP 1 1 RenderFarClip 1 256 RenderFlexTimeFactor 1 1.0 RenderGlowResolutionPow 1 9 @@ -367,7 +358,6 @@ RenderCompressTextures 1 0 // No Pixel Shaders available // list NoPixelShaders -RenderAvatarVP 0 0 RenderAvatarCloth 0 0 RenderReflectionDetail 0 0 WindLightUseAtmosShaders 0 0 @@ -380,7 +370,6 @@ RenderShadowDetail 0 0 // No Vertex Shaders available // list NoVertexShaders -RenderAvatarVP 0 0 RenderAvatarCloth 0 0 RenderReflectionDetail 0 0 WindLightUseAtmosShaders 0 0 @@ -402,7 +391,6 @@ RenderVBOMappingDisable 1 1 list safe RenderAnisotropic 1 0 RenderAvatarCloth 0 0 -RenderAvatarVP 0 0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 80000 RenderObjectBump 0 0 @@ -597,7 +585,6 @@ Disregard128DefaultDrawDistance 1 0 // on various ATI chipsets on drivers before 8.2 list ATIOldDriver -RenderAvatarVP 0 0 RenderAvatarCloth 0 0 // Avoid driver crashes with some features on Linux with old ATI drivers UseOcclusion 0 0 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index c9efd89cc8..fed035c7fa 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -33,7 +33,6 @@ RenderAvatarLODFactor 1 1.0 RenderAvatarPhysicsLODFactor 1 1.0 RenderAvatarMaxNonImpostors 1 16 RenderAvatarMaxComplexity 1 350000 -RenderAvatarVP 1 1 RenderAutoMuteSurfaceAreaLimit 1 1000.0 RenderCubeMap 1 1 RenderDelayVBUpdate 1 0 diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 5250369813..9018a5f168 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -2912,9 +2912,11 @@ void LLAgent::processMaturityPreferenceFromServer(const LLSD &result, U8 perferr bool LLAgent::requestPostCapability(const std::string &capName, LLSD &postData, httpCallback_t cbSuccess, httpCallback_t cbFailure) { - std::string url; - - url = getRegion()->getCapability(capName); + if (!getRegion()) + { + return false; + } + std::string url = getRegion()->getCapability(capName); if (url.empty()) { diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4f3e0b08e4..8af5fdfc93 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -209,7 +209,7 @@ #include "llcommandlineparser.h" #include "llfloatermemleak.h" #include "llfloaterreg.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llfloatersnapshot.h" #include "llsidepanelinventory.h" #include "llatmosphere.h" @@ -1275,7 +1275,6 @@ bool LLAppViewer::init() //LLSimpleton creations LLEnvironment::createInstance(); - LLEnvironment::getInstance()->initSingleton(); LLWorld::createInstance(); LLSelectMgr::createInstance(); LLViewerCamera::createInstance(); @@ -1521,7 +1520,7 @@ bool LLAppViewer::doFrame() LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" ) pingMainloopTimeout("Main:Snapshot"); LLFloaterSnapshot::update(); // take snapshots - LLFloaterOutfitSnapshot::update(); + LLFloaterSimpleOutfitSnapshot::update(); gGLActive = FALSE; } } diff --git a/indra/newview/llaudiosourcevo.cpp b/indra/newview/llaudiosourcevo.cpp index 1846238d93..43abbb57ee 100644 --- a/indra/newview/llaudiosourcevo.cpp +++ b/indra/newview/llaudiosourcevo.cpp @@ -102,7 +102,7 @@ LLVector3d LLAudioSourceVO::getPosGlobal() const bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cutoff) const { - static LLCachedControl<S32> ear_mode(gSavedSettings, "VoiceEarLocation", 0); + static LLCachedControl<S32> ear_mode(gSavedSettings, "MediaSoundsEarLocation", 0); LLVector3d pos_ear; @@ -113,9 +113,6 @@ bool LLAudioSourceVO::isInCutOffRadius(const LLVector3d pos_global, const F32 cu break; case 1: // avatar - case 2: - // voice support 'mixed' in '2' case with agent's position and camera's rotations - // but it is not defined in settings and uses camera as default pos_ear = gAgent.getPositionGlobal(); break; diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp index 7ff24f64ac..7188b9136c 100644 --- a/indra/newview/llchathistory.cpp +++ b/indra/newview/llchathistory.cpp @@ -650,7 +650,7 @@ public: void showInspector() { - if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType) return; + if (mAvatarID.isNull() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType) return; if (mSourceType == CHAT_SOURCE_OBJECT) { @@ -798,6 +798,7 @@ public: icon->setValue(LLSD("OBJECT_Icon")); break; case CHAT_SOURCE_SYSTEM: + case CHAT_SOURCE_REGION: icon->setValue(LLSD("SL_Logo")); break; case CHAT_SOURCE_TELEPORT: @@ -947,7 +948,7 @@ protected: void showInfoCtrl() { - const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType; + const bool isVisible = !mAvatarID.isNull() && !mFrom.empty() && CHAT_SOURCE_SYSTEM != mSourceType && CHAT_SOURCE_REGION != mSourceType; if (isVisible) { const LLRect sticky_rect = mUserNameTextBox->getRect(); @@ -1343,7 +1344,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params); prependNewLineState = false; } - else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log) + else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log && chat.mSourceType != CHAT_SOURCE_REGION) { LLStyle::Params link_params(body_message_params); link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID)); diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h index 787deeb594..7c6980a7e6 100644 --- a/indra/newview/llconversationmodel.h +++ b/indra/newview/llconversationmodel.h @@ -87,7 +87,7 @@ public: virtual BOOL removeItem() { return FALSE; } virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { } virtual void move( LLFolderViewModelItem* parent_listener ) { } - virtual BOOL isItemCopyable() const { return FALSE; } + virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; } virtual BOOL copyToClipboard() const { return FALSE; } virtual BOOL cutToClipboard() { return FALSE; } virtual BOOL isClipboardPasteable() const { return FALSE; } diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index ed991a2bbf..e6b6b10408 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -41,6 +41,7 @@ #include "lldrawable.h" #include "llface.h" #include "llsky.h" +#include "llstartup.h" #include "lltextureentry.h" #include "llviewercamera.h" #include "llviewertexturelist.h" @@ -81,11 +82,6 @@ static S32 bump_channel = -1; // LLAtomicBool; this should work just fine, now. HB #define LL_BUMPLIST_MULTITHREADED 1 -// static -void LLStandardBumpmap::init() -{ - LLStandardBumpmap::restoreGL(); -} // static void LLStandardBumpmap::shutdown() @@ -96,7 +92,7 @@ void LLStandardBumpmap::shutdown() // static void LLStandardBumpmap::restoreGL() { - addstandard(); + addstandard(); } // static @@ -109,6 +105,12 @@ void LLStandardBumpmap::addstandard() return ; } + if (LLStartUp::getStartupState() < STATE_SEED_CAP_GRANTED) + { + // Not ready, need caps for images + return; + } + // can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup. Sigh. So clear the list every time before we (re-)add the standard bumpmaps. //llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 ); clear(); @@ -771,8 +773,6 @@ void LLBumpImageList::init() llassert( mBrightnessEntries.size() == 0 ); llassert( mDarknessEntries.size() == 0 ); - LLStandardBumpmap::init(); - LLStandardBumpmap::restoreGL(); sMainQueue = LL::WorkQueue::getInstance("mainloop"); sTexUpdateQueue = LL::WorkQueue::getInstance("LLImageGL"); // Share work queue with tex loader. diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index e8a027967b..cf463f4458 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -118,7 +118,6 @@ public: static void clear(); static void addstandard(); - static void init(); static void shutdown(); static void restoreGL(); static void destroyGL(); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 1300cf3658..4ef14c20f7 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -874,26 +874,37 @@ void LLEnvironment::initSingleton() requestRegion(); - gAgent.addParcelChangedCallback([this]() { onParcelChange(); }); + if (!mParcelCallbackConnection.connected()) + { + mParcelCallbackConnection = gAgent.addParcelChangedCallback([this]() { onParcelChange(); }); - //TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer. - // We need to know new env version to fix this, without it we can only do full re-request - // Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open - LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); }); - gAgent.addRegionChangedCallback([this]() { onRegionChange(); }); + //TODO: This frequently results in one more request than we need. It isn't breaking, but should be nicer. + // We need to know new env version to fix this, without it we can only do full re-request + // Happens: on updates, on opening LLFloaterRegionInfo, on region crossing if info floater is open + mRegionUpdateCallbackConnection = LLRegionInfoModel::instance().setUpdateCallback([this]() { requestRegion(); }); + mRegionChangeCallbackConnection = gAgent.addRegionChangedCallback([this]() { onRegionChange(); }); - gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); }); + mPositionCallbackConnection = gAgent.whenPositionChanged([this](const LLVector3 &localpos, const LLVector3d &) { onAgentPositionHasChanged(localpos); }); + } if (!gGenericDispatcher.isHandlerPresent(MESSAGE_PUSHENVIRONMENT)) { gGenericDispatcher.addHandler(MESSAGE_PUSHENVIRONMENT, &environment_push_dispatch_handler); } + LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME); LLEventPumps::instance().obtain(PUMP_EXPERIENCE).listen(LISTENER_NAME, [this](LLSD message) { listenExperiencePump(message); return false; }); } void LLEnvironment::cleanupSingleton() { + if (mParcelCallbackConnection.connected()) + { + mParcelCallbackConnection.disconnect(); + mRegionUpdateCallbackConnection.disconnect(); + mRegionChangeCallbackConnection.disconnect(); + mPositionCallbackConnection.disconnect(); + } LLEventPumps::instance().obtain(PUMP_EXPERIENCE).stopListening(LISTENER_NAME); } diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 330de2bea8..64fd170e43 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -402,6 +402,11 @@ private: bool mShowMoonBeacon; S32 mEditorCounter; + connection_t mParcelCallbackConnection; + connection_t mRegionUpdateCallbackConnection; + connection_t mRegionChangeCallbackConnection; + connection_t mPositionCallbackConnection; + struct UpdateInfo { typedef std::shared_ptr<UpdateInfo> ptr_t; diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp index c075f7e8bd..62a1e0af94 100644 --- a/indra/newview/llfloater360capture.cpp +++ b/indra/newview/llfloater360capture.cpp @@ -84,7 +84,7 @@ LLFloater360Capture::~LLFloater360Capture() // Tell the Simulator not to send us everything anymore // and revert to the regular "keyhole" frustum of interest // list updates. - if (gSavedSettings.getBOOL("360CaptureUseInterestListCap")) + if (!LLApp::isExiting() && gSavedSettings.getBOOL("360CaptureUseInterestListCap")) { const bool send_everything = false; changeInterestListMode(send_everything); diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp index 4cceddeefb..f1807f1c5b 100644 --- a/indra/newview/llfloaterimnearbychat.cpp +++ b/indra/newview/llfloaterimnearbychat.cpp @@ -307,7 +307,6 @@ void LLFloaterIMNearbyChat::onOpen(const LLSD& key) restoreFloater(); onCollapseToLine(this); } - showTranslationCheckbox(LLTranslate::isTranslationConfigured()); } // virtual diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp index 48e2b8dc14..ee9dc35283 100644 --- a/indra/newview/llfloaterimsession.cpp +++ b/indra/newview/llfloaterimsession.cpp @@ -842,6 +842,7 @@ void LLFloaterIMSession::updateMessages() std::string from = msg["from"].asString(); std::string message = msg["message"].asString(); bool is_history = msg["is_history"].asBoolean(); + bool is_region_msg = msg["is_region_msg"].asBoolean(); LLChat chat; chat.mFromID = from_id; @@ -849,6 +850,10 @@ void LLFloaterIMSession::updateMessages() chat.mFromName = from; chat.mTimeStr = time; chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle; + if (is_region_msg) + { + chat.mSourceType = CHAT_SOURCE_REGION; + } // process offer notification if (msg.has("notification_id")) diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp index 93a0b39e02..204cd03b09 100644 --- a/indra/newview/llfloaterimsessiontab.cpp +++ b/indra/newview/llfloaterimsessiontab.cpp @@ -253,7 +253,6 @@ BOOL LLFloaterIMSessionTab::postBuild() mGearBtn = getChild<LLButton>("gear_btn"); mAddBtn = getChild<LLButton>("add_btn"); mVoiceButton = getChild<LLButton>("voice_call_btn"); - mTranslationCheckBox = getChild<LLUICtrl>("translate_chat_checkbox_lp"); mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel"); mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder"); @@ -811,8 +810,6 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar() mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat); enableDisableCallBtn(); - - showTranslationCheckbox(); } void LLFloaterIMSessionTab::forceReshape() @@ -829,11 +826,6 @@ void LLFloaterIMSessionTab::reshapeChatLayoutPanel() mChatLayoutPanel->reshape(mChatLayoutPanel->getRect().getWidth(), mInputEditor->getRect().getHeight() + mInputEditorPad, FALSE); } -void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show) -{ - mTranslationCheckBox->setVisible(mIsNearbyChat && show); -} - // static void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/) { diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h index 375461cfc1..9f00917647 100644 --- a/indra/newview/llfloaterimsessiontab.h +++ b/indra/newview/llfloaterimsessiontab.h @@ -71,8 +71,6 @@ public: static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid); static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid); - // show/hide the translation check box - void showTranslationCheckbox(const BOOL visible = FALSE); bool isNearbyChat() {return mIsNearbyChat;} @@ -187,7 +185,6 @@ protected: LLButton* mGearBtn; LLButton* mAddBtn; LLButton* mVoiceButton; - LLUICtrl* mTranslationCheckBox; private: // Handling selection and contextual menu diff --git a/indra/newview/llfloateroutfitsnapshot.cpp b/indra/newview/llfloateroutfitsnapshot.cpp deleted file mode 100644 index ad5e97e067..0000000000 --- a/indra/newview/llfloateroutfitsnapshot.cpp +++ /dev/null @@ -1,372 +0,0 @@ -/** - * @file llfloateroutfitsnapshot.cpp - * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2016, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#include "llviewerprecompiledheaders.h" - -#include "llfloatersnapshot.h" -#include "llfloateroutfitsnapshot.h" - -#include "llagent.h" -#include "llfloaterreg.h" -#include "llimagefiltersmanager.h" -#include "llcheckboxctrl.h" -#include "llcombobox.h" -#include "llpostcard.h" -#include "llresmgr.h" // LLLocale -#include "llsdserialize.h" -#include "llsidetraypanelcontainer.h" -#include "llspinctrl.h" -#include "llviewercontrol.h" -#include "lltoolfocus.h" -#include "lltoolmgr.h" - -///---------------------------------------------------------------------------- -/// Local function declarations, constants, enums, and typedefs -///---------------------------------------------------------------------------- -LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView = NULL; - -const S32 OUTFIT_SNAPSHOT_WIDTH = 256; -const S32 OUTFIT_SNAPSHOT_HEIGHT = 256; - -static LLDefaultChildRegistry::Register<LLOutfitSnapshotFloaterView> r("snapshot_outfit_floater_view"); - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot::Impl -///---------------------------------------------------------------------------- - -// virtual -LLPanelSnapshot* LLFloaterOutfitSnapshot::Impl::getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found) -{ - LLPanel* panel = floater->getChild<LLPanel>("panel_outfit_snapshot_inventory"); - LLPanelSnapshot* active_panel = dynamic_cast<LLPanelSnapshot*>(panel); - if (!ok_if_not_found) - { - llassert_always(active_panel != NULL); - } - return active_panel; -} - -// virtual -LLSnapshotModel::ESnapshotFormat LLFloaterOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) -{ - return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; -} - -// virtual -LLSnapshotModel::ESnapshotLayerType LLFloaterOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) -{ - return LLSnapshotModel::SNAPSHOT_TYPE_COLOR; -} - -// This is the main function that keeps all the GUI controls in sync with the saved settings. -// It should be called anytime a setting is changed that could affect the controls. -// No other methods should be changing any of the controls directly except for helpers called by this method. -// The basic pattern for programmatically changing the GUI settings is to first set the -// appropriate saved settings and then call this method to sync the GUI with them. -// FIXME: The above comment seems obsolete now. -// virtual -void LLFloaterOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) -{ - LLSnapshotModel::ESnapshotType shot_type = getActiveSnapshotType(floater); - LLSnapshotModel::ESnapshotFormat shot_format = (LLSnapshotModel::ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); - LLSnapshotModel::ESnapshotLayerType layer_type = getLayerType(floater); - - LLSnapshotLivePreview* previewp = getPreviewView(); - BOOL got_snap = previewp && previewp->getSnapshotUpToDate(); - - // *TODO: Separate maximum size for Web images from postcards - LL_DEBUGS() << "Is snapshot up-to-date? " << got_snap << LL_ENDL; - - LLLocale locale(LLLocale::USER_LOCALE); - std::string bytes_string; - if (got_snap) - { - LLResMgr::getInstance()->getIntegerString(bytes_string, (previewp->getDataSize()) >> 10); - } - - // Update displayed image resolution. - LLTextBox* image_res_tb = floater->getChild<LLTextBox>("image_res_text"); - image_res_tb->setVisible(got_snap); - if (got_snap) - { - image_res_tb->setTextArg("[WIDTH]", llformat("%d", previewp->getEncodedImageWidth())); - image_res_tb->setTextArg("[HEIGHT]", llformat("%d", previewp->getEncodedImageHeight())); - } - - floater->getChild<LLUICtrl>("file_size_label")->setTextArg("[SIZE]", got_snap ? bytes_string : floater->getString("unknown")); - floater->getChild<LLUICtrl>("file_size_label")->setColor(LLUIColorTable::instance().getColor("LabelTextColor")); - - updateResolution(floater); - - if (previewp) - { - previewp->setSnapshotType(shot_type); - previewp->setSnapshotFormat(shot_format); - previewp->setSnapshotBufferType(layer_type); - } - - LLPanelSnapshot* current_panel = Impl::getActivePanel(floater); - if (current_panel) - { - LLSD info; - info["have-snapshot"] = got_snap; - current_panel->updateControls(info); - } - LL_DEBUGS() << "finished updating controls" << LL_ENDL; -} - -// virtual -std::string LLFloaterOutfitSnapshot::Impl::getSnapshotPanelPrefix() -{ - return "panel_outfit_snapshot_"; -} - -// Show/hide upload status message. -// virtual -void LLFloaterOutfitSnapshot::Impl::setFinished(bool finished, bool ok, const std::string& msg) -{ - mFloater->setSuccessLabelPanelVisible(finished && ok); - mFloater->setFailureLabelPanelVisible(finished && !ok); - - if (finished) - { - LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl"); - std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str")); - finished_lbl->setValue(result_text); - - LLPanel* snapshot_panel = mFloater->getChild<LLPanel>("panel_outfit_snapshot_inventory"); - snapshot_panel->onOpen(LLSD()); - } -} - -void LLFloaterOutfitSnapshot::Impl::updateResolution(void* data) -{ - LLFloaterOutfitSnapshot *view = (LLFloaterOutfitSnapshot *)data; - - if (!view) - { - llassert(view); - return; - } - - S32 width = OUTFIT_SNAPSHOT_WIDTH; - S32 height = OUTFIT_SNAPSHOT_HEIGHT; - - LLSnapshotLivePreview* previewp = getPreviewView(); - if (previewp) - { - S32 original_width = 0, original_height = 0; - previewp->getSize(original_width, original_height); - - if (gSavedSettings.getBOOL("RenderUIInSnapshot") || gSavedSettings.getBOOL("RenderHUDInSnapshot")) - { //clamp snapshot resolution to window size when showing UI or HUD in snapshot - width = llmin(width, gViewerWindow->getWindowWidthRaw()); - height = llmin(height, gViewerWindow->getWindowHeightRaw()); - } - - - llassert(width > 0 && height > 0); - - // use the resolution from the selected pre-canned drop-down choice - LL_DEBUGS() << "Setting preview res selected from combo: " << width << "x" << height << LL_ENDL; - previewp->setSize(width, height); - - if (original_width != width || original_height != height) - { - // hide old preview as the aspect ratio could be wrong - checkAutoSnapshot(previewp, FALSE); - LL_DEBUGS() << "updating thumbnail" << LL_ENDL; - previewp->updateSnapshot(TRUE); - } - } -} - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot -///---------------------------------------------------------------------------- - -// Default constructor -LLFloaterOutfitSnapshot::LLFloaterOutfitSnapshot(const LLSD& key) -: LLFloaterSnapshotBase(key), -mOutfitGallery(NULL) -{ - impl = new Impl(this); -} - -LLFloaterOutfitSnapshot::~LLFloaterOutfitSnapshot() -{ -} - -// virtual -BOOL LLFloaterOutfitSnapshot::postBuild() -{ - mRefreshBtn = getChild<LLUICtrl>("new_snapshot_btn"); - childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); - mRefreshLabel = getChild<LLUICtrl>("refresh_lbl"); - mSucceessLblPanel = getChild<LLUICtrl>("succeeded_panel"); - mFailureLblPanel = getChild<LLUICtrl>("failed_panel"); - - childSetCommitCallback("ui_check", ImplBase::onClickUICheck, this); - getChild<LLUICtrl>("ui_check")->setValue(gSavedSettings.getBOOL("RenderUIInSnapshot")); - - childSetCommitCallback("hud_check", ImplBase::onClickHUDCheck, this); - getChild<LLUICtrl>("hud_check")->setValue(gSavedSettings.getBOOL("RenderHUDInSnapshot")); - - getChild<LLUICtrl>("freeze_frame_check")->setValue(gSavedSettings.getBOOL("UseFreezeFrame")); - childSetCommitCallback("freeze_frame_check", ImplBase::onCommitFreezeFrame, this); - - getChild<LLUICtrl>("auto_snapshot_check")->setValue(gSavedSettings.getBOOL("AutoSnapshot")); - childSetCommitCallback("auto_snapshot_check", ImplBase::onClickAutoSnap, this); - - getChild<LLButton>("retract_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this)); - getChild<LLButton>("extend_btn")->setCommitCallback(boost::bind(&LLFloaterOutfitSnapshot::onExtendFloater, this)); - - // Filters - LLComboBox* filterbox = getChild<LLComboBox>("filters_combobox"); - std::vector<std::string> filter_list = LLImageFiltersManager::getInstance()->getFiltersList(); - for (U32 i = 0; i < filter_list.size(); i++) - { - filterbox->add(filter_list[i]); - } - childSetCommitCallback("filters_combobox", ImplBase::onClickFilter, this); - - mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); - - // create preview window - LLRect full_screen_rect = getRootView()->getRect(); - LLSnapshotLivePreview::Params p; - p.rect(full_screen_rect); - LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); - LLView* parent_view = gSnapshotFloaterView->getParent(); - - parent_view->removeChild(gSnapshotFloaterView); - // make sure preview is below snapshot floater - parent_view->addChild(previewp); - parent_view->addChild(gSnapshotFloaterView); - - //move snapshot floater to special purpose snapshotfloaterview - gFloaterView->removeChild(this); - gSnapshotFloaterView->addChild(this); - - impl->mPreviewHandle = previewp->getHandle(); - previewp->setContainer(this); - impl->updateControls(this); - impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); - impl->updateLayout(this); - - previewp->mKeepAspectRatio = FALSE; - previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); - - return TRUE; -} - -// virtual -void LLFloaterOutfitSnapshot::onOpen(const LLSD& key) -{ - LLSnapshotLivePreview* preview = getPreviewView(); - if (preview) - { - LL_DEBUGS() << "opened, updating snapshot" << LL_ENDL; - preview->updateSnapshot(TRUE); - } - focusFirstItem(FALSE); - gSnapshotFloaterView->setEnabled(TRUE); - gSnapshotFloaterView->setVisible(TRUE); - gSnapshotFloaterView->adjustToFitScreen(this, FALSE); - - impl->updateControls(this); - impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); - impl->updateLayout(this); - - LLPanel* snapshot_panel = getChild<LLPanel>("panel_outfit_snapshot_inventory"); - snapshot_panel->onOpen(LLSD()); - postPanelSwitch(); - -} - -void LLFloaterOutfitSnapshot::onExtendFloater() -{ - impl->setAdvanced(gSavedSettings.getBOOL("AdvanceOutfitSnapshot")); -} - -// static -void LLFloaterOutfitSnapshot::update() -{ - LLFloaterOutfitSnapshot* inst = findInstance(); - if (inst != NULL) - { - inst->impl->updateLivePreview(); - } -} - - -// static -LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::findInstance() -{ - return LLFloaterReg::findTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot"); -} - -// static -LLFloaterOutfitSnapshot* LLFloaterOutfitSnapshot::getInstance() -{ - return LLFloaterReg::getTypedInstance<LLFloaterOutfitSnapshot>("outfit_snapshot"); -} - -// virtual -void LLFloaterOutfitSnapshot::saveTexture() -{ - LL_DEBUGS() << "saveTexture" << LL_ENDL; - - LLSnapshotLivePreview* previewp = getPreviewView(); - if (!previewp) - { - llassert(previewp != NULL); - return; - } - - if (mOutfitGallery) - { - mOutfitGallery->onBeforeOutfitSnapshotSave(); - } - previewp->saveTexture(TRUE, getOutfitID().asString()); - if (mOutfitGallery) - { - mOutfitGallery->onAfterOutfitSnapshotSave(); - } - closeFloater(); -} - -///---------------------------------------------------------------------------- -/// Class LLOutfitSnapshotFloaterView -///---------------------------------------------------------------------------- - -LLOutfitSnapshotFloaterView::LLOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p) -{ -} - -LLOutfitSnapshotFloaterView::~LLOutfitSnapshotFloaterView() -{ -} diff --git a/indra/newview/llfloateroutfitsnapshot.h b/indra/newview/llfloateroutfitsnapshot.h deleted file mode 100644 index bee386ec63..0000000000 --- a/indra/newview/llfloateroutfitsnapshot.h +++ /dev/null @@ -1,123 +0,0 @@ -/** - * @file llfloateroutfitsnapshot.h - * @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2016, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFLOATEROUTFITSNAPSHOT_H -#define LL_LLFLOATEROUTFITSNAPSHOT_H - -#include "llfloater.h" -#include "llfloatersnapshot.h" -#include "lloutfitgallery.h" -#include "llsnapshotlivepreview.h" - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot -///---------------------------------------------------------------------------- - -class LLFloaterOutfitSnapshot : public LLFloaterSnapshotBase -{ - LOG_CLASS(LLFloaterOutfitSnapshot); - -public: - - LLFloaterOutfitSnapshot(const LLSD& key); - /*virtual*/ ~LLFloaterOutfitSnapshot(); - - /*virtual*/ BOOL postBuild(); - /*virtual*/ void onOpen(const LLSD& key); - - static void update(); - - void onExtendFloater(); - - static LLFloaterOutfitSnapshot* getInstance(); - static LLFloaterOutfitSnapshot* findInstance(); - /*virtual*/ void saveTexture(); - - const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } - - void setOutfitID(LLUUID id) { mOutfitID = id; } - LLUUID getOutfitID() { return mOutfitID; } - void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } - - class Impl; - friend class Impl; -private: - - LLUUID mOutfitID; - LLOutfitGallery* mOutfitGallery; -}; - -///---------------------------------------------------------------------------- -/// Class LLFloaterOutfitSnapshot::Impl -///---------------------------------------------------------------------------- - -class LLFloaterOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase -{ - LOG_CLASS(LLFloaterOutfitSnapshot::Impl); -public: - Impl(LLFloaterSnapshotBase* floater) - : LLFloaterSnapshotBase::ImplBase(floater) - {} - ~Impl() - {} - void updateResolution(void* data); - - static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status); - - /*virtual*/ LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true); - /*virtual*/ LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater); - /*virtual*/ std::string getSnapshotPanelPrefix(); - - /*virtual*/ void updateControls(LLFloaterSnapshotBase* floater); - -private: - /*virtual*/ LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater); - /*virtual*/ void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null); -}; - -///---------------------------------------------------------------------------- -/// Class LLOutfitSnapshotFloaterView -///---------------------------------------------------------------------------- - -class LLOutfitSnapshotFloaterView : public LLFloaterView -{ -public: - struct Params - : public LLInitParam::Block<Params, LLFloaterView::Params> - { - }; - -protected: - LLOutfitSnapshotFloaterView(const Params& p); - friend class LLUICtrlFactory; - -public: - virtual ~LLOutfitSnapshotFloaterView(); -}; - -extern LLOutfitSnapshotFloaterView* gOutfitSnapshotFloaterView; - -#endif // LL_LLFLOATEROUTFITSNAPSHOT_H diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 273810e8d4..6909ad513d 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -512,6 +512,7 @@ void LLFloaterPreference::saveSettings() if (panel) panel->saveSettings(); } + saveIgnoredNotifications(); } void LLFloaterPreference::apply() @@ -628,6 +629,8 @@ void LLFloaterPreference::cancel() gSavedSettings.setString("PresetGraphicActive", mSavedGraphicsPreset); LLPresetsManager::getInstance()->triggerChangeSignal(); } + + restoreIgnoredNotifications(); } void LLFloaterPreference::onOpen(const LLSD& key) @@ -1505,6 +1508,10 @@ void LLFloaterPreference::onClickEnablePopup() } buildPopupLists(); + if (!mFilterEdit->getText().empty()) + { + filterIgnorableNotifications(); + } } void LLFloaterPreference::onClickDisablePopup() @@ -1520,6 +1527,10 @@ void LLFloaterPreference::onClickDisablePopup() } buildPopupLists(); + if (!mFilterEdit->getText().empty()) + { + filterIgnorableNotifications(); + } } void LLFloaterPreference::resetAllIgnored() @@ -3545,11 +3556,24 @@ void LLFloaterPreference::onUpdateFilterTerm(bool force) return; mSearchData->mRootTab->hightlightAndHide( seachValue ); + filterIgnorableNotifications(); + LLTabContainer *pRoot = getChild< LLTabContainer >( "pref core" ); if( pRoot ) pRoot->selectFirstTab(); } +void LLFloaterPreference::filterIgnorableNotifications() +{ + bool visible = getChildRef<LLScrollListCtrl>("enabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + visible |= getChildRef<LLScrollListCtrl>("disabled_popups").highlightMatchingItems(mFilterEdit->getValue()); + + if (visible) + { + getChildRef<LLTabContainer>("pref core").setTabVisibility( getChild<LLPanel>("msgs"), true ); + } +} + void collectChildren( LLView const *aView, ll::prefs::PanelDataPtr aParentPanel, ll::prefs::TabContainerDataPtr aParentTabContainer ) { if( !aView ) @@ -3638,3 +3662,28 @@ void LLFloaterPreference::collectSearchableItems() } mSearchDataDirty = false; } + +void LLFloaterPreference::saveIgnoredNotifications() +{ + for (LLNotifications::TemplateMap::const_iterator iter = LLNotifications::instance().templatesBegin(); + iter != LLNotifications::instance().templatesEnd(); + ++iter) + { + LLNotificationTemplatePtr templatep = iter->second; + LLNotificationFormPtr formp = templatep->mForm; + + LLNotificationForm::EIgnoreType ignore = formp->getIgnoreType(); + if (ignore <= LLNotificationForm::IGNORE_NO) + continue; + + mIgnorableNotifs[templatep->mName] = !formp->getIgnored(); + } +} + +void LLFloaterPreference::restoreIgnoredNotifications() +{ + for (std::map<std::string, bool>::iterator it = mIgnorableNotifs.begin(); it != mIgnorableNotifs.end(); ++it) + { + LLUI::getInstance()->mSettingGroups["ignores"]->setBOOL(it->first, it->second); + } +} diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h index 542df18ddb..e312c35135 100644 --- a/indra/newview/llfloaterpreference.h +++ b/indra/newview/llfloaterpreference.h @@ -143,6 +143,9 @@ public: // cancel() can restore them. void saveSettings(); + void saveIgnoredNotifications(); + void restoreIgnoredNotifications(); + void setCacheLocation(const LLStringExplicit& location); void onClickSetCache(); @@ -223,6 +226,9 @@ private: void onUpdateFilterTerm( bool force = false ); void collectSearchableItems(); + void filterIgnorableNotifications(); + + std::map<std::string, bool> mIgnorableNotifs; }; class LLPanelPreference : public LLPanel diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.cpp b/indra/newview/llfloatersimpleoutfitsnapshot.cpp new file mode 100644 index 0000000000..bab2efbbd5 --- /dev/null +++ b/indra/newview/llfloatersimpleoutfitsnapshot.cpp @@ -0,0 +1,333 @@ +/** +* @file llfloatersimpleoutfitsnapshot.cpp +* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery +* +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2022, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llfloatersimpleoutfitsnapshot.h" + +#include "llfloaterreg.h" +#include "llimagefiltersmanager.h" +#include "llstatusbar.h" // can_afford_transaction() +#include "llnotificationsutil.h" +#include "llagentbenefits.h" +#include "llviewercontrol.h" + +LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView = NULL; + +const S32 OUTFIT_SNAPSHOT_WIDTH = 256; +const S32 OUTFIT_SNAPSHOT_HEIGHT = 256; + +static LLDefaultChildRegistry::Register<LLSimpleOutfitSnapshotFloaterView> r("simple_snapshot_outfit_floater_view"); + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleOutfitSnapshot::Impl +///---------------------------------------------------------------------------- + +LLSnapshotModel::ESnapshotFormat LLFloaterSimpleOutfitSnapshot::Impl::getImageFormat(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_FORMAT_PNG; +} + +LLSnapshotModel::ESnapshotLayerType LLFloaterSimpleOutfitSnapshot::Impl::getLayerType(LLFloaterSnapshotBase* floater) +{ + return LLSnapshotModel::SNAPSHOT_TYPE_COLOR; +} + +void LLFloaterSimpleOutfitSnapshot::Impl::updateControls(LLFloaterSnapshotBase* floater) +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + updateResolution(floater); + if (previewp) + { + previewp->setSnapshotType(LLSnapshotModel::ESnapshotType::SNAPSHOT_TEXTURE); + previewp->setSnapshotFormat(LLSnapshotModel::ESnapshotFormat::SNAPSHOT_FORMAT_PNG); + previewp->setSnapshotBufferType(LLSnapshotModel::ESnapshotLayerType::SNAPSHOT_TYPE_COLOR); + } +} + +std::string LLFloaterSimpleOutfitSnapshot::Impl::getSnapshotPanelPrefix() +{ + return "panel_outfit_snapshot_"; +} + +void LLFloaterSimpleOutfitSnapshot::Impl::updateResolution(void* data) +{ + LLFloaterSimpleOutfitSnapshot *view = (LLFloaterSimpleOutfitSnapshot *)data; + + if (!view) + { + llassert(view); + return; + } + + S32 width = OUTFIT_SNAPSHOT_WIDTH; + S32 height = OUTFIT_SNAPSHOT_HEIGHT; + + LLSnapshotLivePreview* previewp = getPreviewView(); + if (previewp) + { + S32 original_width = 0, original_height = 0; + previewp->getSize(original_width, original_height); + + if (gSavedSettings.getBOOL("RenderHUDInSnapshot")) + { //clamp snapshot resolution to window size when showing UI HUD in snapshot + width = llmin(width, gViewerWindow->getWindowWidthRaw()); + height = llmin(height, gViewerWindow->getWindowHeightRaw()); + } + + llassert(width > 0 && height > 0); + + previewp->setSize(width, height); + + if (original_width != width || original_height != height) + { + // hide old preview as the aspect ratio could be wrong + checkAutoSnapshot(previewp, FALSE); + previewp->updateSnapshot(TRUE); + } + } +} + +void LLFloaterSimpleOutfitSnapshot::Impl::setStatus(EStatus status, bool ok, const std::string& msg) +{ + switch (status) + { + case STATUS_READY: + mFloater->setCtrlsEnabled(true); + break; + case STATUS_WORKING: + mFloater->setCtrlsEnabled(false); + break; + case STATUS_FINISHED: + mFloater->setCtrlsEnabled(true); + break; + } + + mStatus = status; +} + +///----------------------------------------------------------------re------------ +/// Class LLFloaterSimpleOutfitSnapshot +///---------------------------------------------------------------------------- + +LLFloaterSimpleOutfitSnapshot::LLFloaterSimpleOutfitSnapshot(const LLSD& key) + : LLFloaterSnapshotBase(key), + mOutfitGallery(NULL) +{ + impl = new Impl(this); +} + +LLFloaterSimpleOutfitSnapshot::~LLFloaterSimpleOutfitSnapshot() +{ +} + +BOOL LLFloaterSimpleOutfitSnapshot::postBuild() +{ + getChild<LLUICtrl>("save_btn")->setLabelArg("[UPLOAD_COST]", std::to_string(LLAgentBenefitsMgr::current().getTextureUploadCost())); + + childSetAction("new_snapshot_btn", ImplBase::onClickNewSnapshot, this); + childSetAction("save_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onSend, this)); + childSetAction("cancel_btn", boost::bind(&LLFloaterSimpleOutfitSnapshot::onCancel, this)); + + mThumbnailPlaceholder = getChild<LLUICtrl>("thumbnail_placeholder"); + + // create preview window + LLRect full_screen_rect = getRootView()->getRect(); + LLSnapshotLivePreview::Params p; + p.rect(full_screen_rect); + LLSnapshotLivePreview* previewp = new LLSnapshotLivePreview(p); + LLView* parent_view = gSnapshotFloaterView->getParent(); + + parent_view->removeChild(gSnapshotFloaterView); + // make sure preview is below snapshot floater + parent_view->addChild(previewp); + parent_view->addChild(gSnapshotFloaterView); + + //move snapshot floater to special purpose snapshotfloaterview + gFloaterView->removeChild(this); + gSnapshotFloaterView->addChild(this); + + impl->mPreviewHandle = previewp->getHandle(); + previewp->setContainer(this); + impl->updateControls(this); + impl->setAdvanced(true); + impl->setSkipReshaping(true); + + previewp->mKeepAspectRatio = FALSE; + previewp->setThumbnailPlaceholderRect(getThumbnailPlaceholderRect()); + previewp->setAllowRenderUI(false); + + return TRUE; +} +const S32 PREVIEW_OFFSET_X = 12; +const S32 PREVIEW_OFFSET_Y = 70; + +void LLFloaterSimpleOutfitSnapshot::draw() +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + + if (previewp && (previewp->isSnapshotActive() || previewp->getThumbnailLock())) + { + // don't render snapshot window in snapshot, even if "show ui" is turned on + return; + } + + LLFloater::draw(); + + if (previewp && !isMinimized() && mThumbnailPlaceholder->getVisible()) + { + if(previewp->getThumbnailImage()) + { + bool working = impl->getStatus() == ImplBase::STATUS_WORKING; + const LLRect& thumbnail_rect = getThumbnailPlaceholderRect(); + const S32 thumbnail_w = previewp->getThumbnailWidth(); + const S32 thumbnail_h = previewp->getThumbnailHeight(); + + S32 offset_x = PREVIEW_OFFSET_X; + S32 offset_y = PREVIEW_OFFSET_Y; + + gGL.matrixMode(LLRender::MM_MODELVIEW); + // Apply floater transparency to the texture unless the floater is focused. + F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency(); + LLColor4 color = working ? LLColor4::grey4 : LLColor4::white; + gl_draw_scaled_image(offset_x, offset_y, + thumbnail_w, thumbnail_h, + previewp->getThumbnailImage(), color % alpha); +#if LL_DARWIN + std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "OutfitSnapshotMacMask" : "OutfitSnapshotMacMask2"; +#else + std::string alpha_color = getTransparencyType() == TT_ACTIVE ? "FloaterFocusBackgroundColor" : "DkGray"; +#endif + + previewp->drawPreviewRect(offset_x, offset_y, LLUIColorTable::instance().getColor(alpha_color)); + + gGL.pushUIMatrix(); + LLUI::translate((F32) thumbnail_rect.mLeft, (F32) thumbnail_rect.mBottom); + mThumbnailPlaceholder->draw(); + gGL.popUIMatrix(); + } + } + impl->updateLayout(this); +} + +void LLFloaterSimpleOutfitSnapshot::onOpen(const LLSD& key) +{ + LLSnapshotLivePreview* preview = getPreviewView(); + if (preview) + { + preview->updateSnapshot(TRUE); + } + focusFirstItem(FALSE); + gSnapshotFloaterView->setEnabled(TRUE); + gSnapshotFloaterView->setVisible(TRUE); + gSnapshotFloaterView->adjustToFitScreen(this, FALSE); + + impl->updateControls(this); + impl->setStatus(ImplBase::STATUS_READY); +} + +void LLFloaterSimpleOutfitSnapshot::onCancel() +{ + closeFloater(); +} + +void LLFloaterSimpleOutfitSnapshot::onSend() +{ + S32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); + if (can_afford_transaction(expected_upload_cost)) + { + saveTexture(); + postSave(); + } + else + { + LLSD args; + args["COST"] = llformat("%d", expected_upload_cost); + LLNotificationsUtil::add("ErrorPhotoCannotAfford", args); + inventorySaveFailed(); + } +} + +void LLFloaterSimpleOutfitSnapshot::postSave() +{ + impl->setStatus(ImplBase::STATUS_WORKING); +} + +// static +void LLFloaterSimpleOutfitSnapshot::update() +{ + LLFloaterSimpleOutfitSnapshot* inst = findInstance(); + if (inst != NULL) + { + inst->impl->updateLivePreview(); + } +} + + +// static +LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::findInstance() +{ + return LLFloaterReg::findTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot"); +} + +// static +LLFloaterSimpleOutfitSnapshot* LLFloaterSimpleOutfitSnapshot::getInstance() +{ + return LLFloaterReg::getTypedInstance<LLFloaterSimpleOutfitSnapshot>("simple_outfit_snapshot"); +} + +void LLFloaterSimpleOutfitSnapshot::saveTexture() +{ + LLSnapshotLivePreview* previewp = getPreviewView(); + if (!previewp) + { + llassert(previewp != NULL); + return; + } + + if (mOutfitGallery) + { + mOutfitGallery->onBeforeOutfitSnapshotSave(); + } + previewp->saveTexture(TRUE, getOutfitID().asString()); + if (mOutfitGallery) + { + mOutfitGallery->onAfterOutfitSnapshotSave(); + } + closeFloater(); +} + +///---------------------------------------------------------------------------- +/// Class LLSimpleOutfitSnapshotFloaterView +///---------------------------------------------------------------------------- + +LLSimpleOutfitSnapshotFloaterView::LLSimpleOutfitSnapshotFloaterView(const Params& p) : LLFloaterView(p) +{ +} + +LLSimpleOutfitSnapshotFloaterView::~LLSimpleOutfitSnapshotFloaterView() +{ +} diff --git a/indra/newview/llfloatersimpleoutfitsnapshot.h b/indra/newview/llfloatersimpleoutfitsnapshot.h new file mode 100644 index 0000000000..cc9a6c5d1e --- /dev/null +++ b/indra/newview/llfloatersimpleoutfitsnapshot.h @@ -0,0 +1,129 @@ +/** +* @file llfloatersimpleoutfitsnapshot.h +* @brief Snapshot preview window for saving as an outfit thumbnail in visual outfit gallery +* +* $LicenseInfo:firstyear=2022&license=viewerlgpl$ +* Second Life Viewer Source Code +* Copyright (C) 2022, Linden Research, Inc. +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; +* version 2.1 of the License only. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +* +* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA +* $/LicenseInfo$ +*/ + +#ifndef LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H +#define LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H + +#include "llfloater.h" +#include "llfloatersnapshot.h" +#include "lloutfitgallery.h" +#include "llsnapshotlivepreview.h" + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleOutfitSnapshot +///---------------------------------------------------------------------------- + +class LLFloaterSimpleOutfitSnapshot : public LLFloaterSnapshotBase +{ + LOG_CLASS(LLFloaterSimpleOutfitSnapshot); + +public: + + LLFloaterSimpleOutfitSnapshot(const LLSD& key); + ~LLFloaterSimpleOutfitSnapshot(); + + BOOL postBuild(); + void onOpen(const LLSD& key); + void draw(); + + static void update(); + + static LLFloaterSimpleOutfitSnapshot* getInstance(); + static LLFloaterSimpleOutfitSnapshot* findInstance(); + void saveTexture(); + + const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } + + void setOutfitID(LLUUID id) { mOutfitID = id; } + LLUUID getOutfitID() { return mOutfitID; } + void setGallery(LLOutfitGallery* gallery) { mOutfitGallery = gallery; } + + void postSave(); + + class Impl; + friend class Impl; + +private: + void onSend(); + void onCancel(); + + LLUUID mOutfitID; + LLOutfitGallery* mOutfitGallery; +}; + +///---------------------------------------------------------------------------- +/// Class LLFloaterSimpleOutfitSnapshot::Impl +///---------------------------------------------------------------------------- + +class LLFloaterSimpleOutfitSnapshot::Impl : public LLFloaterSnapshotBase::ImplBase +{ + LOG_CLASS(LLFloaterSimpleOutfitSnapshot::Impl); +public: + Impl(LLFloaterSnapshotBase* floater) + : LLFloaterSnapshotBase::ImplBase(floater) + {} + ~Impl() + {} + void updateResolution(void* data); + + static void onSnapshotUploadFinished(LLFloaterSnapshotBase* floater, bool status); + + LLPanelSnapshot* getActivePanel(LLFloaterSnapshotBase* floater, bool ok_if_not_found = true) { return NULL; } + LLSnapshotModel::ESnapshotFormat getImageFormat(LLFloaterSnapshotBase* floater); + std::string getSnapshotPanelPrefix(); + + void updateControls(LLFloaterSnapshotBase* floater); + + void setStatus(EStatus status, bool ok = true, const std::string& msg = LLStringUtil::null); + +private: + LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater); + void setFinished(bool finished, bool ok = true, const std::string& msg = LLStringUtil::null) {}; +}; + +///---------------------------------------------------------------------------- +/// Class LLSimpleOutfitSnapshotFloaterView +///---------------------------------------------------------------------------- + +class LLSimpleOutfitSnapshotFloaterView : public LLFloaterView +{ +public: + struct Params + : public LLInitParam::Block<Params, LLFloaterView::Params> + { + }; + +protected: + LLSimpleOutfitSnapshotFloaterView(const Params& p); + friend class LLUICtrlFactory; + +public: + virtual ~LLSimpleOutfitSnapshotFloaterView(); +}; + +extern LLSimpleOutfitSnapshotFloaterView* gSimpleOutfitSnapshotFloaterView; + +#endif // LL_LLFLOATERSIMPLEOUTFITSNAPSHOT_H diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 83212230e5..6b9d4580dc 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -176,16 +176,20 @@ void LLFloaterSnapshotBase::ImplBase::updateLayout(LLFloaterSnapshotBase* floate LLUICtrl* thumbnail_placeholder = floaterp->getChild<LLUICtrl>("thumbnail_placeholder"); thumbnail_placeholder->setVisible(mAdvanced); - thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight()); + floaterp->getChild<LLUICtrl>("image_res_text")->setVisible(mAdvanced); floaterp->getChild<LLUICtrl>("file_size_label")->setVisible(mAdvanced); if (floaterp->hasChild("360_label", TRUE)) { floaterp->getChild<LLUICtrl>("360_label")->setVisible(mAdvanced); } - if(!floaterp->isMinimized()) + if (!mSkipReshaping) { - floaterp->reshape(floater_width, floaterp->getRect().getHeight()); + thumbnail_placeholder->reshape(panel_width, thumbnail_placeholder->getRect().getHeight()); + if (!floaterp->isMinimized()) + { + floaterp->reshape(floater_width, floaterp->getRect().getHeight()); + } } bool use_freeze_frame = floaterp->getChild<LLUICtrl>("freeze_frame_check")->getValue().asBoolean(); @@ -1193,7 +1197,7 @@ S32 LLFloaterSnapshotBase::notify(const LLSD& info) // The refresh button is initially hidden. We show it after the first update, // i.e. when preview appears. - if (!mRefreshBtn->getVisible()) + if (mRefreshBtn && !mRefreshBtn->getVisible()) { mRefreshBtn->setVisible(true); } diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index 7ec133ff45..7fc62a2746 100644 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -59,9 +59,9 @@ public: const LLRect& getThumbnailPlaceholderRect() { return mThumbnailPlaceholder->getRect(); } - void setRefreshLabelVisible(bool value) { mRefreshLabel->setVisible(value); } - void setSuccessLabelPanelVisible(bool value) { mSucceessLblPanel->setVisible(value); } - void setFailureLabelPanelVisible(bool value) { mFailureLblPanel->setVisible(value); } + void setRefreshLabelVisible(bool value) { if (mRefreshLabel) mRefreshLabel->setVisible(value); } + void setSuccessLabelPanelVisible(bool value) { if (mSucceessLblPanel) mSucceessLblPanel->setVisible(value); } + void setFailureLabelPanelVisible(bool value) { if (mFailureLblPanel) mFailureLblPanel->setVisible(value); } void inventorySaveFailed(); class ImplBase; @@ -88,6 +88,7 @@ public: mLastToolset(NULL), mAspectRatioCheckOff(false), mNeedRefresh(false), + mSkipReshaping(false), mStatus(STATUS_READY), mFloater(floater) {} @@ -120,6 +121,7 @@ public: static BOOL updatePreviewList(bool initialized); void setAdvanced(bool advanced) { mAdvanced = advanced; } + void setSkipReshaping(bool skip) { mSkipReshaping = skip; } virtual LLSnapshotModel::ESnapshotLayerType getLayerType(LLFloaterSnapshotBase* floater) = 0; virtual void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE); @@ -135,6 +137,7 @@ public: bool mAspectRatioCheckOff; bool mNeedRefresh; bool mAdvanced; + bool mSkipReshaping; EStatus mStatus; }; diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp index b1316e386d..082bb888b1 100644 --- a/indra/newview/llfloatertranslationsettings.cpp +++ b/indra/newview/llfloatertranslationsettings.cpp @@ -289,7 +289,6 @@ void LLFloaterTranslationSettings::onBtnOK() gSavedSettings.setString("TranslationService", getSelectedService()); gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey()); gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey()); - (LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))-> - showTranslationCheckbox(LLTranslate::isTranslationConfigured()); + closeFloater(false); } diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp index 84a1278767..dbeb157323 100644 --- a/indra/newview/llgroupactions.cpp +++ b/indra/newview/llgroupactions.cpp @@ -175,8 +175,7 @@ public: virtual void processGroupData() = 0; protected: LLUUID mGroupId; -private: - bool mRequestProcessed; + bool mRequestProcessed; }; class LLFetchLeaveGroupData: public LLFetchGroupMemberData @@ -189,6 +188,22 @@ public: { LLGroupActions::processLeaveGroupDataResponse(mGroupId); } + void changed(LLGroupChange gc) + { + if (gc == GC_PROPERTIES && !mRequestProcessed) + { + LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupId); + if (!gdatap) + { + LL_WARNS() << "GroupData was NULL" << LL_ENDL; + } + else + { + processGroupData(); + mRequestProcessed = true; + } + } + } }; LLFetchLeaveGroupData* gFetchLeaveGroupData = NULL; diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 0524313a5c..e6845127e3 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -55,6 +55,7 @@ #include "llviewerwindow.h" #include "llviewerregion.h" #include "llvoavatarself.h" +#include "llworld.h" #include "boost/lexical_cast.hpp" #if LL_MSVC @@ -520,8 +521,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, dialog, parent_estate_id, region_id, - position, - true); + position); if (!gIMMgr->isDNDMessageSend(session_id)) { @@ -572,6 +572,15 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, } if (!mute_im) { + bool region_message = false; + if (region_id.isNull()) + { + LLViewerRegion* regionp = LLWorld::instance().getRegionFromID(from_id); + if (regionp) + { + region_message = true; + } + } gIMMgr->addMessage( session_id, from_id, @@ -583,7 +592,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, parent_estate_id, region_id, position, - true); + region_message); } else { @@ -1102,8 +1111,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, IM_SESSION_INVITE, parent_estate_id, region_id, - position, - true); + position); } else { @@ -1128,8 +1136,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id, IM_SESSION_INVITE, parent_estate_id, region_id, - position, - true); + position); } break; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 4d6ebf9cbb..bf9e226244 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -760,7 +760,7 @@ void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_ } } -void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history) +void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history, bool is_region_msg) { LLSD message; message["from"] = from; @@ -769,6 +769,7 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f message["time"] = time; message["index"] = (LLSD::Integer)mMsgs.size(); message["is_history"] = is_history; + message["is_region_msg"] = is_region_msg; LL_DEBUGS("UIUsage") << "addMessage " << " from " << from << " from_id " << from_id << " utf8_text " << utf8_text << " time " << time << " is_history " << is_history << " session mType " << mType << LL_ENDL; if (from_id == gAgent.getID()) @@ -1149,7 +1150,7 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id) mNoUnreadMsgsSignal(arg); } -bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) { +bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg) { LLIMSession* session = findIMSession(session_id); @@ -1159,7 +1160,7 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, return false; } - session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false)); //might want to add date separately + session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false), false, is_region_msg); //might want to add date separately return true; } @@ -1197,9 +1198,9 @@ bool LLIMModel::proccessOnlineOfflineNotification( } bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file /* = true */) { + const std::string& utf8_text, bool log2file, bool is_region_msg) { - LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file); + LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg); if (!session) return false; //good place to add some1 to recent list @@ -1224,7 +1225,7 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co } LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file /* = true */) + const std::string& utf8_text, bool log2file, bool is_region_msg) { LLIMSession* session = findIMSession(session_id); @@ -1240,7 +1241,7 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, from_name = SYSTEM_FROM; } - addToHistory(session_id, from_name, from_id, utf8_text); + addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg); if (log2file) { logToFile(getHistoryFileName(session_id), from_name, from_id, utf8_text); @@ -2663,7 +2664,7 @@ void LLIMMgr::addMessage( U32 parent_estate_id, const LLUUID& region_id, const LLVector3& position, - bool link_name) // If this is true, then we insert the name and link it to a profile + bool is_region_msg) { LLUUID other_participant_id = target_id; @@ -2735,7 +2736,7 @@ void LLIMMgr::addMessage( //<< "*** region_id: " << region_id << std::endl //<< "*** position: " << position << std::endl; - LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str()); + LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, bonus_info.str(), true, is_region_msg); } // Logically it would make more sense to reject the session sooner, in another area of the @@ -2765,7 +2766,7 @@ void LLIMMgr::addMessage( if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message) { - LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg); + LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg); } // Open conversation floater if offline messages are present @@ -3692,8 +3693,7 @@ public: IM_SESSION_INVITE, message_params["parent_estate_id"].asInteger(), message_params["region_id"].asUUID(), - ll_vector3_from_sd(message_params["position"]), - true); + ll_vector3_from_sd(message_params["position"])); if (LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)) { diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h index fdf9806e2e..326e8f22e3 100644 --- a/indra/newview/llimview.h +++ b/indra/newview/llimview.h @@ -81,7 +81,7 @@ public: void sessionInitReplyReceived(const LLUUID& new_session_id); void addMessagesFromHistory(const std::list<LLSD>& history); - void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false); + void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, bool is_region_msg = false); void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction); /** @deprecated */ @@ -208,13 +208,13 @@ public: * and also saved into a file if log2file is specified. * It sends new message signal for each added message. */ - bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true); + bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false); /** * Similar to addMessage(...) above but won't send a signal about a new message added */ LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, - const std::string& utf8_text, bool log2file = true); + const std::string& utf8_text, bool log2file = true, bool is_region_msg = false); /** * Add a system message to an IM Model @@ -292,7 +292,7 @@ private: /** * Add message to a list of message associated with session specified by session_id */ - bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text); + bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false); }; @@ -334,7 +334,7 @@ public: U32 parent_estate_id = 0, const LLUUID& region_id = LLUUID::null, const LLVector3& position = LLVector3::zero, - bool link_name = false); + bool is_region_msg = false); void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index a0bc1035bf..7793b71f56 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -614,7 +614,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const if (cat) { LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, item_id); - if (!cat_br.isItemCopyable()) + if (!cat_br.isItemCopyable(false)) return FALSE; // Skip to the next item in the clipboard continue; @@ -622,7 +622,7 @@ BOOL LLInvFVBridge::isClipboardPasteable() const // Each item must be copyable to be pastable LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id); - if (!item_br.isItemCopyable()) + if (!item_br.isItemCopyable(false)) { return FALSE; } @@ -654,6 +654,11 @@ BOOL LLInvFVBridge::isClipboardPasteableAsLink() const { return FALSE; } + + if (gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID())) + { + return FALSE; + } } const LLViewerInventoryCategory *cat = model->getCategory(objects.at(i)); if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType())) @@ -729,15 +734,15 @@ void hide_context_entries(LLMenuGL& menu, } bool found = false; - menuentry_vec_t::const_iterator itor2; - for (itor2 = entries_to_show.begin(); itor2 != entries_to_show.end(); ++itor2) - { - if (*itor2 == name) - { - found = true; - break; - } - } + + std::string myinput; + std::vector<std::string> mylist{ "a", "b", "c" }; + + menuentry_vec_t::const_iterator itor2 = std::find(entries_to_show.begin(), entries_to_show.end(), name); + if (itor2 != entries_to_show.end()) + { + found = true; + } // Don't allow multiple separators in a row (e.g. such as if there are no items // between two separators). @@ -755,7 +760,21 @@ void hide_context_entries(LLMenuGL& menu, menu_item->setVisible(FALSE); } - menu_item->setEnabled(FALSE); + if (menu_item->getEnabled()) + { + // These should stay enabled unless specifically disabled + const menuentry_vec_t exceptions = { + "Detach From Yourself", + "Wearable And Object Wear", + "Wearable Add", + }; + + menuentry_vec_t::const_iterator itor2 = std::find(exceptions.begin(), exceptions.end(), name); + if (itor2 == exceptions.end()) + { + menu_item->setEnabled(FALSE); + } + } } else { @@ -882,7 +901,8 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, disabled_items.push_back(std::string("Paste")); } - if (gSavedSettings.getBOOL("InventoryLinking")) + static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true); + if (inventory_linking) { items.push_back(std::string("Paste As Link")); if (!isClipboardPasteableAsLink() || (flags & FIRST_SELECTED_ITEM) == 0) @@ -2059,7 +2079,8 @@ BOOL LLItemBridge::removeItem() // we can't do this check because we may have items in a folder somewhere that is // not yet in memory, so we don't want false negatives. (If disabled, then we // know we only have links in the Outfits folder which we explicitly fetch.) - if (!gSavedSettings.getBOOL("InventoryLinking")) + static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true); + if (!inventory_linking) { if (!item->getIsLinkType()) { @@ -2102,22 +2123,24 @@ BOOL LLItemBridge::confirmRemoveItem(const LLSD& notification, const LLSD& respo return FALSE; } -BOOL LLItemBridge::isItemCopyable() const +bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const { - LLViewerInventoryItem* item = getItem(); - if (item) - { - // Can't copy worn objects. - // Worn objects are tied to their inworld conterparts - // Copy of modified worn object will return object with obsolete asset and inventory - if(get_is_item_worn(mUUID)) - { - return FALSE; - } + LLViewerInventoryItem* item = getItem(); + if (!item) + { + return false; + } + // Can't copy worn objects. + // Worn objects are tied to their inworld conterparts + // Copy of modified worn object will return object with obsolete asset and inventory + if (get_is_item_worn(mUUID)) + { + return false; + } - return item->getPermissions().allowCopyBy(gAgent.getID()) || gSavedSettings.getBOOL("InventoryLinking"); - } - return FALSE; + static LLCachedControl<bool> inventory_linking(gSavedSettings, "InventoryLinking", true); + return (can_copy_as_link && inventory_linking) + || item->getPermissions().allowCopyBy(gAgent.getID()); } LLViewerInventoryItem* LLItemBridge::getItem() const @@ -2321,7 +2344,7 @@ BOOL LLFolderBridge::isUpToDate() const return category->getVersion() != LLViewerInventoryCategory::VERSION_UNKNOWN; } -BOOL LLFolderBridge::isItemCopyable() const +bool LLFolderBridge::isItemCopyable(bool can_copy_as_link) const { // Folders are copyable if items in them are, recursively, copyable. @@ -2336,22 +2359,26 @@ BOOL LLFolderBridge::isItemCopyable() const { LLInventoryItem* item = *iter; LLItemBridge item_br(mInventoryPanel.get(), mRoot, item->getUUID()); - if (!item_br.isItemCopyable()) - return FALSE; -} + if (!item_br.isItemCopyable(false)) + { + return false; + } + } // Check the folders LLInventoryModel::cat_array_t cat_array_copy = *cat_array; for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) -{ + { LLViewerInventoryCategory* category = *iter; LLFolderBridge cat_br(mInventoryPanel.get(), mRoot, category->getUUID()); - if (!cat_br.isItemCopyable()) - return FALSE; - } - - return TRUE; - } + if (!cat_br.isItemCopyable(false)) + { + return false; + } + } + + return true; +} BOOL LLFolderBridge::isClipboardPasteable() const { @@ -3768,6 +3795,7 @@ void LLFolderBridge::perform_pasteFromClipboard() LLInventoryObject *obj = model->getObject(item_id); if (obj) { + if (move_is_into_lost_and_found) { if (LLAssetType::AT_CATEGORY == obj->getType()) @@ -4296,7 +4324,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items.push_back(std::string("IM All Contacts In Folder")); } - if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren()) + if (((flags & ITEM_IN_MULTI_SELECTION) == 0) && hasChildren() && (type != LLFolderType::FT_OUTFIT)) { items.push_back(std::string("Ungroup folder items")); } diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h index 0b0ef273e1..bdffecf1c6 100644 --- a/indra/newview/llinventorybridge.h +++ b/indra/newview/llinventorybridge.h @@ -119,7 +119,7 @@ public: //virtual BOOL removeItem() = 0; virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch); virtual void move(LLFolderViewModelItem* new_parent_bridge) {} - virtual BOOL isItemCopyable() const { return FALSE; } + virtual bool isItemCopyable(bool can_copy_as_link = true) const { return false; } virtual BOOL copyToClipboard() const; virtual BOOL cutToClipboard(); virtual bool isCutToClipboard(); @@ -245,7 +245,7 @@ public: virtual BOOL isItemRenameable() const; virtual BOOL renameItem(const std::string& new_name); virtual BOOL removeItem(); - virtual BOOL isItemCopyable() const; + virtual bool isItemCopyable(bool can_copy_as_link = true) const; virtual bool hasChildren() const { return FALSE; } virtual BOOL isUpToDate() const { return TRUE; } virtual LLUIImagePtr getIconOverlay() const; @@ -318,7 +318,7 @@ public: virtual BOOL isItemRemovable() const; virtual BOOL isItemMovable() const ; virtual BOOL isUpToDate() const; - virtual BOOL isItemCopyable() const; + virtual bool isItemCopyable(bool can_copy_as_link = true) const; virtual BOOL isClipboardPasteable() const; virtual BOOL isClipboardPasteableAsLink() const; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 27edc8148e..5755bc692e 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -862,6 +862,9 @@ LLUUID create_folder_for_item(LLInventoryItem* item, const LLUUID& destFolderId) S32 depth_nesting_in_marketplace(LLUUID cur_uuid) { // Get the marketplace listings root, exit with -1 (i.e. not under the marketplace listings root) if none + // Todo: findCategoryUUIDForType is somewhat expensive with large + // flat root folders yet we use depth_nesting_in_marketplace at + // every turn, find a way to correctly cache this id. const LLUUID marketplace_listings_uuid = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); if (marketplace_listings_uuid.isNull()) { @@ -1504,7 +1507,12 @@ void dump_trace(std::string& message, S32 depth, LLError::ELevel log_level) // This function does no deletion of listings but a mere audit and raises issues to the user (through the // optional callback cb). It also returns a boolean, true if things validate, false if issues are raised. // The only inventory changes that are done is to move and sort folders containing no-copy items to stock folders. -bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_t cb, bool fix_hierarchy, S32 depth) +bool validate_marketplacelistings( + LLInventoryCategory* cat, + validation_callback_t cb, + bool fix_hierarchy, + S32 depth, + bool notify_observers) { #if 0 // Used only for debug @@ -1570,7 +1578,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ LLUUID folder_uuid = gInventory.createNewCategory(parent_uuid, LLFolderType::FT_NONE, cat->getName()); LLInventoryCategory* new_cat = gInventory.getCategory(folder_uuid); gInventory.changeCategoryParent(viewer_cat, folder_uuid, false); - result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1); + result &= validate_marketplacelistings(new_cat, cb, fix_hierarchy, depth + 1, notify_observers); return result; } else @@ -1740,7 +1748,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ // Next type update_marketplace_category(parent_uuid); update_marketplace_category(folder_uuid); - gInventory.notifyObservers(); + if (notify_observers) + { + gInventory.notifyObservers(); + } items_vector_it++; } } @@ -1754,7 +1765,7 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ { LLViewerInventoryCategory * viewer_cat = (LLViewerInventoryCategory *) (*iter); gInventory.changeCategoryParent(viewer_cat, parent_uuid, false); - result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth); + result &= validate_marketplacelistings(viewer_cat, cb, fix_hierarchy, depth, false); } } } @@ -1826,7 +1837,10 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ cb(message,depth,LLError::LEVEL_WARN); } gInventory.removeCategory(cat->getUUID()); - gInventory.notifyObservers(); + if (notify_observers) + { + gInventory.notifyObservers(); + } return result && !has_bad_items; } } @@ -1840,11 +1854,14 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_ for (LLInventoryModel::cat_array_t::iterator iter = cat_array_copy.begin(); iter != cat_array_copy.end(); iter++) { LLInventoryCategory* category = *iter; - result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1); + result &= validate_marketplacelistings(category, cb, fix_hierarchy, depth + 1, false); } update_marketplace_category(cat->getUUID(), true, true); - gInventory.notifyObservers(); + if (notify_observers) + { + gInventory.notifyObservers(); + } return result && !has_bad_items; } @@ -2583,8 +2600,62 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root } std::set<LLUUID> selected_uuid_set = LLAvatarActions::getInventorySelectedUUIDs(); + + // copy list of applicable items into a vector for bulk handling uuid_vec_t ids; - std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids)); + if (action == "wear" || action == "wear_add") + { + const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH); + const LLUUID mp_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false); + std::copy_if(selected_uuid_set.begin(), + selected_uuid_set.end(), + std::back_inserter(ids), + [trash_id, mp_id](LLUUID id) + { + if (get_is_item_worn(id) + || LLAppearanceMgr::instance().getIsInCOF(id) + || gInventory.isObjectDescendentOf(id, trash_id)) + { + return false; + } + if (mp_id.notNull() && gInventory.isObjectDescendentOf(id, mp_id)) + { + return false; + } + LLInventoryObject* obj = (LLInventoryObject*)gInventory.getObject(id); + if (!obj) + { + return false; + } + if (obj->getIsLinkType() && gInventory.isObjectDescendentOf(obj->getLinkedUUID(), trash_id)) + { + return false; + } + if (obj->getIsLinkType() && LLAssetType::lookupIsLinkType(obj->getType())) + { + // missing + return false; + } + return true; + } + ); + } + else if (isRemoveAction(action)) + { + std::copy_if(selected_uuid_set.begin(), + selected_uuid_set.end(), + std::back_inserter(ids), + [](LLUUID id) + { + return get_is_item_worn(id); + } + ); + } + else + { + std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids)); + } + // Check for actions that get handled in bulk if (action == "wear") { diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h index ba9f157e47..56ad6f6496 100644 --- a/indra/newview/llinventoryfunctions.h +++ b/indra/newview/llinventoryfunctions.h @@ -87,7 +87,7 @@ bool can_move_item_to_marketplace(const LLInventoryCategory* root_folder, LLInve bool can_move_folder_to_marketplace(const LLInventoryCategory* root_folder, LLInventoryCategory* dest_folder, LLInventoryCategory* inv_cat, std::string& tooltip_msg, S32 bundle_size = 1, bool check_items = true, bool from_paste = false); bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_folder, bool copy = false); bool move_folder_to_marketplacelistings(LLInventoryCategory* inv_cat, const LLUUID& dest_folder, bool copy = false, bool move_no_copy_items = false); -bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1); +bool validate_marketplacelistings(LLInventoryCategory* inv_cat, validation_callback_t cb = NULL, bool fix_hierarchy = true, S32 depth = -1, bool notify_observers = true); S32 depth_nesting_in_marketplace(LLUUID cur_uuid); LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth); S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false); diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index fab7ae8f1a..6ba04cdff2 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -1851,9 +1851,13 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent) mChangedItemIDs.insert(referent); } - // Fix me: From DD-81, probably shouldn't be here, instead - // should be somewhere in an observer - update_marketplace_category(referent, false); + if (mask != LLInventoryObserver::LABEL) + { + // Fix me: From DD-81, probably shouldn't be here, instead + // should be somewhere in an observer or in + // LLMarketplaceInventoryObserver::onIdleProcessQueue + update_marketplace_category(referent, false); + } if (mask & LLInventoryObserver::ADD) { diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp index 31e76267e6..d790c6f95e 100644 --- a/indra/newview/lllandmarklist.cpp +++ b/indra/newview/lllandmarklist.cpp @@ -39,12 +39,6 @@ // Globals LLLandmarkList gLandmarkList; -// number is mostly arbitrary, but it should be below DEFAULT_QUEUE_SIZE pool size, -// which is 4096, to not overfill the pool if user has more than 4K of landmarks -// and it should leave some space for other potential simultaneous asset request -const S32 MAX_SIMULTANEOUS_REQUESTS = 512; - - //////////////////////////////////////////////////////////////////////////// // LLLandmarkList @@ -83,12 +77,6 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t loaded_callback_map_t::value_type vt(asset_uuid, cb); mLoadedCallbackMap.insert(vt); } - - if ( mWaitList.find(asset_uuid) != mWaitList.end() ) - { - // Landmark is sheduled for download, but not requested yet - return NULL; - } landmark_requested_list_t::iterator iter = mRequestedList.find(asset_uuid); if (iter != mRequestedList.end()) @@ -100,17 +88,6 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t } } - if (mRequestedList.size() > MAX_SIMULTANEOUS_REQUESTS) - { - // Workarounds for corutines pending list size limit: - // Postpone download till queue is emptier. - // Coroutines have own built in 'pending' list, but unfortunately - // it is too small compared to potential amount of landmarks - // or assets. - mWaitList.insert(asset_uuid); - return NULL; - } - mRequestedList[asset_uuid] = gFrameTimeSeconds; // Note that getAssetData can callback immediately and cleans mRequestedList @@ -197,33 +174,6 @@ void LLLandmarkList::processGetAssetReply( gLandmarkList.mRequestedList.erase(uuid); //mBadList effectively blocks any load, so no point keeping id in requests gLandmarkList.eraseCallbacks(uuid); } - - // getAssetData can fire callback immediately, causing - // a recursion which is suboptimal for very large wait list. - // 'scheduling' indicates that we are inside request and - // shouldn't be launching more requests. - static bool scheduling = false; - if (!scheduling && !gLandmarkList.mWaitList.empty()) - { - scheduling = true; - while (!gLandmarkList.mWaitList.empty() && gLandmarkList.mRequestedList.size() < MAX_SIMULTANEOUS_REQUESTS) - { - // start new download from wait list - landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin(); - LLUUID asset_uuid = *iter; - gLandmarkList.mWaitList.erase(iter); - - // add to mRequestedList before calling getAssetData() - gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds; - - // Note that getAssetData can callback immediately and cleans mRequestedList - gAssetStorage->getAssetData(asset_uuid, - LLAssetType::AT_LANDMARK, - LLLandmarkList::processGetAssetReply, - NULL); - } - scheduling = false; - } } BOOL LLLandmarkList::isAssetInLoadedCallbackMap(const LLUUID& asset_uuid) diff --git a/indra/newview/lllandmarklist.h b/indra/newview/lllandmarklist.h index f5fa958204..b50332b215 100644 --- a/indra/newview/lllandmarklist.h +++ b/indra/newview/lllandmarklist.h @@ -72,7 +72,6 @@ protected: typedef std::set<LLUUID> landmark_uuid_list_t; landmark_uuid_list_t mBadList; - landmark_uuid_list_t mWaitList; typedef std::map<LLUUID,F32> landmark_requested_list_t; landmark_requested_list_t mRequestedList; diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp index dd4ae4d201..2d726409c6 100644 --- a/indra/newview/llmarketplacefunctions.cpp +++ b/indra/newview/llmarketplacefunctions.cpp @@ -30,6 +30,7 @@ #include "llagent.h" #include "llbufferstream.h" +#include "llcallbacklist.h" #include "llinventoryfunctions.h" #include "llinventoryobserver.h" #include "llnotificationsutil.h" @@ -605,20 +606,67 @@ public: LLMarketplaceInventoryObserver() {} virtual ~LLMarketplaceInventoryObserver() {} virtual void changed(U32 mask); + +private: + static void onIdleProcessQueue(void *userdata); + + // doesn't hold just marketplace related ids + static std::set<LLUUID> sAddQueue; + static std::set<LLUUID> sStructureQueue; + static bool sProcessingQueue; }; +std::set<LLUUID> LLMarketplaceInventoryObserver::sAddQueue; +std::set<LLUUID> LLMarketplaceInventoryObserver::sStructureQueue; +bool LLMarketplaceInventoryObserver::sProcessingQueue = false; + void LLMarketplaceInventoryObserver::changed(U32 mask) { - // When things are added to the marketplace, we might need to re-validate and fix the containing listings - if (mask & LLInventoryObserver::ADD) + if (mask & LLInventoryObserver::ADD && LLMarketplaceData::instance().hasValidationWaiting()) { + // When things are added to the marketplace, we might need to re-validate and fix the containing listings + // just add whole list even if it contains items and non-marketplace folders const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); - - std::set<LLUUID>::const_iterator id_it = changed_items.begin(); - std::set<LLUUID>::const_iterator id_end = changed_items.end(); + sAddQueue.insert(changed_items.begin(), changed_items.end()); + } + + if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE)) + { + // When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder: + // * stock counts changing : no copy items coming in and out will change the stock count on folders + // * version and listing folders : moving those might invalidate the marketplace data itself + // Since we should cannot raise inventory change while the observer is called (the list will be cleared + // once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied. + const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); + sStructureQueue.insert(changed_items.begin(), changed_items.end()); + } + + if (!sProcessingQueue && (!sAddQueue.empty() || !sStructureQueue.empty())) + { + gIdleCallbacks.addFunction(onIdleProcessQueue, NULL); + // can do without sProcessingQueue, but it's usufull for simplicity and reliability + sProcessingQueue = true; + } +} + +void LLMarketplaceInventoryObserver::onIdleProcessQueue(void *userdata) +{ + U64 start_time = LLTimer::getTotalTime(); // microseconds + const U64 MAX_PROCESSING_TIME = 1000; + U64 stop_time = start_time + MAX_PROCESSING_TIME; + + if (!sAddQueue.empty()) + { + // Make a copy of sAddQueue since decrementValidationWaiting + // can theoretically add more items + std::set<LLUUID> add_queue(sAddQueue); + sAddQueue.clear(); + + std::set<LLUUID>::const_iterator id_it = add_queue.begin(); + std::set<LLUUID>::const_iterator id_end = add_queue.end(); // First, count the number of items in this list... S32 count = 0; - for (;id_it != id_end; ++id_it) + for (; id_it != id_end; ++id_it) { LLInventoryObject* obj = gInventory.getObject(*id_it); if (obj && (LLAssetType::AT_CATEGORY != obj->getType())) @@ -629,56 +677,58 @@ void LLMarketplaceInventoryObserver::changed(U32 mask) // Then, decrement the folders of that amount // Note that of all of those, only one folder will be a listing folder (if at all). // The other will be ignored by the decrement method. - id_it = changed_items.begin(); - for (;id_it != id_end; ++id_it) + id_it = add_queue.begin(); + for (; id_it != id_end; ++id_it) { LLInventoryObject* obj = gInventory.getObject(*id_it); if (obj && (LLAssetType::AT_CATEGORY == obj->getType())) { - LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(),count); + // can trigger notifyObservers + LLMarketplaceData::instance().decrementValidationWaiting(obj->getUUID(), count); } } - } - - // When things are changed in the inventory, this can trigger a host of changes in the marketplace listings folder: - // * stock counts changing : no copy items coming in and out will change the stock count on folders - // * version and listing folders : moving those might invalidate the marketplace data itself - // Since we should cannot raise inventory change while the observer is called (the list will be cleared - // once observers are called) we need to raise a flag in the inventory to signal that things have been dirtied. - - if (mask & (LLInventoryObserver::INTERNAL | LLInventoryObserver::STRUCTURE)) - { - const std::set<LLUUID>& changed_items = gInventory.getChangedIDs(); - - std::set<LLUUID>::const_iterator id_it = changed_items.begin(); - std::set<LLUUID>::const_iterator id_end = changed_items.end(); - for (;id_it != id_end; ++id_it) + } + + while (!sStructureQueue.empty() && LLTimer::getTotalTime() < stop_time) + { + std::set<LLUUID>::const_iterator id_it = sStructureQueue.begin(); + LLInventoryObject* obj = gInventory.getObject(*id_it); + if (obj) { - LLInventoryObject* obj = gInventory.getObject(*id_it); - if (obj) + if (LLAssetType::AT_CATEGORY == obj->getType()) { - if (LLAssetType::AT_CATEGORY == obj->getType()) + // If it's a folder known to the marketplace, let's check it's in proper shape + if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it)) { - // If it's a folder known to the marketplace, let's check it's in proper shape - if (LLMarketplaceData::instance().isListed(*id_it) || LLMarketplaceData::instance().isVersionFolder(*id_it)) - { - LLInventoryCategory* cat = (LLInventoryCategory*)(obj); - validate_marketplacelistings(cat); - } + LLInventoryCategory* cat = (LLInventoryCategory*)(obj); + // can trigger notifyObservers + // can cause more structural changes + validate_marketplacelistings(cat); } - else + } + else + { + // If it's not a category, it's an item... + LLInventoryItem* item = (LLInventoryItem*)(obj); + // If it's a no copy item, we may need to update the label count of marketplace listings + if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) { - // If it's not a category, it's an item... - LLInventoryItem* item = (LLInventoryItem*)(obj); - // If it's a no copy item, we may need to update the label count of marketplace listings - if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID(), gAgent.getGroupID())) - { - LLMarketplaceData::instance().setDirtyCount(); - } + LLMarketplaceData::instance().setDirtyCount(); } } } - } + + // sStructureQueue could have been modified in validate_marketplacelistings + // adding items does not invalidate existing iterator + sStructureQueue.erase(id_it); + } + + if (LLApp::isExiting() || (sAddQueue.empty() && sStructureQueue.empty())) + { + // Nothing to do anymore + gIdleCallbacks.deleteFunction(onIdleProcessQueue, NULL); + sProcessingQueue = false; + } } // Tuple == Item diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h index 088507d850..24fdc5e0ad 100644 --- a/indra/newview/llmarketplacefunctions.h +++ b/indra/newview/llmarketplacefunctions.h @@ -242,6 +242,7 @@ public: void setUpdating(const LLUUID& folder_id, bool isUpdating); // Used to decide when to run a validation on listing folders + bool hasValidationWaiting() { return mValidationWaitingList.size() > 0; } void setValidationWaiting(const LLUUID& folder_id, S32 count); void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1); diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index f419e2e06d..1facbbf37c 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -41,7 +41,7 @@ #include "llfilepicker.h" #include "llfloaterperms.h" #include "llfloaterreg.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llimagedimensionsinfo.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" @@ -1386,8 +1386,8 @@ void LLOutfitGallery::onSelectPhoto(LLUUID selected_outfit_id) void LLOutfitGallery::onTakeSnapshot(LLUUID selected_outfit_id) { - LLFloaterReg::toggleInstanceOrBringToFront("outfit_snapshot"); - LLFloaterOutfitSnapshot* snapshot_floater = LLFloaterOutfitSnapshot::getInstance(); + LLFloaterReg::toggleInstanceOrBringToFront("simple_outfit_snapshot"); + LLFloaterSimpleOutfitSnapshot* snapshot_floater = LLFloaterSimpleOutfitSnapshot::getInstance(); if (snapshot_floater) { snapshot_floater->setOutfitID(selected_outfit_id); diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp index e1818cc68b..416857bd30 100644 --- a/indra/newview/llpanelmediasettingsgeneral.cpp +++ b/indra/newview/llpanelmediasettingsgeneral.cpp @@ -454,7 +454,8 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_ LLViewerMedia::getInstance()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID()); if(media_impl) { - media_impl->navigateHome(); + media_impl->setPriority(LLPluginClassMedia::PRIORITY_NORMAL); + media_impl->navigateHome(); return true; } } diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 0bfc1297d3..bc7933d84b 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -93,6 +93,8 @@ enum { MI_HOLE_COUNT }; +const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters + //static const std::string LEGACY_FULLBRIGHT_DESC =LLTrans::getString("Fullbright"); BOOL LLPanelObject::postBuild() @@ -1685,6 +1687,16 @@ void LLPanelObject::sendPosition(BOOL btn_down) mCtrlPosZ->set(LLWorld::getInstance()->resolveLandHeightAgent(newpos) + 1.f); } } + else + { + if (newpos.length() > MAX_ATTACHMENT_DIST) + { + newpos.clampLength(MAX_ATTACHMENT_DIST); + mCtrlPosX->set(newpos.mV[VX]); + mCtrlPosY->set(newpos.mV[VY]); + mCtrlPosZ->set(newpos.mV[VZ]); + } + } // Make sure new position is in a valid region, so the object // won't get dumped by the simulator. @@ -2191,6 +2203,10 @@ void LLPanelObject::onPastePos() mClipboardPos.mV[VY] = llclamp(mClipboardPos.mV[VY], 0.f, max_width); //height will get properly clamped by sendPosition } + else + { + mClipboardPos.clampLength(MAX_ATTACHMENT_DIST); + } mCtrlPosX->set( mClipboardPos.mV[VX] ); mCtrlPosY->set( mClipboardPos.mV[VY] ); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index cfaa9456be..fff25c6c61 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -131,7 +131,7 @@ public: virtual BOOL removeItem(); virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch); virtual void move(LLFolderViewModelItem* parent_listener); - virtual BOOL isItemCopyable() const; + virtual bool isItemCopyable(bool can_copy_as_link = true) const; virtual BOOL copyToClipboard() const; virtual BOOL cutToClipboard(); virtual BOOL isClipboardPasteable() const; @@ -439,10 +439,10 @@ void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener) { } -BOOL LLTaskInvFVBridge::isItemCopyable() const +bool LLTaskInvFVBridge::isItemCopyable(bool can_link) const { LLInventoryItem* item = findItem(); - if(!item) return FALSE; + if(!item) return false; return gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE); } diff --git a/indra/newview/llpanelpresetscamerapulldown.cpp b/indra/newview/llpanelpresetscamerapulldown.cpp index 183123e534..4c9c30160c 100644 --- a/indra/newview/llpanelpresetscamerapulldown.cpp +++ b/indra/newview/llpanelpresetscamerapulldown.cpp @@ -127,7 +127,10 @@ void LLPanelPresetsCameraPulldown::onRowClick(const LLSD& user_data) LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL; LLFloaterCamera::switchToPreset(name); - setVisible(FALSE); + // Scroll grabbed focus, drop it to prevent selection of parent menu + setFocus(FALSE); + + setVisible(FALSE); } else { diff --git a/indra/newview/llpanelpresetspulldown.cpp b/indra/newview/llpanelpresetspulldown.cpp index d52ad8056f..23e4fa8887 100644 --- a/indra/newview/llpanelpresetspulldown.cpp +++ b/indra/newview/llpanelpresetspulldown.cpp @@ -122,6 +122,9 @@ void LLPanelPresetsPulldown::onRowClick(const LLSD& user_data) LL_DEBUGS() << "selected '" << name << "'" << LL_ENDL; LLPresetsManager::getInstance()->loadPreset(PRESETS_GRAPHIC, name); + // Scroll grabbed focus, drop it to prevent selection of parent menu + setFocus(FALSE); + setVisible(FALSE); } else diff --git a/indra/newview/llpanelpulldown.cpp b/indra/newview/llpanelpulldown.cpp index 4de6ee8182..075278f44c 100644 --- a/indra/newview/llpanelpulldown.cpp +++ b/indra/newview/llpanelpulldown.cpp @@ -51,6 +51,7 @@ void LLPanelPulldown::onMouseEnter(S32 x, S32 y, MASK mask) /*virtual*/ void LLPanelPulldown::onTopLost() { + setFocus(FALSE); // drop focus to prevent transfer to parent setVisible(FALSE); } @@ -113,6 +114,7 @@ void LLPanelPulldown::draw() if (alpha == 0.f) { + setFocus(FALSE); // drop focus to prevent transfer to parent setVisible(FALSE); } } diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp index 0287c07f96..c297cac771 100644 --- a/indra/newview/llpathfindingnavmesh.cpp +++ b/indra/newview/llpathfindingnavmesh.cpp @@ -143,7 +143,7 @@ void LLPathfindingNavMesh::handleNavMeshResult(const LLSD &pContent, U32 pNavMes unsigned int binSize = value.size(); std::string newStr(reinterpret_cast<const char *>(&value[0]), binSize); std::istringstream streamdecomp( newStr ); - unsigned int decompBinSize = 0; + size_t decompBinSize = 0; bool valid = false; U8* pUncompressedNavMeshContainer = unzip_llsdNavMesh( valid, decompBinSize, streamdecomp, binSize ) ; if ( !valid ) diff --git a/indra/newview/llscripteditor.cpp b/indra/newview/llscripteditor.cpp index c6bb2f19dd..140cbbedbe 100644 --- a/indra/newview/llscripteditor.cpp +++ b/indra/newview/llscripteditor.cpp @@ -187,82 +187,8 @@ void LLScriptEditor::drawSelectionBackground() // Draw selection even if we don't have keyboard focus for search/replace if( hasSelection() && !mLineInfoList.empty()) { - std::vector<LLRect> selection_rects; - - S32 selection_left = llmin( mSelectionStart, mSelectionEnd ); - S32 selection_right = llmax( mSelectionStart, mSelectionEnd ); - - // Skip through the lines we aren't drawing. - LLRect content_display_rect = getVisibleDocumentRect(); - - // binary search for line that starts before top of visible buffer - line_list_t::const_iterator line_iter = std::lower_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mTop, LLTextBase::compare_bottom()); - line_list_t::const_iterator end_iter = std::upper_bound(mLineInfoList.begin(), mLineInfoList.end(), content_display_rect.mBottom, LLTextBase::compare_top()); - - bool done = false; - - // Find the coordinates of the selected area - for (;line_iter != end_iter && !done; ++line_iter) - { - // is selection visible on this line? - if (line_iter->mDocIndexEnd > selection_left && line_iter->mDocIndexStart < selection_right) - { - segment_set_t::iterator segment_iter; - S32 segment_offset; - getSegmentAndOffset(line_iter->mDocIndexStart, &segment_iter, &segment_offset); - - LLRect selection_rect; - selection_rect.mLeft = line_iter->mRect.mLeft; - selection_rect.mRight = line_iter->mRect.mLeft; - selection_rect.mBottom = line_iter->mRect.mBottom; - selection_rect.mTop = line_iter->mRect.mTop; - - for(;segment_iter != mSegments.end(); ++segment_iter, segment_offset = 0) - { - LLTextSegmentPtr segmentp = *segment_iter; - - S32 segment_line_start = segmentp->getStart() + segment_offset; - S32 segment_line_end = llmin(segmentp->getEnd(), line_iter->mDocIndexEnd); - - if (segment_line_start > segment_line_end) break; - - S32 segment_width = 0; - S32 segment_height = 0; - - // if selection after beginning of segment - if(selection_left >= segment_line_start) - { - S32 num_chars = llmin(selection_left, segment_line_end) - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mLeft += segment_width; - } - - // if selection_right == segment_line_end then that means we are the first character of the next segment - // or first character of the next line, in either case we want to add the length of the current segment - // to the selection rectangle and continue. - // if selection right > segment_line_end then selection spans end of current segment... - if (selection_right >= segment_line_end) - { - // extend selection slightly beyond end of line - // to indicate selection of newline character (use "n" character to determine width) - S32 num_chars = segment_line_end - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mRight += segment_width; - } - // else if selection ends on current segment... - else - { - S32 num_chars = selection_right - segment_line_start; - segmentp->getDimensions(segment_offset, num_chars, segment_width, segment_height); - selection_rect.mRight += segment_width; - - break; - } - } - selection_rects.push_back(selection_rect); - } - } - + std::vector<LLRect> selection_rects = getSelctionRects(); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); const LLColor4& color = mReadOnly ? mReadOnlyFgColor : mFgColor; F32 alpha = hasFocus() ? 0.7f : 0.3f; @@ -272,6 +198,7 @@ void LLScriptEditor::drawSelectionBackground() (1.f + color.mV[VGREEN]) * 0.5f, (1.f + color.mV[VBLUE]) * 0.5f, alpha); + LLRect content_display_rect = getVisibleDocumentRect(); for (std::vector<LLRect>::iterator rect_it = selection_rects.begin(); rect_it != selection_rects.end(); diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h index 8c0d70c16c..ec0de1fbfd 100644 --- a/indra/newview/llsky.h +++ b/indra/newview/llsky.h @@ -39,7 +39,6 @@ class LLViewerCamera; class LLVOWLSky; -class LLVOWLClouds; class LLSky diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 8134187c21..ed7e18fadc 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -233,7 +233,7 @@ bool LLSnapshotLivePreview::setSnapshotQuality(S32 quality, bool set_by_user) return false; } -void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) +void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color) { F32 line_width ; glGetFloatv(GL_LINE_WIDTH, &line_width) ; @@ -246,7 +246,6 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y) //draw four alpha rectangles to cover areas outside of the snapshot image if(!mKeepAspectRatio) { - LLColor4 alpha_color(0.5f, 0.5f, 0.5f, 0.8f) ; S32 dwl = 0, dwr = 0 ; if(mThumbnailWidth > mPreviewRect.getWidth()) { diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index 683cd016d8..1f81307976 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -112,7 +112,7 @@ public: BOOL setThumbnailImageSize() ; void generateThumbnailImage(BOOL force_update = FALSE) ; void resetThumbnailImage() { mThumbnailImage = NULL ; } - void drawPreviewRect(S32 offset_x, S32 offset_y) ; + void drawPreviewRect(S32 offset_x, S32 offset_y, LLColor4 alpha_color = LLColor4(0.5f, 0.5f, 0.5f, 0.8f)); void prepareFreezeFrame(); LLViewerTexture* getBigThumbnailImage(); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 054e9530d4..1dd5c5cbe5 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1285,9 +1285,6 @@ bool idle_startup() // Initialize classes w/graphics stuff. // LLViewerStatsRecorder::instance(); // Since textures work in threads - gTextureList.doPrefetchImages(); - display_startup(); - LLSurface::initClasses(); display_startup(); @@ -1432,6 +1429,15 @@ bool idle_startup() if (STATE_SEED_CAP_GRANTED == LLStartUp::getStartupState()) { display_startup(); + + // These textures are not warrantied to be cached, so needs + // to hapen with caps granted + gTextureList.doPrefetchImages(); + + // will init images, should be done with caps, but before gSky.init() + LLEnvironment::getInstance()->initSingleton(); + + display_startup(); update_texture_fetch(); display_startup(); @@ -2526,8 +2532,6 @@ void use_circuit_callback(void**, S32 result) void register_viewer_callbacks(LLMessageSystem* msg) { msg->setHandlerFuncFast(_PREHASH_LayerData, process_layer_data ); - msg->setHandlerFuncFast(_PREHASH_ImageData, LLViewerTextureList::receiveImageHeader ); - msg->setHandlerFuncFast(_PREHASH_ImagePacket, LLViewerTextureList::receiveImagePacket ); msg->setHandlerFuncFast(_PREHASH_ObjectUpdate, process_object_update ); msg->setHandlerFunc("ObjectUpdateCompressed", process_compressed_object_update ); msg->setHandlerFunc("ObjectUpdateCached", process_cached_object_update ); @@ -2913,6 +2917,7 @@ void reset_login() gAgentWearables.cleanup(); gAgentCamera.cleanup(); gAgent.cleanup(); + gSky.cleanup(); // mVOSkyp is an inworld object. LLWorld::getInstance()->resetClass(); if ( gViewerWindow ) diff --git a/indra/newview/llsurfacepatch.cpp b/indra/newview/llsurfacepatch.cpp index aeefcd6fb8..449d3d95c8 100644 --- a/indra/newview/llsurfacepatch.cpp +++ b/indra/newview/llsurfacepatch.cpp @@ -714,7 +714,7 @@ BOOL LLSurfacePatch::updateTexture() { mVObjp->dirtyGeom(); gPipeline.markGLRebuild(mVObjp); - return TRUE; + return !mSTexUpdate; } } } diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp index 9403e73b87..5c6f7254f2 100644 --- a/indra/newview/lltexturecache.cpp +++ b/indra/newview/lltexturecache.cpp @@ -859,12 +859,12 @@ LLTextureCache::~LLTextureCache() ////////////////////////////////////////////////////////////////////////////// //virtual -S32 LLTextureCache::update(F32 max_time_ms) +size_t LLTextureCache::update(F32 max_time_ms) { static LLFrameTimer timer ; static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds. - S32 res; + size_t res; res = LLWorkerThread::update(max_time_ms); mListMutex.lock(); @@ -1646,6 +1646,12 @@ void LLTextureCache::purgeAllTextures(bool purge_directories) { gDirUtilp->deleteFilesInDir(dirname, mask); } +#if LL_WINDOWS + // Texture cache can be large and can take a while to remove + // assure OS that processes is alive and not hanging + MSG msg; + PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE | PM_NOYIELD); +#endif } gDirUtilp->deleteFilesInDir(mTexturesDirName, mask); // headers, fast cache if (purge_directories) diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h index e1c752b58e..b6ace467c7 100644 --- a/indra/newview/lltexturecache.h +++ b/indra/newview/lltexturecache.h @@ -113,7 +113,7 @@ public: LLTextureCache(bool threaded); ~LLTextureCache(); - /*virtual*/ S32 update(F32 max_time_ms); + /*virtual*/ size_t update(F32 max_time_ms); void purgeCache(ELLPath location, bool remove_dir = true); void setReadOnly(BOOL read_only) ; diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 0edaf40c66..6f6ca2be9b 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -282,7 +282,6 @@ static const char* e_state_name[] = "LOAD_FROM_TEXTURE_CACHE", "CACHE_POST", "LOAD_FROM_NETWORK", - "LOAD_FROM_SIMULATOR", "WAIT_HTTP_RESOURCE", "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", @@ -456,7 +455,6 @@ public: LOAD_FROM_TEXTURE_CACHE, CACHE_POST, LOAD_FROM_NETWORK, - LOAD_FROM_SIMULATOR, WAIT_HTTP_RESOURCE, // Waiting for HTTP resources WAIT_HTTP_RESOURCE2, // Waiting for HTTP resources SEND_HTTP_REQ, // Commit to sending as HTTP @@ -497,8 +495,6 @@ private: // Locks: Mw void clearPackets(); - // Locks: Mw - void setupPacketData(); // Locks: Mw (ctor invokes without lock) U32 calcWorkPriority(); @@ -507,10 +503,6 @@ private: void removeFromCache(); // Threads: Ttf - // Locks: Mw - bool processSimulatorPackets(); - - // Threads: Ttf bool writeToCacheComplete(); // Threads: Ttf @@ -612,8 +604,7 @@ private: BOOL mHaveAllData; BOOL mInLocalCache; BOOL mInCache; - bool mCanUseHTTP, - mCanUseNET ; //can get from asset server. + bool mCanUseHTTP; S32 mRetryAttempt; S32 mActiveCount; LLCore::HttpStatus mGetStatus; @@ -885,7 +876,6 @@ const char* sStateDescs[] = { "LOAD_FROM_TEXTURE_CACHE", "CACHE_POST", "LOAD_FROM_NETWORK", - "LOAD_FROM_SIMULATOR", "WAIT_HTTP_RESOURCE", "WAIT_HTTP_RESOURCE2", "SEND_HTTP_REQ", @@ -897,7 +887,7 @@ const char* sStateDescs[] = { "DONE" }; -const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::LOAD_FROM_SIMULATOR, +const std::set<S32> LOGGED_STATES = { LLTextureFetchWorker::LOAD_FROM_TEXTURE_CACHE, LLTextureFetchWorker::LOAD_FROM_NETWORK, LLTextureFetchWorker::WAIT_HTTP_REQ, LLTextureFetchWorker::DECODE_IMAGE_UPDATE, LLTextureFetchWorker::WAIT_ON_WRITE }; // static @@ -972,8 +962,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher, mResourceWaitCount(0U), mFetchRetryPolicy(10.0,3600.0,2.0,10) { - mCanUseNET = mUrl.empty() ; - calcWorkPriority(); mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL; // LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL; @@ -1037,39 +1025,6 @@ void LLTextureFetchWorker::clearPackets() mFirstPacket = 0; } -// Locks: Mw -void LLTextureFetchWorker::setupPacketData() -{ - S32 data_size = 0; - if (mFormattedImage.notNull()) - { - data_size = mFormattedImage->getDataSize(); - } - if (data_size > 0) - { - // Only used for simulator requests - mFirstPacket = (data_size - FIRST_PACKET_SIZE) / MAX_IMG_PACKET_SIZE + 1; - if (FIRST_PACKET_SIZE + (mFirstPacket-1) * MAX_IMG_PACKET_SIZE != data_size) - { - LL_WARNS(LOG_TXT) << "Bad CACHED TEXTURE size: " << data_size << " removing." << LL_ENDL; - removeFromCache(); - resetFormattedData(); - clearPackets(); - } - else if (mFileSize > 0) - { - mLastPacket = mFirstPacket-1; - mTotalPackets = (mFileSize - FIRST_PACKET_SIZE + MAX_IMG_PACKET_SIZE-1) / MAX_IMG_PACKET_SIZE + 1; - } - else - { - // This file was cached using HTTP so we have to refetch the first packet - resetFormattedData(); - clearPackets(); - } - } -} - // Locks: Mw (ctor invokes without lock) U32 LLTextureFetchWorker::calcWorkPriority() { @@ -1177,13 +1132,13 @@ bool LLTextureFetchWorker::doWork(S32 param) if(mImagePriority < F_ALMOST_ZERO) { - if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR) + if (mState == INIT || mState == LOAD_FROM_NETWORK) { LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL; return true; // abort } } - if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP) + if(mState > CACHE_POST && !mCanUseHTTP) { //nowhere to get data, abort. LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL; @@ -1387,10 +1342,14 @@ bool LLTextureFetchWorker::doWork(S32 param) if ( use_http && mCanUseHTTP && mUrl.empty())//get http url. { LLViewerRegion* region = NULL; - if (mHost.isInvalid()) - region = gAgent.getRegion(); - else - region = LLWorld::getInstance()->getRegion(mHost); + if (mHost.isInvalid()) + { + region = gAgent.getRegion(); + } + else if (LLWorld::instanceExists()) + { + region = LLWorld::getInstance()->getRegion(mHost); + } if (region) { @@ -1408,14 +1367,14 @@ bool LLTextureFetchWorker::doWork(S32 param) else { mCanUseHTTP = false ; - LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL; + LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL; } } else { // This will happen if not logged in or if a region deoes not have HTTP Texture enabled //LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL; - LL_DEBUGS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL; + LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL; mCanUseHTTP = false; } } @@ -1434,84 +1393,12 @@ bool LLTextureFetchWorker::doWork(S32 param) } // don't return, fall through to next state } - else if (mSentRequest == UNSENT && mCanUseNET) - { - // Add this to the network queue and sit here. - // LLTextureFetch::update() will send off a request which will change our state - mWriteToCacheState = CAN_WRITE ; - mRequestedSize = mDesiredSize; - mRequestedDiscard = mDesiredDiscard; - mSentRequest = QUEUED; - mFetcher->addToNetworkQueue(this); - recordTextureStart(false); - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - - return false; - } else { - // Shouldn't need to do anything here - //llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end()); - // Make certain this is in the network queue - //mFetcher->addToNetworkQueue(this); - //recordTextureStart(false); - //setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - return false; } } - if (mState == LOAD_FROM_SIMULATOR) - { - if (mFormattedImage.isNull()) - { - mFormattedImage = new LLImageJ2C; - } - if (processSimulatorPackets()) - { - // Capture some measure of total size for metrics - F64 byte_count = 0; - if (mLastPacket >= mFirstPacket) - { - for (S32 i=mFirstPacket; i<=mLastPacket; i++) - { - llassert_always((i>=0) && (i<mPackets.size())); - if (mPackets[i]) - { - byte_count += mPackets[i]->mSize; - } - } - } - - LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL; - mFetcher->removeFromNetworkQueue(this, false); - if (mFormattedImage.isNull() || !mFormattedImage->getDataSize()) - { - // processSimulatorPackets() failed -// LL_WARNS(LOG_TXT) << "processSimulatorPackets() failed to load buffer" << LL_ENDL; - LL_WARNS(LOG_TXT) << mID << " processSimulatorPackets() failed to load buffer" << LL_ENDL; - return true; // failed - } - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - if (mLoadedDiscard < 0) - { - LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard - << ", should be >=0" << LL_ENDL; - } - setState(DECODE_IMAGE); - mWriteToCacheState = SHOULD_WRITE; - - recordTextureDone(false, byte_count); - } - else - { - mFetcher->addToNetworkQueue(this); // failsafe - setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); - recordTextureStart(false); - } - return false; - } - if (mState == WAIT_HTTP_RESOURCE) { // NOTE: @@ -1553,8 +1440,6 @@ bool LLTextureFetchWorker::doWork(S32 param) LL_WARNS(LOG_TXT) << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << LL_ENDL; return true; // abort } - - mFetcher->removeFromNetworkQueue(this, false); S32 cur_size = 0; if (mFormattedImage.notNull()) @@ -1701,17 +1586,6 @@ bool LLTextureFetchWorker::doWork(S32 param) } return true; } - - // roll back to try UDP - if (mCanUseNET) - { - setState(INIT); - mCanUseHTTP = false; - mUrl.clear(); - setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority); - releaseHttpSemaphore(); - return false; - } } else if (http_service_unavail == mGetStatus) { @@ -2284,69 +2158,6 @@ void LLTextureFetchWorker::removeFromCache() // Threads: Ttf // Locks: Mw -bool LLTextureFetchWorker::processSimulatorPackets() -{ - if (mFormattedImage.isNull() || mRequestedSize < 0) - { - // not sure how we got here, but not a valid state, abort! - llassert_always(mDecodeHandle == 0); - mFormattedImage = NULL; - return true; - } - - if (mLastPacket >= mFirstPacket) - { - S32 buffer_size = mFormattedImage->getDataSize(); - for (S32 i = mFirstPacket; i<=mLastPacket; i++) - { - llassert_always((i>=0) && (i<mPackets.size())); - llassert_always(mPackets[i]); - buffer_size += mPackets[i]->mSize; - } - bool have_all_data = mLastPacket >= mTotalPackets-1; - if (mRequestedSize <= 0) - { - // We received a packed but haven't requested anything yet (edge case) - // Return true (we're "done") since we didn't request anything - return true; - } - if (buffer_size >= mRequestedSize || have_all_data) - { - /// We have enough (or all) data - if (have_all_data) - { - mHaveAllData = TRUE; - } - S32 cur_size = mFormattedImage->getDataSize(); - if (buffer_size > cur_size) - { - /// We have new data - U8* buffer = (U8*)ll_aligned_malloc_16(buffer_size); - S32 offset = 0; - if (cur_size > 0 && mFirstPacket > 0) - { - memcpy(buffer, mFormattedImage->getData(), cur_size); - offset = cur_size; - } - for (S32 i=mFirstPacket; i<=mLastPacket; i++) - { - memcpy(buffer + offset, mPackets[i]->mData, mPackets[i]->mSize); - offset += mPackets[i]->mSize; - } - // NOTE: setData releases current data - mFormattedImage->setData(buffer, buffer_size); - } - mLoadedDiscard = mRequestedDiscard; - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////////////////// - -// Threads: Ttf -// Locks: Mw S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response, bool partial, bool success) { @@ -2813,40 +2624,6 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const } -// Threads: T* (but Ttf in practice) - -// protected -void LLTextureFetch::addToNetworkQueue(LLTextureFetchWorker* worker) -{ - lockQueue(); // +Mfq - bool in_request_map = (mRequestMap.find(worker->mID) != mRequestMap.end()) ; - unlockQueue(); // -Mfq - - LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq - if (in_request_map) - { - // only add to the queue if in the request map - // i.e. a delete has not been requested - mNetworkQueue.insert(worker->mID); - } - for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); - iter1 != mCancelQueue.end(); ++iter1) - { - iter1->second.erase(worker->mID); - } -} // -Mfnq - -// Threads: T* -void LLTextureFetch::removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel) -{ - LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq - size_t erased = mNetworkQueue.erase(worker->mID); - if (cancel && erased > 0) - { - mCancelQueue[worker->mHost].insert(worker->mID); - } -} // -Mfnq - // Threads: T* // // protected @@ -2880,7 +2657,6 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel) unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; worker->scheduleDelete(); @@ -2908,7 +2684,6 @@ void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel) unlockQueue(); // -Mfq llassert_always(erased_1 > 0) ; - removeFromNetworkQueue(worker, cancel); llassert_always(!(worker->getFlags(LLWorkerClass::WCF_DELETE_REQUESTED))) ; worker->scheduleDelete(); @@ -3104,9 +2879,9 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority) // Threads: T* //virtual -S32 LLTextureFetch::getPending() +size_t LLTextureFetch::getPending() { - S32 res; + size_t res; lockData(); // +Ct { LLMutexLock lock(&mQueueMutex); // +Mfq @@ -3181,7 +2956,7 @@ void LLTextureFetch::commonUpdate() // Threads: Tmain //virtual -S32 LLTextureFetch::update(F32 max_time_ms) +size_t LLTextureFetch::update(F32 max_time_ms) { static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 3000.0); @@ -3195,19 +2970,8 @@ S32 LLTextureFetch::update(F32 max_time_ms) mNetworkQueueMutex.unlock(); // -Mfnq } - S32 res = LLWorkerThread::update(max_time_ms); + size_t res = LLWorkerThread::update(max_time_ms); - if (!mDebugPause) - { - // this is the startup state when send_complete_agent_movement() message is sent. - // Before this, the RequestImages message sent by sendRequestListToSimulators - // won't work so don't bother trying - if (LLStartUp::getStartupState() > STATE_AGENT_SEND) - { - sendRequestListToSimulators(); - } - } - if (!mThreaded) { commonUpdate(); @@ -3298,202 +3062,6 @@ void LLTextureFetch::threadedUpdate() ////////////////////////////////////////////////////////////////////////////// -// Threads: Tmain -void LLTextureFetch::sendRequestListToSimulators() -{ - // All requests - const F32 REQUEST_DELTA_TIME = 0.10f; // 10 fps - - // Sim requests - const S32 IMAGES_PER_REQUEST = 50; - const F32 SIM_LAZY_FLUSH_TIMEOUT = 10.0f; // temp - const F32 MIN_REQUEST_TIME = 1.0f; - const F32 MIN_DELTA_PRIORITY = 1000.f; - - // Periodically, gather the list of textures that need data from the network - // And send the requests out to the simulators - static LLFrameTimer timer; - if (timer.getElapsedTimeF32() < REQUEST_DELTA_TIME) - { - return; - } - timer.reset(); - - // Send requests - typedef std::set<LLTextureFetchWorker*,LLTextureFetchWorker::Compare> request_list_t; - typedef std::map< LLHost, request_list_t > work_request_map_t; - work_request_map_t requests; - { - LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq - for (queue_t::iterator iter = mNetworkQueue.begin(); iter != mNetworkQueue.end(); ) - { - queue_t::iterator curiter = iter++; - LLTextureFetchWorker* req = getWorker(*curiter); - if (!req) - { - mNetworkQueue.erase(curiter); - continue; // paranoia - } - if ((req->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK) && - (req->mState != LLTextureFetchWorker::LOAD_FROM_SIMULATOR)) - { - // We already received our URL, remove from the queue - LL_WARNS(LOG_TXT) << "Worker: " << req->mID << " in mNetworkQueue but in wrong state: " << req->mState << LL_ENDL; - mNetworkQueue.erase(curiter); - continue; - } - if (req->mID == mDebugID) - { - mDebugCount++; // for setting breakpoints - } - if (req->mSentRequest == LLTextureFetchWorker::SENT_SIM && - req->mTotalPackets > 0 && - req->mLastPacket >= req->mTotalPackets-1) - { - // We have all the packets... make sure this is high priority -// req->setPriority(LLWorkerThread::PRIORITY_HIGH | req->mWorkPriority); - continue; - } - F32 elapsed = req->mRequestedDeltaTimer.getElapsedTimeF32(); - { - F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority); - if ((req->mSimRequestedDiscard != req->mDesiredDiscard) || - (delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) || - (elapsed >= SIM_LAZY_FLUSH_TIMEOUT)) - { - requests[req->mHost].insert(req); - } - } - } - } // -Mfnq - - for (work_request_map_t::iterator iter1 = requests.begin(); - iter1 != requests.end(); ++iter1) - { - LLHost host = iter1->first; - // invalid host = use agent host - if (host.isInvalid()) - { - host = gAgent.getRegionHost(); - } - - S32 sim_request_count = 0; - - for (request_list_t::iterator iter2 = iter1->second.begin(); - iter2 != iter1->second.end(); ++iter2) - { - LLTextureFetchWorker* req = *iter2; - if (gMessageSystem) - { - if (req->mSentRequest != LLTextureFetchWorker::SENT_SIM) - { - // Initialize packet data based on data read from cache - req->lockWorkMutex(); // +Mw - req->setupPacketData(); - req->unlockWorkMutex(); // -Mw - } - if (0 == sim_request_count) - { - gMessageSystem->newMessageFast(_PREHASH_RequestImage); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - } - S32 packet = req->mLastPacket + 1; - gMessageSystem->nextBlockFast(_PREHASH_RequestImage); - gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID); - gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard); - gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, req->mImagePriority); - gMessageSystem->addU32Fast(_PREHASH_Packet, packet); - gMessageSystem->addU8Fast(_PREHASH_Type, req->mType); -// LL_INFOS(LOG_TXT) << "IMAGE REQUEST: " << req->mID << " Discard: " << req->mDesiredDiscard -// << " Packet: " << packet << " Priority: " << req->mImagePriority << LL_ENDL; - - static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false); - static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false); - if (log_to_viewer_log || log_to_sim) - { - mTextureInfo.setRequestStartTime(req->mID, LLTimer::getTotalTime()); - mTextureInfo.setRequestOffset(req->mID, 0); - mTextureInfo.setRequestSize(req->mID, 0); - mTextureInfo.setRequestType(req->mID, LLTextureInfoDetails::REQUEST_TYPE_UDP); - } - - req->lockWorkMutex(); // +Mw - req->mSentRequest = LLTextureFetchWorker::SENT_SIM; - req->mSimRequestedDiscard = req->mDesiredDiscard; - req->mRequestedPriority = req->mImagePriority; - req->mRequestedDeltaTimer.reset(); - req->unlockWorkMutex(); // -Mw - sim_request_count++; - if (sim_request_count >= IMAGES_PER_REQUEST) - { -// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; - - gMessageSystem->sendSemiReliable(host, NULL, NULL); - sim_request_count = 0; - } - } - } - if (gMessageSystem && sim_request_count > 0 && sim_request_count < IMAGES_PER_REQUEST) - { -// LL_INFOS(LOG_TXT) << "REQUESTING " << sim_request_count << " IMAGES FROM HOST: " << host.getIPString() << LL_ENDL; - gMessageSystem->sendSemiReliable(host, NULL, NULL); - sim_request_count = 0; - } - } - - // Send cancelations - { - LLMutexLock lock2(&mNetworkQueueMutex); // +Mfnq - if (gMessageSystem && !mCancelQueue.empty()) - { - for (cancel_queue_t::iterator iter1 = mCancelQueue.begin(); - iter1 != mCancelQueue.end(); ++iter1) - { - LLHost host = iter1->first; - if (host.isInvalid()) - { - host = gAgent.getRegionHost(); - } - S32 request_count = 0; - for (queue_t::iterator iter2 = iter1->second.begin(); - iter2 != iter1->second.end(); ++iter2) - { - if (0 == request_count) - { - gMessageSystem->newMessageFast(_PREHASH_RequestImage); - gMessageSystem->nextBlockFast(_PREHASH_AgentData); - gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); - gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); - } - gMessageSystem->nextBlockFast(_PREHASH_RequestImage); - gMessageSystem->addUUIDFast(_PREHASH_Image, *iter2); - gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, -1); - gMessageSystem->addF32Fast(_PREHASH_DownloadPriority, 0); - gMessageSystem->addU32Fast(_PREHASH_Packet, 0); - gMessageSystem->addU8Fast(_PREHASH_Type, 0); -// LL_INFOS(LOG_TXT) << "CANCELING IMAGE REQUEST: " << (*iter2) << LL_ENDL; - - request_count++; - if (request_count >= IMAGES_PER_REQUEST) - { - gMessageSystem->sendSemiReliable(host, NULL, NULL); - request_count = 0; - } - } - if (request_count > 0 && request_count < IMAGES_PER_REQUEST) - { - gMessageSystem->sendSemiReliable(host, NULL, NULL); - } - } - mCancelQueue.clear(); - } - } // -Mfnq -} - -////////////////////////////////////////////////////////////////////////////// - // Threads: T* // Locks: Mw bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size) @@ -3556,138 +3124,6 @@ void LLTextureFetchWorker::setState(e_state new_state) mState = new_state; } -// Threads: T* -bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, - U16 data_size, U8* data) -{ - LLTextureFetchWorker* worker = getWorker(id); - bool res = true; - - ++mPacketCount; - - if (!worker) - { -// LL_WARNS(LOG_TXT) << "Received header for non active worker: " << id << LL_ENDL; - res = false; - } - else if (worker->mState != LLTextureFetchWorker::LOAD_FROM_NETWORK || - worker->mSentRequest != LLTextureFetchWorker::SENT_SIM) - { -// LL_WARNS(LOG_TXT) << "receiveImageHeader for worker: " << id -// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] -// << " sent: " << worker->mSentRequest << LL_ENDL; - res = false; - } - else if (worker->mLastPacket != -1) - { - // check to see if we've gotten this packet before -// LL_WARNS(LOG_TXT) << "Received duplicate header for: " << id << LL_ENDL; - res = false; - } - else if (!data_size) - { -// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; - res = false; - } - if (!res) - { - mNetworkQueueMutex.lock(); // +Mfnq - ++mBadPacketCount; - mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock(); // -Mfnq - return false; - } - - LLViewerStatsRecorder::instance().textureFetch(data_size); - LLViewerStatsRecorder::instance().log(0.1f); - - worker->lockWorkMutex(); - - - // Copy header data into image object - worker->mImageCodec = codec; - worker->mTotalPackets = packets; - worker->mFileSize = (S32)totalbytes; - llassert_always(totalbytes > 0); - llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize); - res = worker->insertPacket(0, data, data_size); - worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); - worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR); - worker->unlockWorkMutex(); // -Mw - return res; -} - - -// Threads: T* -bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data) -{ - LLTextureFetchWorker* worker = getWorker(id); - bool res = true; - - ++mPacketCount; - - if (!worker) - { -// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " for non active worker: " << id << LL_ENDL; - res = false; - } - else if (worker->mLastPacket == -1) - { -// LL_WARNS(LOG_TXT) << "Received packet " << packet_num << " before header for: " << id << LL_ENDL; - res = false; - } - else if (!data_size) - { -// LL_WARNS(LOG_TXT) << "Img: " << id << ":" << " Empty Image Header" << LL_ENDL; - res = false; - } - if (!res) - { - mNetworkQueueMutex.lock(); // +Mfnq - ++mBadPacketCount; - mCancelQueue[host].insert(id); - mNetworkQueueMutex.unlock(); // -Mfnq - return false; - } - - LLViewerStatsRecorder::instance().textureFetch(data_size); - LLViewerStatsRecorder::instance().log(0.1f); - - worker->lockWorkMutex(); - - - res = worker->insertPacket(packet_num, data, data_size); - - if ((worker->mState == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) || - (worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK)) - { - worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority); - worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR); - } - else - { -// LL_WARNS(LOG_TXT) << "receiveImagePacket " << packet_num << "/" << worker->mLastPacket << " for worker: " << id -// << " in state: " << LLTextureFetchWorker::sStateDescs[worker->mState] << LL_ENDL; - removeFromNetworkQueue(worker, true); // failsafe - } - - if (packet_num >= (worker->mTotalPackets - 1)) - { - static LLCachedControl<bool> log_to_viewer_log(gSavedSettings,"LogTextureDownloadsToViewerLog", false); - static LLCachedControl<bool> log_to_sim(gSavedSettings,"LogTextureDownloadsToSimulator", false); - - if (log_to_viewer_log || log_to_sim) - { - U64Microseconds timeNow = LLTimer::getTotalTime(); - mTextureInfoMainThread.setRequestSize(id, worker->mFileSize); - mTextureInfoMainThread.setRequestCompleteTimeAndLog(id, timeNow); - } - } - worker->unlockWorkMutex(); // -Mw - - return res; -} - ////////////////////////////////////////////////////////////////////////////// // Threads: T* @@ -3726,13 +3162,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r request_dtime = worker->mRequestedDeltaTimer.getElapsedTimeF32(); if (worker->mFileSize > 0) { - if (state == LLTextureFetchWorker::LOAD_FROM_SIMULATOR) - { - S32 data_size = FIRST_PACKET_SIZE + (worker->mLastPacket-1) * MAX_IMG_PACKET_SIZE; - data_size = llmax(data_size, 0); - data_progress = (F32)data_size / (F32)worker->mFileSize; - } - else if (worker->mFormattedImage.notNull()) + if (worker->mFormattedImage.notNull()) { data_progress = (F32)worker->mFormattedImage->getDataSize() / (F32)worker->mFileSize; } diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h index bf6732963f..611a7d6419 100644 --- a/indra/newview/lltexturefetch.h +++ b/indra/newview/lltexturefetch.h @@ -65,7 +65,7 @@ public: class TFRequest; // Threads: Tmain - /*virtual*/ S32 update(F32 max_time_ms); + /*virtual*/ size_t update(F32 max_time_ms); // called in the main thread after the TextureCacheThread shuts down. // Threads: Tmain @@ -101,12 +101,6 @@ public: // Threads: T* bool updateRequestPriority(const LLUUID& id, F32 priority); - // Threads: T* - bool receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes, U16 data_size, U8* data); - - // Threads: T* - bool receiveImagePacket(const LLHost& host, const LLUUID& id, U16 packet_num, U16 data_size, U8* data); - // Threads: T* (but not safe) void setTextureBandwidth(F32 bandwidth) { mTextureBandwidth = bandwidth; } @@ -137,7 +131,7 @@ public: U32 getTotalNumHTTPRequests(); // Threads: T* - S32 getPending(); + size_t getPending(); // Threads: T* void lockQueue() { mQueueMutex.lock(); } @@ -227,12 +221,6 @@ public: // ---------------------------------- protected: - // Threads: T* (but Ttf in practice) - void addToNetworkQueue(LLTextureFetchWorker* worker); - - // Threads: T* - void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel); - // Threads: T* void addToHTTPQueue(const LLUUID& id); @@ -251,9 +239,6 @@ protected: bool runCondition(); private: - // Threads: Tmain - void sendRequestListToSimulators(); - // Threads: Ttf /*virtual*/ void startThread(void); @@ -319,7 +304,7 @@ public: private: LLMutex mQueueMutex; //to protect mRequestMap and mCommands only - LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue. + LLMutex mNetworkQueueMutex; //to protect mHTTPTextureQueue LLTextureCache* mTextureCache; LLImageDecodeThread* mImageDecodeThread; @@ -330,10 +315,8 @@ private: // Set of requests that require network data typedef std::set<LLUUID> queue_t; - queue_t mNetworkQueue; // Mfnq queue_t mHTTPTextureQueue; // Mfnq typedef std::map<LLHost,std::set<LLUUID> > cancel_queue_t; - cancel_queue_t mCancelQueue; // Mfnq F32 mTextureBandwidth; // <none> F32 mMaxBandwidth; // Mfnq LLTextureInfo mTextureInfo; diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp index b74577315e..cf9211767e 100644 --- a/indra/newview/lltextureview.cpp +++ b/indra/newview/lltextureview.cpp @@ -234,7 +234,6 @@ void LLTextureBar::draw() { "DSK", LLColor4::cyan }, // LOAD_FROM_TEXTURE_CACHE { "DSK", LLColor4::blue }, // CACHE_POST { "NET", LLColor4::green }, // LOAD_FROM_NETWORK - { "SIM", LLColor4::green }, // LOAD_FROM_SIMULATOR { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE { "HTW", LLColor4::green }, // WAIT_HTTP_RESOURCE2 { "REQ", LLColor4::yellow },// SEND_HTTP_REQ diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index 01d799dcd5..752fc6f3f3 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -44,6 +44,7 @@ #include "llagent.h" // HACK for destinations guide on startup #include "llfloaterreg.h" // HACK for destinations guide on startup #include "llviewercontrol.h" // HACK for destinations guide on startup +#include "llinventorymodel.h" // HACK to disable starter avatars button for NUX #include <boost/foreach.hpp> @@ -319,6 +320,22 @@ bool LLToolBarView::loadToolbars(bool force_default) } } } + + // SL-18581: Don't show the starter avatar toolbar button for NUX users + LLViewerInventoryCategory* my_outfits_cat = gInventory.getCategory(gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS)); + if (gAgent.isFirstLogin() + && my_outfits_cat != NULL + && my_outfits_cat->getDescendentCount() > 0) + { + for (S32 i = LLToolBarEnums::TOOLBAR_FIRST; i <= LLToolBarEnums::TOOLBAR_LAST; i++) + { + if (mToolbars[i]) + { + mToolbars[i]->removeCommand(LLCommandId("avatar")); + } + } + } + mToolbarsLoaded = true; return true; } diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp index 70065cb5a0..aa9ff012c3 100644 --- a/indra/newview/llviewerassetstorage.cpp +++ b/indra/newview/llviewerassetstorage.cpp @@ -134,14 +134,6 @@ LLViewerAssetStorage::~LLViewerAssetStorage() // This class has dedicated coroutine pool, clean it up, otherwise coroutines will crash later. LLCoprocedureManager::instance().close(VIEWER_ASSET_STORAGE_CORO_POOL); } - - while (mCoroWaitList.size() > 0) - { - CoroWaitList &request = mCoroWaitList.front(); - // Clean up pending downloads, delete request and trigger callbacks - removeAndCallbackPendingDownloads(request.mId, request.mType, request.mId, request.mType, LL_ERR_NOERR, LLExtStat::NONE); - mCoroWaitList.pop_front(); - } } // virtual @@ -346,28 +338,6 @@ void LLViewerAssetStorage::storeAssetData( } } -void LLViewerAssetStorage::checkForTimeouts() -{ - LLAssetStorage::checkForTimeouts(); - - // Restore requests - LLCoprocedureManager* manager = LLCoprocedureManager::getInstance(); - while (mCoroWaitList.size() > 0 - && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1)) - { - CoroWaitList &request = mCoroWaitList.front(); - - bool with_http = true; - bool is_temp = false; - LLViewerAssetStatsFF::record_enqueue(request.mType, with_http, is_temp); - - manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", - boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, request.mRequest, request.mId, request.mType, request.mCallback, request.mUserData)); - - mCoroWaitList.pop_front(); - } -} - /** * @brief Allocate and queue an asset fetch request for the viewer * @@ -424,21 +394,18 @@ void LLViewerAssetStorage::queueRequestHttp( // This is the same as the current UDP logic - don't re-request a duplicate. if (!duplicate) { - // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit LLCoprocedureManager* manager = LLCoprocedureManager::getInstance(); - if (manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < (LLCoprocedureManager::DEFAULT_QUEUE_SIZE - 1)) - { - bool with_http = true; - bool is_temp = false; - LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); - - manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro", - boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data)); - } - else - { - mCoroWaitList.emplace_back(req, uuid, atype, callback, user_data); - } + bool with_http = true; + bool is_temp = false; + LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp); + manager->enqueueCoprocedure( + VIEWER_ASSET_STORAGE_CORO_POOL, + "LLViewerAssetStorage::assetRequestCoro", + [this, req, uuid, atype, callback, user_data] + (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t&, const LLUUID&) + { + assetRequestCoro(req, uuid, atype, callback, user_data); + }); } } diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h index 0965a17ce1..c3719d0918 100644 --- a/indra/newview/llviewerassetstorage.h +++ b/indra/newview/llviewerassetstorage.h @@ -65,8 +65,6 @@ public: bool user_waiting=FALSE, F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override; - void checkForTimeouts() override; - protected: void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, @@ -118,8 +116,6 @@ protected: LLGetAssetCallback mCallback; void *mUserData; }; - typedef std::list<CoroWaitList> wait_list_t; - wait_list_t mCoroWaitList; std::string mViewerAssetUrl; S32 mCountRequests; diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp index 14fae8d035..232b52a3f9 100644 --- a/indra/newview/llviewerassetupload.cpp +++ b/indra/newview/llviewerassetupload.cpp @@ -868,11 +868,6 @@ void LLViewerAssetUpload::AssetInventoryUploadCoproc(LLCoreHttpUtil::HttpCorouti { floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory"))); } - LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot"); - if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown()) - { - floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", success).with("msg", "inventory"))); - } } //========================================================================= @@ -951,11 +946,5 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res floater_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory"))); } } - - LLFloater* floater_outfit_snapshot = LLFloaterReg::findInstance("outfit_snapshot"); - if (uploadInfo->getAssetType() == LLAssetType::AT_TEXTURE && floater_outfit_snapshot && floater_outfit_snapshot->isShown()) - { - floater_outfit_snapshot->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "inventory"))); - } } diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp index f810e5f4ef..cc73f7ca80 100644 --- a/indra/newview/llvieweraudio.cpp +++ b/indra/newview/llvieweraudio.cpp @@ -496,7 +496,20 @@ void audio_update_listener() if (gAudiop) { // update listener position because agent has moved - LLVector3d lpos_global = gAgentCamera.getCameraPositionGlobal(); + static LLUICachedControl<S32> mEarLocation("MediaSoundsEarLocation", 0); + LLVector3d ear_position; + switch(mEarLocation) + { + case 0: + default: + ear_position = gAgentCamera.getCameraPositionGlobal(); + break; + + case 1: + ear_position = gAgent.getPositionGlobal(); + break; + } + LLVector3d lpos_global = ear_position; LLVector3 lpos_global_f; lpos_global_f.setVec(lpos_global); diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index bc46a61fb0..34c9dae4bb 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -616,7 +616,7 @@ bool toggle_show_navigation_panel(const LLSD& newvalue) LLNavigationBar::getInstance()->setVisible(value); gSavedSettings.setBOOL("ShowMiniLocationPanel", !value); - + gViewerWindow->reshapeStatusBarContainer(); return true; } diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 06a6c5e373..59654350e4 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -103,7 +103,7 @@ #include "llfloaterobjectweights.h" #include "llfloateropenobject.h" #include "llfloateroutfitphotopreview.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llfloaterpathfindingcharacters.h" #include "llfloaterpathfindingconsole.h" #include "llfloaterpathfindinglinksets.h" @@ -170,6 +170,7 @@ // *NOTE: Please add files in alphabetical order to keep merges easy. // handle secondlife:///app/openfloater/{NAME} URLs +const std::string FLOATER_PROFILE("profile"); class LLFloaterOpenHandler : public LLCommandHandler { public: @@ -185,7 +186,12 @@ public: } const std::string floater_name = LLURI::unescape(params[0].asString()); - LLFloaterReg::showInstance(floater_name); + LLSD key; + if (floater_name == FLOATER_PROFILE) + { + key["id"] = gAgentID; + } + LLFloaterReg::showInstance(floater_name, key); return true; } @@ -368,7 +374,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("scene_load_stats", "floater_scene_load_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSceneLoadStats>); LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSnapshot>); - LLFloaterReg::add("outfit_snapshot", "floater_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOutfitSnapshot>); + LLFloaterReg::add("simple_outfit_snapshot", "floater_simple_outfit_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSimpleOutfitSnapshot>); LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>); LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterProfile>); LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>); diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp index fd314ed3dc..b3bfb86b99 100644 --- a/indra/newview/llviewerjointattachment.cpp +++ b/indra/newview/llviewerjointattachment.cpp @@ -45,7 +45,7 @@ #include "llglheaders.h" extern LLPipeline gPipeline; -const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters? +const F32 MAX_ATTACHMENT_DIST = 3.5f; // meters //----------------------------------------------------------------------------- // LLViewerJointAttachment() diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index a1cb152e1e..8570c0cd5d 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -3581,7 +3581,20 @@ void LLViewerMediaImpl::calculateInterest() LLVector3d global_delta = agent_global - obj_global ; mProximityDistance = global_delta.magVecSquared(); // use distance-squared because it's cheaper and sorts the same. - LLVector3d camera_delta = gAgentCamera.getCameraPositionGlobal() - obj_global; + static LLUICachedControl<S32> mEarLocation("MediaSoundsEarLocation", 0); + LLVector3d ear_position; + switch(mEarLocation) + { + case 0: + default: + ear_position = gAgentCamera.getCameraPositionGlobal(); + break; + + case 1: + ear_position = agent_global; + break; + } + LLVector3d camera_delta = ear_position - obj_global; mProximityCamera = camera_delta.magVec(); } } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 3573af40cb..c796ed30f7 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4334,6 +4334,10 @@ class LLLandSit : public view_listener_t { bool handleEvent(const LLSD& userdata) { + if (gAgent.isSitting()) + { + gAgent.standUp(); + } LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal; LLQuaternion target_rot; diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index f1e2c06e0c..fdf1d04c09 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -38,7 +38,7 @@ #include "llfloatermap.h" #include "llfloatermodelpreview.h" #include "llfloatersnapshot.h" -#include "llfloateroutfitsnapshot.h" +#include "llfloatersimpleoutfitsnapshot.h" #include "llimage.h" #include "llimagebmp.h" #include "llimagepng.h" @@ -664,7 +664,7 @@ class LLFileEnableCloseAllWindows : public view_listener_t bool handleEvent(const LLSD& userdata) { LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); - LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance(); + LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance(); bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain()) || (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain()); bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened; @@ -681,7 +681,7 @@ class LLFileCloseAllWindows : public view_listener_t LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance(); if (floater_snapshot) floater_snapshot->closeFloater(app_quitting); - LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance(); + LLFloaterSimpleOutfitSnapshot* floater_outfit_snapshot = LLFloaterSimpleOutfitSnapshot::findInstance(); if (floater_outfit_snapshot) floater_outfit_snapshot->closeFloater(app_quitting); if (gMenuHolder) gMenuHolder->hideMenus(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index aad6c14b4d..7ac1df8e31 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -316,7 +316,8 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe mLastUpdateType(OUT_UNKNOWN), mLastUpdateCached(FALSE), mCachedMuteListUpdateTime(0), - mCachedOwnerInMuteList(false) + mCachedOwnerInMuteList(false), + mRiggedAttachedWarned(false) { if (!is_global) { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index bef8e3e7e3..0005cdf14e 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -702,6 +702,8 @@ public: // Replace textures with web pages on this object while drawing BOOL mRenderMedia; + bool mRiggedAttachedWarned; + // In bits S32 mBestUpdatePrecision; diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp index 75eb16c085..97dc916bfe 100644 --- a/indra/newview/llviewerparcelmgr.cpp +++ b/indra/newview/llviewerparcelmgr.cpp @@ -1974,7 +1974,7 @@ void LLViewerParcelMgr::optionallyStartMusic(const std::string &music_url, const static LLCachedControl<bool> tentative_autoplay(gSavedSettings, "MediaTentativeAutoPlay", true); // only play music when you enter a new parcel if the UI control for this // was not *explicitly* stopped by the user. (part of SL-4878) - LLPanelNearByMedia* nearby_media_panel = gStatusBar->getNearbyMediaPanel(); + LLPanelNearByMedia* nearby_media_panel = gStatusBar ? gStatusBar->getNearbyMediaPanel() : NULL; LLViewerAudio* viewer_audio = LLViewerAudio::getInstance(); // ask mode //todo constants diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index da3c860ddb..93ae1670c8 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -45,11 +45,13 @@ #include "llxmltree.h" #include "message.h" +#include "lldrawpoolbump.h" // to init bumpmap images #include "lltexturecache.h" #include "lltexturefetch.h" #include "llviewercontrol.h" #include "llviewertexture.h" #include "llviewermedia.h" +#include "llviewernetwork.h" #include "llviewerregion.h" #include "llviewerstats.h" #include "pipeline.h" @@ -139,9 +141,6 @@ void LLViewerTextureList::doPreloadImages() //uv_test->setClamp(FALSE, FALSE); //uv_test->setMipFilterNearest(TRUE, TRUE); - // prefetch specific UUIDs - LLViewerTextureManager::getFetchedTexture(IMG_SHOT); - LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF); LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); if (image) { @@ -160,12 +159,6 @@ void LLViewerTextureList::doPreloadImages() image->setAddressMode(LLTexUnit::TAM_WRAP); mImagePreloads.insert(image); } - image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); - if (image) - { - image->setAddressMode(LLTexUnit::TAM_WRAP); - mImagePreloads.insert(image); - } image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE, 0, 0, IMG_TRANSPARENT); if (image) @@ -198,7 +191,18 @@ void LLViewerTextureList::doPreloadImages() static std::string get_texture_list_name() { - return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml"); + if (LLGridManager::getInstance()->isInProductionGrid()) + { + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, + "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + ".xml"); + } + else + { + const std::string& grid_id_str = LLGridManager::getInstance()->getGridId(); + const std::string& grid_id_lower = utf8str_tolower(grid_id_str); + return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, + "texture_list_" + gSavedSettings.getString("LoginLocation") + "." + gDirUtilp->getUserName() + "." + grid_id_lower + ".xml"); + } } void LLViewerTextureList::doPrefetchImages() @@ -207,6 +211,26 @@ void LLViewerTextureList::doPrefetchImages() gTextureTimer.start(); gTextureTimer.pause(); + // todo: do not load without getViewerAssetUrl() + // either fail login without caps or provide this + // in some other way, textures won't load otherwise + LLViewerFetchedTexture *imagep = findImage(DEFAULT_WATER_NORMAL, TEX_LIST_STANDARD); + if (!imagep) + { + // add it to mImagePreloads only once + imagep = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI); + if (imagep) + { + imagep->setAddressMode(LLTexUnit::TAM_WRAP); + mImagePreloads.insert(imagep); + } + } + + LLViewerTextureManager::getFetchedTexture(IMG_SHOT); + LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF); + + LLStandardBumpmap::addstandard(); + if (LLAppViewer::instance()->getPurgeCache()) { // cache was purged, no point @@ -1501,152 +1525,6 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem) /////////////////////////////////////////////////////////////////////////////// -// static -void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_data) -{ - static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; - - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - - // Receive image header, copy into image object and decompresses - // if this is a one-packet image. - - LLUUID id; - - char ip_string[256]; - u32_to_ip_string(msg->getSenderIP(),ip_string); - - U32Bytes received_size ; - if (msg->getReceiveCompressedSize()) - { - received_size = (U32Bytes)msg->getReceiveCompressedSize() ; - } - else - { - received_size = (U32Bytes)msg->getReceiveSize() ; - } - add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, received_size); - add(LLStatViewer::TEXTURE_PACKETS, 1); - - U8 codec; - U16 packets; - U32 totalbytes; - msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); - msg->getU8Fast(_PREHASH_ImageID, _PREHASH_Codec, codec); - msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packets, packets); - msg->getU32Fast(_PREHASH_ImageID, _PREHASH_Size, totalbytes); - - S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); - if (!data_size) - { - return; - } - if (data_size < 0) - { - // msg->getSizeFast() is probably trying to tell us there - // was an error. - LL_ERRS() << "image header chunk size was negative: " - << data_size << LL_ENDL; - return; - } - - // this buffer gets saved off in the packet list - U8 *data = new U8[data_size]; - msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); - - LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - if (!image) - { - delete [] data; - return; - } - if(log_texture_traffic) - { - gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ; - } - - //image->getLastPacketTimer()->reset(); - bool res = LLAppViewer::getTextureFetch()->receiveImageHeader(msg->getSender(), id, codec, packets, totalbytes, data_size, data); - if (!res) - { - delete[] data; - } -} - -// static -void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_data) -{ - static LLCachedControl<bool> log_texture_traffic(gSavedSettings,"LogTextureNetworkTraffic", false) ; - - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - - // Receives image packet, copy into image object, - // checks if all packets received, decompresses if so. - - LLUUID id; - U16 packet_num; - - char ip_string[256]; - u32_to_ip_string(msg->getSenderIP(),ip_string); - - U32Bytes received_size ; - if (msg->getReceiveCompressedSize()) - { - received_size = (U32Bytes)msg->getReceiveCompressedSize() ; - } - else - { - received_size = (U32Bytes)msg->getReceiveSize() ; - } - - add(LLStatViewer::TEXTURE_NETWORK_DATA_RECEIVED, F64Bytes(received_size)); - add(LLStatViewer::TEXTURE_PACKETS, 1); - - //llprintline("Start decode, image header..."); - msg->getUUIDFast(_PREHASH_ImageID, _PREHASH_ID, id); - msg->getU16Fast(_PREHASH_ImageID, _PREHASH_Packet, packet_num); - S32 data_size = msg->getSizeFast(_PREHASH_ImageData, _PREHASH_Data); - - if (!data_size) - { - return; - } - if (data_size < 0) - { - // msg->getSizeFast() is probably trying to tell us there - // was an error. - LL_ERRS() << "image data chunk size was negative: " - << data_size << LL_ENDL; - return; - } - if (data_size > MTUBYTES) - { - LL_ERRS() << "image data chunk too large: " << data_size << " bytes" << LL_ENDL; - return; - } - U8 *data = new U8[data_size]; - msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size); - - LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - if (!image) - { - delete [] data; - return; - } - if(log_texture_traffic) - { - gTotalTextureBytesPerBoostLevel[image->getBoostLevel()] += received_size ; - } - - //image->getLastPacketTimer()->reset(); - bool res = LLAppViewer::getTextureFetch()->receiveImagePacket(msg->getSender(), id, packet_num, data_size, data); - if (!res) - { - delete[] data; - } -} - - // We've been that the asset server does not contain the requested image id. // static void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **user_data) diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h index 6fb0d3552e..0018e78d45 100644 --- a/indra/newview/llviewertexturelist.h +++ b/indra/newview/llviewertexturelist.h @@ -98,8 +98,6 @@ public: const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT); static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data ); - static void receiveImageHeader(LLMessageSystem *msg, void **user_data); - static void receiveImagePacket(LLMessageSystem *msg, void **user_data); public: LLViewerTextureList(); @@ -133,7 +131,9 @@ public: void updateMaxResidentTexMem(S32Megabytes mem); + // Local UI images void doPreloadImages(); + // Network images. Needs caps and cache to work void doPrefetchImages(); void clearFetchingRequests(); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 8a7d5f12d0..3b391e311a 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -262,6 +262,8 @@ static const F32 MIN_UI_SCALE = 0.75f; static const F32 MAX_UI_SCALE = 7.0f; static const F32 MIN_DISPLAY_SCALE = 0.75f; +static const char KEY_MOUSELOOK = 'M'; + static LLCachedControl<std::string> sSnapshotBaseName(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseName", "Snapshot")); static LLCachedControl<std::string> sSnapshotDir(LLCachedControl<std::string>(gSavedPerAccountSettings, "SnapshotBaseDir", "")); @@ -2232,31 +2234,36 @@ void LLViewerWindow::initWorldUI() // Force gFloaterTools to initialize LLFloaterReg::getInstance("build"); - // Status bar LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container"); gStatusBar = new LLStatusBar(status_bar_container->getLocalRect()); - gStatusBar->setFollowsAll(); + gStatusBar->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_RIGHT); gStatusBar->setShape(status_bar_container->getLocalRect()); // sync bg color with menu bar gStatusBar->setBackgroundColor( gMenuBarView->getBackgroundColor().get() ); // add InBack so that gStatusBar won't be drawn over menu - status_bar_container->addChildInBack(gStatusBar); - status_bar_container->setVisible(TRUE); + status_bar_container->addChildInBack(gStatusBar, 2/*tab order, after menu*/); + status_bar_container->setVisible(TRUE); // Navigation bar - LLPanel* nav_bar_container = getRootView()->getChild<LLPanel>("nav_bar_container"); + LLView* nav_bar_container = getRootView()->getChild<LLView>("nav_bar_container"); LLNavigationBar* navbar = LLNavigationBar::getInstance(); navbar->setShape(nav_bar_container->getLocalRect()); navbar->setBackgroundColor(gMenuBarView->getBackgroundColor().get()); nav_bar_container->addChild(navbar); nav_bar_container->setVisible(TRUE); - + + if (!gSavedSettings.getBOOL("ShowNavbarNavigationPanel")) { navbar->setVisible(FALSE); } + else + { + reshapeStatusBarContainer(); + } + // Top Info bar LLPanel* topinfo_bar_container = getRootView()->getChild<LLPanel>("topinfo_bar_container"); @@ -2883,6 +2890,13 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask) if (keyboard_focus && !gFocusMgr.getKeystrokesOnly()) { + //Most things should fall through, but mouselook is an exception, + //don't switch to mouselook if any floater has focus + if ((key == KEY_MOUSELOOK) && !(mask & (MASK_CONTROL | MASK_ALT))) + { + return TRUE; + } + LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(keyboard_focus); if (cur_focus && cur_focus->acceptsTextInput()) { @@ -5842,6 +5856,27 @@ LLRect LLViewerWindow::getChatConsoleRect() return console_rect; } + +void LLViewerWindow::reshapeStatusBarContainer() +{ + LLPanel* status_bar_container = getRootView()->getChild<LLPanel>("status_bar_container"); + LLView* nav_bar_container = getRootView()->getChild<LLView>("nav_bar_container"); + + S32 new_height = status_bar_container->getRect().getHeight(); + S32 new_width = status_bar_container->getRect().getWidth(); + + if (gSavedSettings.getBOOL("ShowNavbarNavigationPanel")) + { + // Navigation bar is outside visible area, expand status_bar_container to show it + new_height += nav_bar_container->getRect().getHeight(); + } + else + { + // collapse status_bar_container + new_height -= nav_bar_container->getRect().getHeight(); + } + status_bar_container->reshape(new_width, new_height, TRUE); +} //---------------------------------------------------------------------------- diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 979a560508..1927e01ddb 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -177,6 +177,8 @@ public: bool getUIVisibility(); void handlePieMenu(S32 x, S32 y, MASK mask); + void reshapeStatusBarContainer(); + BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down); // diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 46beac8255..0e6734f6e0 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -287,6 +287,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ; if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. { + if (mDetailTextures[i]->getDecodePriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage()) + { + mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP); + mDetailTextures[i]->forceToRefetchTexture(ddiscard); + } + if(delete_raw) { mDetailTextures[i]->destroyRawImage() ; diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 42550ed48d..176528cb56 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -10636,7 +10636,7 @@ void LLVOAvatar::updateVisualComplexity() // with an avatar. This will be either an attached object or an animated // object. void LLVOAvatar::accountRenderComplexityForObject( - const LLViewerObject *attached_object, + LLViewerObject *attached_object, const F32 max_attachment_complexity, LLVOVolume::texture_cost_t& textures, U32& cost, @@ -10708,7 +10708,7 @@ void LLVOAvatar::accountRenderComplexityForObject( && attached_object->mDrawable) { textures.clear(); - + BOOL is_rigged_mesh = attached_object->isRiggedMesh(); mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea(); const LLVOVolume* volume = attached_object->mDrawable->getVOVolume(); @@ -10729,6 +10729,7 @@ void LLVOAvatar::accountRenderComplexityForObject( iter != child_list.end(); ++iter) { LLViewerObject* childp = *iter; + is_rigged_mesh |= childp->isRiggedMesh(); const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp); if (chld_volume) { @@ -10737,6 +10738,16 @@ void LLVOAvatar::accountRenderComplexityForObject( hud_object_complexity.objectsCount++; } } + if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned) + { + LLSD args; + LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID()); + args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown"); + args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName()); + LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args); + + attached_object->mRiggedAttachedWarned = true; + } hud_object_complexity.texturesCount += textures.size(); @@ -10841,7 +10852,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity() attachment_iter != attachment->mAttachedObjects.end(); ++attachment_iter) { - const LLViewerObject* attached_object = attachment_iter->get(); + LLViewerObject* attached_object = attachment_iter->get(); accountRenderComplexityForObject(attached_object, max_attachment_complexity, textures, cost, hud_complexity_list); } diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 8d1dcbcda2..56f2b73bef 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -293,7 +293,7 @@ public: void addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses = false); void idleUpdateRenderComplexity(); void idleUpdateDebugInfo(); - void accountRenderComplexityForObject(const LLViewerObject *attached_object, + void accountRenderComplexityForObject(LLViewerObject *attached_object, const F32 max_attachment_complexity, LLVOVolume::texture_cost_t& textures, U32& cost, diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h index a53f309e46..e7033290c7 100644 --- a/indra/newview/llvoground.h +++ b/indra/newview/llvoground.h @@ -49,7 +49,6 @@ public: /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); - void cleanupGL(); }; #endif // LL_LLVOGROUND_H diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index ac6369e4e2..ab90f2e482 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -1247,8 +1247,8 @@ bool LLVivoxVoiceClient::establishVoiceConnection() if (result.has("connector")) { - LLVoiceVivoxStats::getInstance()->establishAttemptEnd(connected); connected = LLSD::Boolean(result["connector"]); + LLVoiceVivoxStats::getInstance()->establishAttemptEnd(connected); if (!connected) { if (result.has("retry") && ++retries <= CONNECT_RETRY_MAX && !sShuttingDown) @@ -4551,9 +4551,7 @@ void LLVivoxVoiceClient::messageEvent( IM_NOTHING_SPECIAL, // default arg 0, // default arg LLUUID::null, // default arg - LLVector3::zero, // default arg - true); // prepend name and make it a link to the user's profile - + LLVector3::zero); // default arg } } } @@ -6229,7 +6227,7 @@ void LLVivoxVoiceClient::clearSessionHandle(const sessionStatePtr_t &session) { if (session) { - if (session->mHandle.empty()) + if (!session->mHandle.empty()) { sessionMap::iterator iter = mSessionsByHandle.find(session->mHandle); if (iter != mSessionsByHandle.end()) diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index aa32ef04b2..55bcbf8aa5 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -93,7 +93,7 @@ LLWorld::LLWorld() : mLastPacketsLost(0), mSpaceTimeUSec(0) { - for (S32 i = 0; i < 8; i++) + for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++) { mEdgeWaterObjects[i] = NULL; } @@ -126,7 +126,7 @@ void LLWorld::resetClass() LLViewerPartSim::getInstance()->destroyClass(); mDefaultWaterTexturep = NULL ; - for (S32 i = 0; i < 8; i++) + for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++) { mEdgeWaterObjects[i] = NULL; } @@ -753,6 +753,8 @@ void LLWorld::clearAllVisibleObjects() //clear all cached visible objects. (*iter)->clearCachedVisibleObjects(); } + clearHoleWaterObjects(); + clearEdgeWaterObjects(); } void LLWorld::updateParticles() @@ -920,7 +922,7 @@ void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool inc } S32 dir; - for (dir = 0; dir < 8; dir++) + for (dir = 0; dir < EDGE_WATER_OBJECTS_COUNT; dir++) { LLVOWater* waterp = mEdgeWaterObjects[dir]; if (waterp && waterp->mDrawable) @@ -931,6 +933,26 @@ void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool inc } } +void LLWorld::clearHoleWaterObjects() +{ + for (std::list<LLPointer<LLVOWater> >::iterator iter = mHoleWaterObjects.begin(); + iter != mHoleWaterObjects.end(); ++iter) + { + LLVOWater* waterp = (*iter).get(); + gObjectList.killObject(waterp); + } + mHoleWaterObjects.clear(); +} + +void LLWorld::clearEdgeWaterObjects() +{ + for (S32 i = 0; i < EDGE_WATER_OBJECTS_COUNT; i++) + { + gObjectList.killObject(mEdgeWaterObjects[i]); + mEdgeWaterObjects[i] = NULL; + } +} + void LLWorld::updateWaterObjects() { if (!gAgent.getRegion()) @@ -974,13 +996,7 @@ void LLWorld::updateWaterObjects() } } - for (std::list<LLPointer<LLVOWater> >::iterator iter = mHoleWaterObjects.begin(); - iter != mHoleWaterObjects.end(); ++ iter) - { - LLVOWater* waterp = (*iter).get(); - gObjectList.killObject(waterp); - } - mHoleWaterObjects.clear(); + clearHoleWaterObjects(); // Use the water height of the region we're on for areas where there is no region F32 water_height = gAgent.getRegion()->getWaterHeight(); @@ -1021,7 +1037,7 @@ void LLWorld::updateWaterObjects() (S32)(512 - (region_y - min_y)) }; S32 dir; - for (dir = 0; dir < 8; dir++) + for (dir = 0; dir < EDGE_WATER_OBJECTS_COUNT; dir++) { S32 dim[2] = { 0 }; switch (gDirAxes[dir][0]) diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h index 5c43cdf4e2..5dee8eea0f 100644 --- a/indra/newview/llworld.h +++ b/indra/newview/llworld.h @@ -122,12 +122,9 @@ public: void updateRegions(F32 max_update_time); void updateVisibilities(); void updateParticles(); - void updateClouds(const F32 dt); - LLCloudGroup * findCloudGroup(const LLCloudPuff &puff); void renderPropertyLines(); - void resetStats(); void updateNetStats(); // Update network statistics for all the regions... void printPacketsLost(); @@ -140,7 +137,7 @@ public: void setLandFarClip(const F32 far_clip); LLViewerTexture *getDefaultWaterTexture(); - void updateWaterObjects(); + void updateWaterObjects(); void precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water); @@ -175,6 +172,9 @@ public: bool isRegionListed(const LLViewerRegion* region) const; private: + void clearHoleWaterObjects(); + void clearEdgeWaterObjects(); + region_list_t mActiveRegionList; region_list_t mRegionList; region_list_t mVisibleRegionList; @@ -198,15 +198,14 @@ private: U32 mNumOfActiveCachedObjects; U64MicrosecondsImplicit mSpaceTimeUSec; - BOOL mClassicCloudsEnabled; - //////////////////////////// // // Data for "Fake" objects // std::list<LLPointer<LLVOWater> > mHoleWaterObjects; - LLPointer<LLVOWater> mEdgeWaterObjects[8]; + static const S32 EDGE_WATER_OBJECTS_COUNT = 8; + LLPointer<LLVOWater> mEdgeWaterObjects[EDGE_WATER_OBJECTS_COUNT]; LLPointer<LLViewerTexture> mDefaultWaterTexturep; }; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 96ba80dacc..13d6966723 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -685,7 +685,9 @@ void LLPipeline::cleanup() mFaceSelectImagep = NULL; - mMovedBridge.clear(); + mMovedList.clear(); + mMovedBridge.clear(); + mShiftList.clear(); mInitialized = false; @@ -1773,15 +1775,20 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); - iter != gPipeline.mNearbyLights.end(); iter++) - { - if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) - { - gPipeline.mLights.erase(iter->drawable); - gPipeline.mNearbyLights.erase(iter); - } - } + light_set_t::iterator iter = gPipeline.mNearbyLights.begin(); + + while (iter != gPipeline.mNearbyLights.end()) + { + if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar) + { + gPipeline.mLights.erase(iter->drawable); + iter = gPipeline.mNearbyLights.erase(iter); + } + else + { + iter++; + } + } } U32 LLPipeline::addObject(LLViewerObject *vobj) @@ -2817,6 +2824,14 @@ void LLPipeline::clearRebuildDrawables() drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD); } mMovedList.clear(); + + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); + iter != mShiftList.end(); ++iter) + { + LLDrawable *drawablep = *iter; + drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD | LLDrawable::ON_SHIFT_LIST); + } + mShiftList.clear(); } void LLPipeline::rebuildPriorityGroups() @@ -10906,6 +10921,8 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) if (preview_avatar) { // Only show rigged attachments for preview + // For the sake of performance and so that static + // objects won't obstruct previewing changes LLVOAvatar::attachment_map_t::iterator iter; for (iter = avatar->mAttachmentPoints.begin(); iter != avatar->mAttachmentPoints.end(); @@ -10917,9 +10934,27 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) ++attachment_iter) { LLViewerObject* attached_object = attachment_iter->get(); - if (attached_object && attached_object->isRiggedMesh()) + if (attached_object) { - markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + if (attached_object->isRiggedMesh()) + { + markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + } + else + { + // sometimes object is a linkset and rigged mesh is a child + LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); + for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); + iter != child_list.end(); iter++) + { + LLViewerObject* child = *iter; + if (child->isRiggedMesh()) + { + markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera); + break; + } + } + } } } } diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 62d3ae7a39..0830d4a2ea 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -465,7 +465,7 @@ public: RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED, RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS, RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT, - RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT, + RENDER_TYPE_PASS_FULLBRIGHT_RIGGED = LLRenderPass::PASS_FULLBRIGHT_RIGGED, RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE, RENDER_TYPE_PASS_INVISIBLE_RIGGED = LLRenderPass::PASS_INVISIBLE_RIGGED, RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY, diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml index c3ce83e834..8bb3feaeb0 100644 --- a/indra/newview/skins/default/colors.xml +++ b/indra/newview/skins/default/colors.xml @@ -985,4 +985,10 @@ <color name="AddPaymentPanel" value="0.27 0.27 0.27 1" /> + <color + name="OutfitSnapshotMacMask" + value="0.115 0.115 0.115 1"/> + <color + name="OutfitSnapshotMacMask2" + value="0.1 0.1 0.1 1"/> </colors> diff --git a/indra/newview/skins/default/xui/en/floater_about_land.xml b/indra/newview/skins/default/xui/en/floater_about_land.xml index 4678d65b85..4985d07eb9 100644 --- a/indra/newview/skins/default/xui/en/floater_about_land.xml +++ b/indra/newview/skins/default/xui/en/floater_about_land.xml @@ -2,13 +2,16 @@ <floater positioning="cascading" can_tear_off="false" - height="396" + can_resize="true" layout="topleft" name="floaterland" help_topic="floaterland" save_rect="true" title="ABOUT LAND" - width="634"> + height="396" + width="634" + min_height="420" + min_width="634"> <floater.string name="maturity_icon_general"> "Parcel_PG_Dark" @@ -659,10 +662,11 @@ type="string" length="1" enabled="false" - follows="top|left" + follows="top|left|right" height="175" layout="topleft" left="10" + right="-10" max_length="65535" name="covenant_editor" width="470" @@ -1129,25 +1133,25 @@ top_delta="-6"/> <button enabled="false" - follows="left|top" + follows="top|right" height="23" label="Return Objects" layout="topleft" left_pad="6" name="Return objects..." top_delta="0" - right="-154" + right="-10" width="164" /> <name_list column_padding="0" draw_heading="true" - follows="top|left" + follows="all" height="150" layout="topleft" left="10" name="owner list" name_column="name" - width="470"> + right="-10"> <name_list.columns label="Type" name="type" @@ -1341,9 +1345,9 @@ Only large parcels can be listed in search. <panel bevel_style="none" border="true" - top="121" - bottom="121" - follows="left|bottom|right" + top="116" + bottom="116" + follows="left|top|right" left="20" right="-20"/> <check_box @@ -1377,9 +1381,10 @@ Only large parcels can be listed in search. enabled="true" height="23" layout="topleft" - left="164" + left="18" top="194" name="land category" + follows="left|top" visible="true" width="140"> <combo_box.item @@ -1508,18 +1513,18 @@ Only large parcels can be listed in search. Landing Point: [LANDING] </text> <button - follows="right|top" + follows="left|top" top_pad="0" height="23" label="Set" label_selected="Set" layout="topleft" name="Set" - left="399" + left_delta="0" tool_tip="Sets the landing point where visitors arrive. Sets to your avatar's location inside this parcel." width="50" /> <button - follows="right|top" + follows="left|top" height="23" label="Clear" label_selected="Clear" @@ -1546,7 +1551,8 @@ Only large parcels can be listed in search. layout="topleft" name="landing type" top_pad="0" - left="399" + left_delta="0" + follows="left|top" tool_tip="Teleport Routing -- select how to handle teleports onto your land" width="120"> <combo_box.item @@ -1590,7 +1596,8 @@ Only large parcels can be listed in search. <combo_box height="23" layout="topleft" - left_pad="144" + left_pad="0" + follows="left|top" name="media type" tool_tip="Specify if the URL is a movie, web page, or other media" width="120" @@ -1625,11 +1632,11 @@ Only large parcels can be listed in search. width="300" top_delta="0"/> <button - follows="right|top" + follows="left|top" height="23" label="Set" layout="topleft" - left_pad="149" + left_pad="3" name="set_media_url" width="70" top_delta="0"/> @@ -1908,7 +1915,7 @@ Only large parcels can be listed in search. </text> <check_box height="16" - label="Obscure MOAP" + label="Restrict MOAP to this parcel" layout="topleft" left="110" left_pad="0" @@ -1985,7 +1992,8 @@ Only large parcels can be listed in search. <combo_box height="23" layout="topleft" - left_pad="166" + follows="left|top" + left_pad="22" name="pass_combo" top_delta="0" width="100"> @@ -2039,14 +2047,21 @@ Only large parcels can be listed in search. top_pad="5" width="400"> (The estate owner may have limited these choices) - </text> - <panel - name="Allowed_layout_panel" - follows="top|left" - left="10" - height="170" - top_pad="8" - width="240"> + </text> + <layout_stack name="access_stack" + height="170" + follows="all" + animate="false" + left="10" + right="-10" + top_pad="8" + orientation="horizontal"> + <layout_panel + auto_resize="true" + user_resize="false" + name="Allowed_layout_panel" + height="170" + width="240"> <text type="string" length="1" @@ -2062,7 +2077,7 @@ Only large parcels can be listed in search. </text> <name_list column_padding="0" - follows="top|bottom" + follows="all" heading_height="14" height="125" layout="topleft" @@ -2070,7 +2085,7 @@ Only large parcels can be listed in search. multi_select="true" name="AccessList" tool_tip="([LISTED] listed, [MAX] max)" - width="230" /> + width="228" /> <button follows="bottom" height="23" @@ -2080,22 +2095,21 @@ Only large parcels can be listed in search. name="add_allowed" width="100" /> <button - follows="bottom" + follows="right|bottom" height="23" label="Remove" label_selected="Remove" layout="topleft" - left_pad="10" + left_pad="28" name="remove_allowed" - right="-10" width="100" /> - </panel> - <panel + </layout_panel> + <layout_panel + auto_resize="true" + user_resize="false" name="Banned_layout_panel" - follows="top|right" height="170" - width="240" - left_pad="146"> + width="240"> <text type="string" length="1" @@ -2103,7 +2117,7 @@ Only large parcels can be listed in search. height="16" label="Ban" layout="topleft" - left="0" + left="1" name="BanCheck" top="0" width="200"> @@ -2111,11 +2125,11 @@ Only large parcels can be listed in search. </text> <name_list column_padding="0" - follows="top|bottom" + follows="all" heading_height="16" height="125" layout="topleft" - left="0" + left="1" multi_select="true" draw_heading="true" name="BannedList" @@ -2135,21 +2149,21 @@ Only large parcels can be listed in search. height="23" label="Add" layout="topleft" - left="0" + left="1" name="add_banned" width="100" /> <button enabled="false" - follows="bottom" + follows="right|bottom" height="23" label="Remove" label_selected="Remove" layout="topleft" - left_pad="10" + left_pad="29" name="remove_banned" - right="-10" width="100" /> - </panel> + </layout_panel> + </layout_stack> </panel> <panel border="true" diff --git a/indra/newview/skins/default/xui/en/floater_how_to.xml b/indra/newview/skins/default/xui/en/floater_how_to.xml index baff8e1bc0..19e42798af 100644 --- a/indra/newview/skins/default/xui/en/floater_how_to.xml +++ b/indra/newview/skins/default/xui/en/floater_how_to.xml @@ -3,7 +3,6 @@ legacy_header_height="18" can_resize="false" can_minimize="false" - can_close="false" height="525" layout="topleft" name="floater_how_to" diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml index 15f02ab9c3..da84fbeea6 100644 --- a/indra/newview/skins/default/xui/en/floater_im_session.xml +++ b/indra/newview/skins/default/xui/en/floater_im_session.xml @@ -221,20 +221,6 @@ right="-1" bottom="-1"> <layout_panel - auto_resize="false" - height="26" - name="translate_chat_checkbox_lp"> - <check_box - top="10" - control_name="TranslateChat" - enabled="true" - height="16" - label="Translate chat" - left="5" - name="translate_chat_checkbox" - width="230" /> - </layout_panel> - <layout_panel name="chat_holder"> <chat_history font="SansSerifSmall" diff --git a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml deleted file mode 100644 index 15c480f144..0000000000 --- a/indra/newview/skins/default/xui/en/floater_outfit_snapshot.xml +++ /dev/null @@ -1,351 +0,0 @@ -<?xml version="1.0" encoding="utf-8" standalone="yes" ?> -<floater - positioning="cascading" - legacy_header_height="18" - can_minimize="true" - can_resize="false" - can_close="true" - height="455" - layout="topleft" - name="outfit_snapshot" - single_instance="true" - help_topic="snapshot" - save_rect="true" - save_visibility="false" - title="OUTFIT SNAPSHOT" - width="624" - min_height="455"> - <floater.string - name="unknown"> - unknown - </floater.string> - <string - name="inventory_progress_str"> - Saving to Inventory - </string> - <string - name="inventory_succeeded_str"> - Saved to Inventory! - </string> - <string - name="inventory_failed_str"> - Failed to save to inventory. - </string> - <button - follows="left|top" - height="25" - image_overlay="Refresh_Off" - image_hover_unselected="Toolbar_Middle_Over" - image_selected="Toolbar_Middle_Selected" - image_unselected="Toolbar_Middle_Off" - image_overlay_alignment="left" - imgoverlay_label_space="5" - pad_bottom="0" - halign="left" - layout="topleft" - left="10" - label="REFRESH" - name="new_snapshot_btn" - top_pad="26" - width="167" /> - <button - follows="left|top" - control_name="AdvanceOutfitSnapshot" - invisibility_control="AdvanceOutfitSnapshot" - height="25" - is_toggle="true" - layout="topleft" - image_hover_unselected="Toolbar_Middle_Over" - image_selected="Toolbar_Middle_Off" - image_unselected="Toolbar_Middle_Off" - image_overlay="Conv_toolbar_expand" - name="retract_btn" - left_pad="1" - top_delta="0" - width="31" /> - <button - follows="left|top" - control_name="AdvanceOutfitSnapshot" - visibility_control="AdvanceOutfitSnapshot" - height="25" - is_toggle="true" - layout="topleft" - image_overlay="Conv_toolbar_collapse" - image_hover_unselected="Toolbar_Middle_Over" - image_selected="Toolbar_Middle_Off" - image_unselected="Toolbar_Middle_Off" - name="extend_btn" - left_delta="0" - top_delta="0" - width="31" /> - <panel - height="154" - layout="topleft" - follows="top|left" - left="0" - name="advanced_options_panel" - top_pad="-6" - width="210"> - <view_border - bevel_style="in" - follows="left|top|right" - height="1" - left="10" - layout="topleft" - name="advanced_options_hr" - right="-1" - top_pad="5" - /> - <text - type="string" - length="1" - follows="left|top" - height="13" - layout="topleft" - left="10" - name="layer_type_label" - top_pad="10" - width="100"> - Capture: - </text> - <check_box - label="Interface" - layout="topleft" - left="30" - height="16" - top_pad="8" - width="180" - name="ui_check" /> - <check_box - label="HUDs" - layout="topleft" - height="16" - left="30" - top_pad="1" - width="180" - name="hud_check" /> - <check_box - label="Freeze frame (fullscreen)" - layout="topleft" - height="16" - left="10" - top_pad="1" - width="180" - name="freeze_frame_check" /> - <check_box - label="Auto-refresh" - layout="topleft" - height="16" - left="10" - top_pad="1" - width="180" - name="auto_snapshot_check" /> - <text - type="string" - length="1" - follows="left|top" - height="13" - layout="topleft" - left="10" - name="filter_list_label" - top_pad="10" - width="50"> - Filter: - </text> - <combo_box - control_name="PhotoFilters" - follows="left|right|top" - name="filters_combobox" - tool_tip="Image filters" - top_delta="-3" - left="50" - right="-1" - height="21" - width="135"> - <combo_box.item - label="No Filter" - name="NoFilter" - value="NoFilter" /> - </combo_box> - <view_border - bevel_style="in" - follows="left|top|right" - height="1" - left="10" - layout="topleft" - name="advanced_options_hr" - right="-1" - top_pad="7" - /> - </panel> - <panel - class="llpaneloutfitsnapshotinventory" - follows="left|top" - height="230" - layout="topleft" - left="0" - name="panel_outfit_snapshot_inventory" - filename="panel_outfit_snapshot_inventory.xml" - top_pad="10" - width="215" - /> - <view_border - bevel_style="in" - follows="left|top" - height="1" - left="10" - layout="topleft" - name="status_hr" - width="199" - top_pad="-16"/> - <panel - background_visible="false" - follows="left|top" - font="SansSerifLarge" - halign="center" - height="20" - layout="topleft" - left="10" - length="1" - name="succeeded_panel" - width="198" - top_pad="1" - type="string" - visible="false"> - <text - follows="all" - font="SansSerif" - halign="center" - height="18" - layout="topleft" - left="1" - length="1" - name="succeeded_lbl" - right="-1" - text_color="0.2 0.85 0.2 1" - top="4" - translate="false" - type="string"> - Succeeded - </text> - </panel> - <panel - background_visible="false" - follows="left|top" - font="SansSerifLarge" - halign="center" - height="20" - layout="topleft" - left="10" - length="1" - name="failed_panel" - width="198" - top_delta="0" - type="string" - visible="false"> - <text - follows="all" - font="SansSerif" - halign="center" - height="18" - layout="topleft" - left="1" - length="1" - name="failed_lbl" - right="-1" - text_color="0.95 0.4 0.4 1" - top="4" - translate="false" - type="string"> - Failed - </text> - </panel> - <loading_indicator - follows="left|top" - height="24" - layout="topleft" - name="working_indicator" - left="10" - top_delta="0" - visible="false" - width="24" /> - <text - follows="left|top" - font="SansSerifBold" - height="14" - layout="topleft" - left_pad="3" - length="1" - halign="left" - name="working_lbl" - top_delta="5" - translate="false" - type="string" - visible="false" - width="162"> - Working - </text> - <text - follows="left|top" - font="SansSerifBold" - halign="left" - height="18" - layout="topleft" - left="10" - length="1" - name="refresh_lbl" - text_color="0.95 0.4 0.4 1" - top_delta="0" - translate="false" - type="string" - visible="false" - width="130"> - Refresh to save. - </text> - <ui_ctrl - layout="topleft" - name="thumbnail_placeholder" - top="23" - left="215" - width="400" - height="400" - follows="top|left"/> - <view_border - bevel_style="in" - height="21" - layout="topleft" - name="img_info_border" - top_pad="0" - right="-10" - follows="left|top|right" - left_delta="0"/> - <text - type="string" - font="SansSerifSmall" - length="1" - follows="left|top|right" - height="14" - layout="topleft" - left="220" - right="-20" - halign="left" - name="image_res_text" - top_delta="5" - width="200"> - [WIDTH]px (width) x [HEIGHT]px (height) - </text> - <text - follows="right|top" - font="SansSerifSmall" - height="14" - layout="topleft" - left="-65" - length="1" - halign="right" - name="file_size_label" - top_delta="0" - type="string" - width="50"> - [SIZE] KB - </text> -</floater> diff --git a/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml b/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml new file mode 100644 index 0000000000..5ece7b85d5 --- /dev/null +++ b/indra/newview/skins/default/xui/en/floater_simple_outfit_snapshot.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8" standalone="yes" ?> +<floater + positioning="cascading" + legacy_header_height="18" + can_minimize="true" + can_resize="false" + can_close="true" + height="305" + layout="topleft" + name="simple_outfit_snapshot" + single_instance="true" + help_topic="snapshot" + save_rect="true" + save_visibility="false" + title="OUTFIT SNAPSHOT" + width="351"> + <ui_ctrl + layout="topleft" + name="thumbnail_placeholder" + top="18" + left="22" + width="335" + height="200" + follows="top|left"/> + <button + follows="left|bottom" + height="22" + layout="topleft" + left="29" + label="Take photo" + name="new_snapshot_btn" + bottom="-15" + width="90" /> + <button + follows="left|bottom" + height="22" + layout="topleft" + left_pad="10" + label="Save (L$[UPLOAD_COST])" + name="save_btn" + width="90" /> + <button + follows="left|bottom" + height="22" + layout="topleft" + left_pad="10" + label="Cancel" + name="cancel_btn" + width="90" /> +</floater> diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml index a8db0aca4e..7e172e138a 100644 --- a/indra/newview/skins/default/xui/en/floater_tos.xml +++ b/indra/newview/skins/default/xui/en/floater_tos.xml @@ -76,7 +76,7 @@ word_wrap="true" text_readonly_color="LabelDisabledColor" width="552"> - I have read and agree to the Second Life Terms and Conditions, Privacy Policy, and Terms of Service, including the dispute resolution requirements. + I consent to the Linden Lab Terms of Service, Second Life Terms and Conditions, and acknowledge receipt of the Privacy Policy. </text> <button enabled="false" diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml index 842184de88..bab37c6258 100644 --- a/indra/newview/skins/default/xui/en/main_view.xml +++ b/indra/newview/skins/default/xui/en/main_view.xml @@ -8,16 +8,6 @@ tab_stop="false" name="main_view" width="1024"> - - <!-- At the moment layout_stack is not an LLUICtrl, - but Tab requires focus_root to function and focus_root - functionality is implemented in LLUICtrl --> - <panel follows="all" - height="768" - name="menu_tab_wrapper" - mouse_opaque="false" - focus_root="true" - top="0"> <layout_stack border_size="0" follows="all" mouse_opaque="false" @@ -25,31 +15,35 @@ name="menu_stack" orientation="vertical" top="0"> + <!-- Menu, nav bar and status bar need common focus_root--> <layout_panel mouse_opaque="true" follows="left|right|top" name="status_bar_container" + focus_root="true" height="19" left="0" top="0" width="1024" auto_resize="false" - default_tab_group="1" visible="true"> <view mouse_opaque="false" - follows="all" + follows="top|left|right" name="menu_bar_holder" + tab_group="1" left="0" top="0" width="1024" - tab_group="1" height="19"/> + <view mouse_opaque="false" + follows="top|left|right" + name="nav_bar_container" + tab_group="3" + left="0" + top="19" + width="1024" + height="34" + visible="false"/> </layout_panel> - <layout_panel auto_resize="false" - height="34" - mouse_opaque="false" - name="nav_bar_container" - width="1024" - visible="false"/> <layout_panel auto_resize="true" follows="all" height="500" @@ -109,7 +103,6 @@ tab_stop="false"/> </layout_panel> </layout_stack> - </panel> <!--menu_tab_wrapper--> <panel top="0" follows="all" diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 1ddec93668..d1a99133f0 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -9689,7 +9689,7 @@ Do you wish to continue? The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh. <tag>confirm</tag> <usetemplate - ignoretext="The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh." + ignoretext="The selected object affects the navmesh. Changing it to a Flexible Path will remove it from the navmesh." name="okcancelignore" notext="Cancel" yestext="OK"/> @@ -11914,4 +11914,20 @@ Unpacking: [UNPACK_TIME]s [USIZE]KB yestext="OK"/> </notification> + <notification + icon="alertmodal.tga" + name="RiggedMeshAttachedToHUD" + type="alertmodal"> + An object "[NAME]" attached to HUD point "[POINT]" contains rigged mesh. + +Rigged mesh objects are designed for attachment to the avatar. You will see this object but no one else will. + +If you want others to see this object, remove it and re-attach it to an avatar attachment point. + <tag>confirm</tag> + <usetemplate + ignoretext="Warn me when rigged mesh is attached to HUD point." + name="okignore" + yestext="OK"/> + </notification> + </notifications> diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml index 4de56b424e..edc1fb21e7 100644 --- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml +++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml @@ -18,26 +18,6 @@ orientation="vertical" width="242"> <layout_panel - auto_resize="false" - height="26" - layout="topleft" - left_delta="0" - name="translate_chat_checkbox_lp" - top_delta="0" - visible="true" - width="230"> - <check_box - top="10" - control_name="TranslateChat" - enabled="true" - height="16" - label="Translate chat" - layout="topleft" - left="5" - name="translate_chat_checkbox" - width="230" /> - </layout_panel> - <layout_panel auto_resize="true" height="138" left_delta="0" diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml index 42a34d171a..ab2e9c72f3 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml @@ -322,154 +322,161 @@ name="enable_voice_check" width="110"/> <!-- --> - <text - follows="left|top" - layout="topleft" - height="15" - left="0" - top_pad="3" - width="120" - halign="right" - name="media_autoplay_label"> - Media auto-play - </text> - <combo_box + <text + type="string" + length="1" + follows="left|top" + layout="topleft" + left="23" + top_delta="22" + name="Listen media from" + height="15" + word_wrap="true" + width="112"> + Hear media and sounds from: + </text> + <radio_group + control_name="MediaSoundsEarLocation" + follows="left|top" + top_delta="-6" + layout="topleft" + left_pad="20" + width="360" + height="40" + name="media_ear_location"> + <radio_item + height="19" + label="Camera position" + follows="left|top" + layout="topleft" + name="0" + width="200"/> + <radio_item + height="19" + follows="left|top" + label="Avatar position" + layout="topleft" + left_delta="0" + name="1" + top_delta ="18" + width="200" /> + </radio_group> + <check_box + name="media_show_on_others_btn" + control_name="MediaShowOnOthers" + value="true" + follows="left|top" + layout="topleft" + height="15" + top_pad="8" + tool_tip="Uncheck this to hide media attached to other avatars nearby" + label="Play media attached to other avatars" + left="20" + width="230"/> + <text + follows="left|top" + layout="topleft" + height="15" + left="23" + top_pad="8" + width="120" + name="media_autoplay_label"> + Auto-play media + </text> + <combo_box control_name="ParcelMediaAutoPlayEnable" enabled_control="AudioStreamingMedia" follows="left|top" layout="topleft" height="23" - left_pad="7" + left_pad="-15" top_delta="-4" name="media_auto_play_combo" - width="100"> - <item - label="No" - name="autoplay_disabled" - value="0"/> - <item - label="Yes" - name="autoplay_enabled" - value="1"/> - <item - label="Ask" - name="autoplay_ask" - value="2"/> - </combo_box> - <check_box - name="media_show_on_others_btn" - control_name="MediaShowOnOthers" - value="true" - follows="left|bottom|right" - height="15" - tool_tip="Uncheck this to hide media attached to other avatars nearby" - label="Play media attached to other avatars" - left="25" - width="230"/> - <check_box - name="gesture_audio_play_btn" - control_name="EnableGestureSounds" - disabled_control="MuteAudio" - value="true" - follows="left|bottom|right" - height="15" - tool_tip="Check this to hear sounds from gestures" - label="Play sounds from gestures" - top_pad="1" - left="25"/> - <text - type="string" - length="1" - follows="left|top" - height="20" - layout="topleft" - left="25" - name="voice_chat_settings" - width="200" - top_pad="16"> - Voice Chat Settings - </text> - <text - type="string" - length="1" - follows="left|top" - layout="topleft" - left="46" - top_delta="16" - name="Listen from" - width="112"> - Listen from: - </text> - <icon - follows="left|top" - height="18" - image_name="Cam_FreeCam_Off" - layout="topleft" - name="camera_icon" - mouse_opaque="false" - visible="true" - width="18" - left_pad="-4" - top_delta="-5"/> - <icon - follows="left|top" - height="18" - image_name="Move_Walk_Off" - layout="topleft" - left_pad="170" - name="avatar_icon" - mouse_opaque="false" - visible="true" - width="18" - top_delta="0" /> - <radio_group - enabled_control="EnableVoiceChat" - control_name="VoiceEarLocation" - follows="left|top" - layout="topleft" - left_delta="-168" - width="360" - height="20" - name="ear_location"> - <radio_item - height="19" - label="Camera position" - follows="left|top" - layout="topleft" - name="0" - width="200"/> - <radio_item - height="19" - follows="left|top" - label="Avatar position" - layout="topleft" - left_pad="-16" - name="1" - top_delta ="0" - width="200" /> - </radio_group> + width="115"> + <item + label="Never" + name="autoplay_disabled" + value="0"/> + <item + label="Always" + name="autoplay_enabled" + value="1"/> + <item + label="Ask" + name="autoplay_ask" + value="2"/> + </combo_box> + <text + type="string" + length="1" + follows="left|top" + layout="topleft" + left="23" + top_delta="30" + name="Listen from" + width="112"> + Hear voice from: + </text> + <radio_group + enabled_control="EnableVoiceChat" + control_name="VoiceEarLocation" + follows="left|top" + layout="topleft" + left_pad="20" + top_delta="-6" + width="360" + height="40" + name="ear_location"> + <radio_item + height="19" + label="Camera position" + follows="left|top" + layout="topleft" + name="0" + width="200"/> + <radio_item + height="19" + follows="left|top" + label="Avatar position" + layout="topleft" + left_delta="0" + name="1" + top_delta ="18" + width="200" /> + </radio_group> <check_box control_name="LipSyncEnabled" follows="left|top" height="15" label="Move avatar lips when speaking" layout="topleft" - left="44" + left="20" name="enable_lip_sync" - top_pad="5" + top_pad="10" width="237"/> - <check_box - follows="top|left" - enabled_control="EnableVoiceChat" - control_name="PushToTalkToggle" - height="15" - label="Toggle speak on/off when I press button in toolbar" - layout="topleft" - left="44" - name="push_to_talk_toggle_check" - width="237" - tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down." - top_pad="3"/> + <check_box + follows="top|left" + enabled_control="EnableVoiceChat" + control_name="PushToTalkToggle" + height="15" + label="Toggle speak on/off when I press button in toolbar" + layout="topleft" + left="20" + name="push_to_talk_toggle_check" + width="237" + tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down." + top_pad="5"/> + <check_box + name="gesture_audio_play_btn" + control_name="EnableGestureSounds" + disabled_control="MuteAudio" + value="true" + follows="left|bottom|right" + height="15" + tool_tip="Check this to hear sounds from gestures" + label="Play sounds from gestures" + top_pad="5" + left="20"/> <button control_name="ShowDeviceSettings" follows="left|top" @@ -478,7 +485,7 @@ label="Voice Input/Output devices" layout="topleft" left="20" - top_pad="6" + top_pad="9" name="device_settings_btn" width="230"> </button> diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml index 6f95e282ca..cf5d98aa9a 100644 --- a/indra/newview/skins/default/xui/en/strings.xml +++ b/indra/newview/skins/default/xui/en/strings.xml @@ -4300,6 +4300,10 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string> <string name="Mav_Details_MAV_CONFIRMATION_DATA_MISMATCH"> The physics shape contains bad confirmation data. Try to correct the physics model. </string> + <!-- MAV_BLOCK_MISSING means server didn't get and couldn't substitute physics_convex, high_lod or BoundingVerts--> + <string name="Mav_Details_MAV_BLOCK_MISSING"> + Missing data. Make sure high lod is present and valid. Set the physics model if not set. + </string> <string name="Mav_Details_MAV_UNKNOWN_VERSION"> The physics shape does not have correct version. Set the correct version for the physics model. </string> |