From 59becbde7577d035f2e9a2a54b94ff2d554e7e73 Mon Sep 17 00:00:00 2001 From: ZiRee Date: Thu, 28 Jul 2022 16:12:17 +0000 Subject: GCC11.1 warning: moving a local object in a return statement prevents copy elision [-Werror=pessimizing-move] --- indra/llcommon/threadsafeschedule.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llcommon/threadsafeschedule.h b/indra/llcommon/threadsafeschedule.h index 3e0da94c02..0c3a541196 100644 --- a/indra/llcommon/threadsafeschedule.h +++ b/indra/llcommon/threadsafeschedule.h @@ -248,7 +248,7 @@ namespace LL TimePoint until = TimePoint::clock::now() + std::chrono::hours(24); pop_result popped = tryPopUntil_(lock, until, tt); if (popped == POPPED) - return std::move(tt); + return tt; // DONE: throw, just as super::pop() does if (popped == DONE) -- cgit v1.2.3 From 97b0b87f7a908750763a4a357be15dc42f8f8cd3 Mon Sep 17 00:00:00 2001 From: ZiRee Date: Thu, 28 Jul 2022 16:15:35 +0000 Subject: Creating an LLVector4 from LLColor3 causes an array out of bounds read on reading .mV[3]. Doing a detour via LLVector3 fixes this but maybe there is a less roundabout way. --- indra/newview/llsettingsvo.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 7c762170a7..707b602fc6 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -694,8 +694,8 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky(); - LLVector4 sunDiffuse = LLVector4(psky->getSunlightColor().mV); - LLVector4 moonDiffuse = LLVector4(psky->getMoonlightColor().mV); + LLVector4 sunDiffuse = LLVector4(LLVector3(psky->getSunlightColor().mV)); + LLVector4 moonDiffuse = LLVector4(LLVector3(psky->getMoonlightColor().mV)); shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse); shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse); -- cgit v1.2.3 From 94cb1ba16c5b301779e437f73af9e06558f15760 Mon Sep 17 00:00:00 2001 From: ZiRee Date: Thu, 28 Jul 2022 16:18:30 +0000 Subject: GCC11.1 does not like these being floats, so cast them to U32 before using them as array size: error: expression in new-declarator must have integral or enumeration type --- indra/newview/llvosky.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index 1aa00bc894..909588367b 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -100,8 +100,8 @@ LLSkyTex::LLSkyTex() : void LLSkyTex::init(bool isShiny) { mIsShiny = isShiny; - mSkyData = new LLColor4[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION]; - mSkyDirs = new LLVector3[SKYTEX_RESOLUTION * SKYTEX_RESOLUTION]; + mSkyData = new LLColor4[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; + mSkyDirs = new LLVector3[(U32)(SKYTEX_RESOLUTION * SKYTEX_RESOLUTION)]; for (S32 i = 0; i < 2; ++i) { -- cgit v1.2.3 From e980999fb6d76089e224f32668cc4bde8f88dbaa Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Mon, 19 Sep 2022 17:48:55 +0300 Subject: SL-18171 Remove link that opens old help browser --- .../skins/default/xui/en/floater_object_weights.xml | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/indra/newview/skins/default/xui/en/floater_object_weights.xml b/indra/newview/skins/default/xui/en/floater_object_weights.xml index eb283a1043..889efa061c 100644 --- a/indra/newview/skins/default/xui/en/floater_object_weights.xml +++ b/indra/newview/skins/default/xui/en/floater_object_weights.xml @@ -2,7 +2,7 @@ - - - -- cgit v1.2.3 From 1b31ab5c5279829ace4144c7495ad4f961c2f202 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 14:42:53 -0400 Subject: Introduce a U8* based interface to unzip_llsd and unpackVolumeFaces --- indra/llcommon/llsdserialize.cpp | 121 +++++++++++++++++++++------------------ indra/llcommon/llsdserialize.h | 6 ++ indra/llmath/llvolume.cpp | 20 ++++++- indra/llmath/llvolume.h | 6 +- 4 files changed, 96 insertions(+), 57 deletions(-) diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp index 8b4a0ee6d8..a510b73096 100644 --- a/indra/llcommon/llsdserialize.cpp +++ b/indra/llcommon/llsdserialize.cpp @@ -34,6 +34,9 @@ #include #include "apr_base64.h" +#include +#include + #ifdef LL_USESYSTEMLIBS # include #else @@ -2128,7 +2131,9 @@ std::string zip_llsd(LLSD& data) { //copy result into output if (strm.avail_out >= CHUNK) { - free(output); + deflateEnd(&strm); + if(output) + free(output); LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL; return std::string(); } @@ -2151,7 +2156,9 @@ std::string zip_llsd(LLSD& data) } else { - free(output); + deflateEnd(&strm); + if(output) + free(output); LL_WARNS() << "Failed to compress LLSD block." << LL_ENDL; return std::string(); } @@ -2162,7 +2169,8 @@ std::string zip_llsd(LLSD& data) std::string result((char*) output, size); deflateEnd(&strm); - free(output); + if(output) + free(output); return result; } @@ -2171,54 +2179,67 @@ std::string zip_llsd(LLSD& data) // not very efficient -- creats a copy of decompressed LLSD block in memory // and deserializes from that copy using LLSDSerialize LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, S32 size) +{ + std::unique_ptr in = std::unique_ptr(new(std::nothrow) U8[size]); + if (!in) + { + return ZR_MEM_ERROR; + } + is.read((char*) in.get(), size); + + return unzip_llsd(data, in.get(), size); +} + +LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, const U8* in, S32 size) { U8* result = NULL; U32 cur_size = 0; z_stream strm; - const U32 CHUNK = 65536; + constexpr U32 CHUNK = 1024 * 512; - U8 *in = new(std::nothrow) U8[size]; - if (!in) + static thread_local std::unique_ptr out; + if (!out) { - return ZR_MEM_ERROR; + out = std::unique_ptr(new(std::nothrow) U8[CHUNK]); } - is.read((char*) in, size); - - U8 out[CHUNK]; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; strm.avail_in = size; - strm.next_in = in; + strm.next_in = const_cast(in); S32 ret = inflateInit(&strm); do { strm.avail_out = CHUNK; - strm.next_out = out; + strm.next_out = out.get(); ret = inflate(&strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR) + switch (ret) + { + case Z_NEED_DICT: + case Z_DATA_ERROR: { inflateEnd(&strm); free(result); - delete [] in; return ZR_DATA_ERROR; } - - switch (ret) + case Z_STREAM_ERROR: + case Z_BUF_ERROR: { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; - case Z_DATA_ERROR: + inflateEnd(&strm); + free(result); + return ZR_BUFFER_ERROR; + } + case Z_MEM_ERROR: + { inflateEnd(&strm); free(result); - delete [] in; return ZR_MEM_ERROR; - break; + } } U32 have = CHUNK-strm.avail_out; @@ -2231,17 +2252,15 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, { free(result); } - delete[] in; return ZR_MEM_ERROR; } result = new_result; - memcpy(result+cur_size, out, have); + memcpy(result+cur_size, out.get(), have); cur_size += have; - } while (ret == Z_OK); + } while (ret == Z_OK && ret != Z_STREAM_END); inflateEnd(&strm); - delete [] in; if (ret != Z_STREAM_END) { @@ -2251,37 +2270,11 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is, //result now points to the decompressed LLSD block { - std::istringstream istr; - // Since we are using this for meshes, data we are dealing with tend to be large. - // So string can potentially fail to allocate, make sure this won't cause problems - try - { - std::string res_str((char*)result, cur_size); - - std::string deprecated_header(""); - - if (res_str.substr(0, deprecated_header.size()) == deprecated_header) - { - res_str = res_str.substr(deprecated_header.size() + 1, cur_size); - } - cur_size = res_str.size(); - - istr.str(res_str); - } -#ifdef LL_WINDOWS - catch (std::length_error) - { - free(result); - return ZR_SIZE_ERROR; - } -#endif - catch (std::bad_alloc&) - { - free(result); - return ZR_MEM_ERROR; - } + char* result_ptr = strip_deprecated_header((char*)result, cur_size); - if (!LLSDSerialize::fromBinary(data, istr, cur_size, UNZIP_LLSD_MAX_DEPTH)) + boost::iostreams::stream istrm(result_ptr, cur_size); + + if (!LLSDSerialize::fromBinary(data, istrm, cur_size, UNZIP_LLSD_MAX_DEPTH)) { free(result); return ZR_PARSE_ERROR; @@ -2395,4 +2388,22 @@ U8* unzip_llsdNavMesh( bool& valid, unsigned int& outsize, std::istream& is, S32 return result; } +char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size) +{ + const char* deprecated_header = ""; + constexpr size_t deprecated_header_size = 17; + + if (cur_size > deprecated_header_size + && memcmp(in, deprecated_header, deprecated_header_size) == 0) + { + in = in + deprecated_header_size; + cur_size = cur_size - deprecated_header_size; + if (header_size) + { + *header_size = deprecated_header_size + 1; + } + } + + return in; +} diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h index d6079fd9fa..d33d2b6f34 100644 --- a/indra/llcommon/llsdserialize.h +++ b/indra/llcommon/llsdserialize.h @@ -858,9 +858,12 @@ public: ZR_SIZE_ERROR, ZR_DATA_ERROR, ZR_PARSE_ERROR, + ZR_BUFFER_ERROR, + ZR_VERSION_ERROR } EZipRresult; // return OK or reason for failure static EZipRresult unzip_llsd(LLSD& data, std::istream& is, S32 size); + static EZipRresult unzip_llsd(LLSD& data, const U8* in, S32 size); }; //dirty little zip functions -- yell at davep @@ -868,4 +871,7 @@ 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); + +// returns a pointer to the array or past the array if the deprecated header exists +LL_COMMON_API char* strip_deprecated_header(char* in, U32& cur_size, U32* header_size = nullptr); #endif // LL_LLSDSERIALIZE_H diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 93f1d508f3..91457fbebe 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2391,7 +2391,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; return false; } - + return unpackVolumeFacesInternal(mdl); +} + +bool LLVolume::unpackVolumeFaces(U8* in_data, S32 size) +{ + //input data is now pointing at a zlib compressed block of LLSD + //decompress block + LLSD mdl; + U32 uzip_result = LLUZipHelper::unzip_llsd(mdl, in_data, size); + if (uzip_result != LLUZipHelper::ZR_OK) + { + LL_DEBUGS("MeshStreaming") << "Failed to unzip LLSD blob for LoD with code " << uzip_result << " , will probably fetch from sim again." << LL_ENDL; + return false; + } + return unpackVolumeFacesInternal(mdl); +} + +bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl) +{ { U32 face_count = mdl.size(); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 9697952f5b..b53b0fd1cc 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -1096,8 +1096,12 @@ protected: BOOL generate(); void createVolumeFaces(); public: - virtual bool unpackVolumeFaces(std::istream& is, S32 size); + bool unpackVolumeFaces(std::istream& is, S32 size); + bool unpackVolumeFaces(U8* in_data, S32 size); +private: + bool unpackVolumeFacesInternal(const LLSD& mdl); +public: virtual void setMeshAssetLoaded(BOOL loaded); virtual BOOL isMeshAssetLoaded(); -- cgit v1.2.3 From 4be11d87b5941b0a2159f62ab40500945cc873d5 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 14:44:19 -0400 Subject: Utilize pointer based unzip_llsd and unpackVolumeFaces in meshrepo and materialmgr --- indra/newview/llmaterialmgr.cpp | 18 +++++-------- indra/newview/llmeshrepository.cpp | 52 ++++---------------------------------- 2 files changed, 11 insertions(+), 59 deletions(-) diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp index 11aa607393..6e1e6506d9 100644 --- a/indra/newview/llmaterialmgr.cpp +++ b/indra/newview/llmaterialmgr.cpp @@ -429,12 +429,10 @@ void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUI llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); - LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); - std::string content_string(reinterpret_cast(content_binary.data()), content_binary.size()); - std::istringstream content_stream(content_string); + const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); LLSD response_data; - U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size()); + U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size()); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL; @@ -472,12 +470,10 @@ void LLMaterialMgr::onGetAllResponse(bool success, const LLSD& content, const LL llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); - LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); - std::string content_string(reinterpret_cast(content_binary.data()), content_binary.size()); - std::istringstream content_stream(content_string); + const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); LLSD response_data; - U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size()); + U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size()); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL; @@ -541,12 +537,10 @@ void LLMaterialMgr::onPutResponse(bool success, const LLSD& content) llassert(content.has(MATERIALS_CAP_ZIP_FIELD)); llassert(content[MATERIALS_CAP_ZIP_FIELD].isBinary()); - LLSD::Binary content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); - std::string content_string(reinterpret_cast(content_binary.data()), content_binary.size()); - std::istringstream content_stream(content_string); + const LLSD::Binary& content_binary = content[MATERIALS_CAP_ZIP_FIELD].asBinary(); LLSD response_data; - U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_stream, content_binary.size()); + U32 uzip_result = LLUZipHelper::unzip_llsd(response_data, content_binary.data(), content_binary.size()); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS("Materials") << "Cannot unzip LLSD binary content: " << uzip_result << LL_ENDL; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 4dd0543693..e1ff233354 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1911,19 +1911,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p } LLPointer volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod)); - std::istringstream stream; - try - { - std::string mesh_string((char*)data, data_size); - stream.str(mesh_string); - } - catch (std::bad_alloc&) - { - // out of memory, we won't be able to process this mesh - return MESH_OUT_OF_MEMORY; - } - - if (volume->unpackVolumeFaces(stream, data_size)) + if (volume->unpackVolumeFaces(data, data_size)) { if (volume->getNumFaces() > 0) { @@ -1953,10 +1941,7 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat { try { - std::string res_str((char*)data, data_size); - std::istringstream stream(res_str); - - U32 uzip_result = LLUZipHelper::unzip_llsd(skin, stream, data_size); + U32 uzip_result = LLUZipHelper::unzip_llsd(skin, data, data_size); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS(LOG_MESH) << "Mesh skin info parse error. Not a valid mesh asset! ID: " << mesh_id @@ -1994,10 +1979,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 { try { - std::string res_str((char*)data, data_size); - std::istringstream stream(res_str); - - U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, stream, data_size); + U32 uzip_result = LLUZipHelper::unzip_llsd(decomp, data, data_size); if (uzip_result != LLUZipHelper::ZR_OK) { LL_WARNS(LOG_MESH) << "Mesh decomposition parse error. Not a valid mesh asset! ID: " << mesh_id @@ -2006,7 +1988,7 @@ bool LLMeshRepoThread::decompositionReceived(const LLUUID& mesh_id, U8* data, S3 return false; } } - catch (std::bad_alloc&) + catch (const std::bad_alloc&) { LL_WARNS(LOG_MESH) << "Out of memory for mesh ID " << mesh_id << " of size: " << data_size << LL_ENDL; return false; @@ -2043,32 +2025,8 @@ EMeshProcessingResult LLMeshRepoThread::physicsShapeReceived(const LLUUID& mesh_ volume_params.setSculptID(mesh_id, LL_SCULPT_TYPE_MESH); LLPointer volume = new LLVolume(volume_params,0); - std::istringstream stream; - try - { - std::string mesh_string((char*)data, data_size); - stream.str(mesh_string); - } - catch (std::bad_alloc&) - { - // out of memory, we won't be able to process this mesh - delete d; - return MESH_OUT_OF_MEMORY; - } - - if (volume->unpackVolumeFaces(stream, data_size)) + if (volume->unpackVolumeFaces(data, data_size)) { - //load volume faces into decomposition buffer - S32 vertex_count = 0; - S32 index_count = 0; - - for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) - { - const LLVolumeFace& face = volume->getVolumeFace(i); - vertex_count += face.mNumVertices; - index_count += face.mNumIndices; - } - d->mPhysicsShapeMesh.clear(); std::vector& pos = d->mPhysicsShapeMesh.mPositions; -- cgit v1.2.3 From e097794919bff8456da498382b250891ab5235a0 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 14:48:19 -0400 Subject: Optimize mesh header size and data access throughout meshrepo --- indra/newview/llmeshrepository.cpp | 99 +++++++++++++++++++++----------------- indra/newview/llmeshrepository.h | 4 +- 2 files changed, 55 insertions(+), 48 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index e1ff233354..968d2ec8be 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -138,7 +138,7 @@ // data copied // headerReceived() invoked // LLSD parsed -// mMeshHeader, mMeshHeaderSize updated +// mMeshHeader updated // scan mPendingLOD for LOD request // push LODRequest to mLODReqQ // ... @@ -246,7 +246,6 @@ // sActiveLODRequests mMutex rw.any.mMutex, ro.repo.none [1] // sMaxConcurrentRequests mMutex wo.main.none, ro.repo.none, ro.main.mMutex // mMeshHeader mHeaderMutex rw.repo.mHeaderMutex, ro.main.mHeaderMutex, ro.main.none [0] -// mMeshHeaderSize mHeaderMutex rw.repo.mHeaderMutex // mSkinRequests mMutex rw.repo.mMutex, ro.repo.none [5] // mSkinInfoQ mMutex rw.repo.mMutex, rw.main.mMutex [5] (was: [0]) // mDecompositionRequests mMutex rw.repo.mMutex, ro.repo.none [5] @@ -1178,10 +1177,13 @@ void LLMeshRepoThread::lockAndLoadMeshLOD(const LLVolumeParams& mesh_params, S32 void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) { //could be called from any thread + const LLUUID& mesh_id = mesh_params.getSculptID(); LLMutexLock lock(mMutex); - mesh_header_map::iterator iter = mMeshHeader.find(mesh_params.getSculptID()); + LLMutexLock header_lock(mHeaderMutex); + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); if (iter != mMeshHeader.end()) { //if we have the header, request LOD byte range + LODRequest req(mesh_params, lod); { mLODReqQ.push(req); @@ -1317,7 +1319,8 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) mHeaderMutex->lock(); - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; @@ -1325,13 +1328,14 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) ++LLMeshRepository::sMeshRequestCount; bool ret = true; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["skin"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["skin"]["size"].asInteger(); + const LLSD& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header["skin"]["offset"].asInteger(); + S32 size = header["skin"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1413,21 +1417,23 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id) mHeaderMutex->lock(); - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; bool ret = true; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger(); + const auto& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header["physics_convex"]["offset"].asInteger(); + S32 size = header["physics_convex"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1510,21 +1516,23 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id) mHeaderMutex->lock(); - if (mMeshHeader.find(mesh_id) == mMeshHeader.end()) + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) { //we have no header info for this mesh, do nothing mHeaderMutex->unlock(); return false; } ++LLMeshRepository::sMeshRequestCount; - U32 header_size = mMeshHeaderSize[mesh_id]; + U32 header_size = header_it->second.first; bool ret = true; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger(); + const auto& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header["physics_mesh"]["offset"].asInteger(); + S32 size = header["physics_mesh"]["size"].asInteger(); mHeaderMutex->unlock(); @@ -1704,20 +1712,25 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, return false; } - mHeaderMutex->lock(); + const LLUUID& mesh_id = mesh_params.getSculptID(); + mHeaderMutex->lock(); + auto header_it = mMeshHeader.find(mesh_id); + if (header_it == mMeshHeader.end()) + { //we have no header info for this mesh, do nothing + mHeaderMutex->unlock(); + return false; + } ++LLMeshRepository::sMeshRequestCount; bool retval = true; - - LLUUID mesh_id = mesh_params.getSculptID(); - U32 header_size = mMeshHeaderSize[mesh_id]; - + U32 header_size = header_it->second.first; if (header_size > 0) { - S32 version = mMeshHeader[mesh_id]["version"].asInteger(); - S32 offset = header_size + mMeshHeader[mesh_id][header_lod[lod]]["offset"].asInteger(); - S32 size = mMeshHeader[mesh_id][header_lod[lod]]["size"].asInteger(); + const auto& header = header_it->second.second; + S32 version = header["version"].asInteger(); + S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger(); + S32 size = header[header_lod[lod]]["size"].asInteger(); mHeaderMutex->unlock(); if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0) @@ -1878,8 +1891,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes { LLMutexLock lock(mHeaderMutex); - mMeshHeaderSize[mesh_id] = header_size; - mMeshHeader[mesh_id] = header; + mMeshHeader[mesh_id] = { header_size, header }; LLMeshRepository::sCacheBytesHeaders += header_size; } @@ -2928,7 +2940,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo if (iter != mMeshHeader.end()) { - LLSD& header = iter->second; + LLSD& header = iter->second.second; return LLMeshRepository::getActualMeshLOD(header, lod); } @@ -3173,8 +3185,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id); if (iter != gMeshRepo.mThread->mMeshHeader.end()) { - header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id]; - header = iter->second; + header_bytes = (S32)iter->second.first; + header = iter->second.second; } if (header_bytes > 0 @@ -4142,16 +4154,13 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id) bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id) { LLMutexLock lock(mHeaderMutex); - if (mMeshHeaderSize[mesh_id] > 0) + mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); + if (iter != mMeshHeader.end() && iter->second.first > 0) { - mesh_header_map::iterator iter = mMeshHeader.find(mesh_id); - if (iter != mMeshHeader.end()) + LLSD &mesh = iter->second.second; + if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) { - LLSD &mesh = iter->second; - if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) - { - return true; - } + return true; } } @@ -4176,9 +4185,9 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - LLSD& header = iter->second; + const LLSD& header = iter->second.second; if (header.has("404")) { @@ -4282,9 +4291,9 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - result = getStreamingCostLegacy(iter->second, radius, bytes, bytes_visible, lod, unscaled_value); + result = getStreamingCostLegacy(iter->second.second, radius, bytes, bytes_visible, lod, unscaled_value); } } if (result > 0.f) @@ -4597,9 +4606,9 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data) { LLMutexLock lock(mThread->mHeaderMutex); LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id); - if (iter != mThread->mMeshHeader.end() && mThread->mMeshHeaderSize[mesh_id] > 0) + if (iter != mThread->mMeshHeader.end() && iter->second.first > 0) { - LLSD& header = iter->second; + LLSD& header = iter->second.second; bool header_invalid = (header.has("404") || !header.has("lowest_lod") diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f61da3e571..6f43b0aa83 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -210,10 +210,8 @@ public: LLCondition* mSignal; //map of known mesh headers - typedef std::map mesh_header_map; + typedef boost::unordered_map> mesh_header_map; // pair is header_size and data mesh_header_map mMeshHeader; - - std::map mMeshHeaderSize; class HeaderRequest : public RequestStats { -- cgit v1.2.3 From 7dcdc4c37823c2db86454d3ba142f09b0475b4d8 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 14:54:42 -0400 Subject: Replaced usage of LLVolumeParams as map key in meshrepo with the mesh uuid --- indra/newview/llmeshrepository.cpp | 47 ++++++++++++++++++++++---------------- indra/newview/llmeshrepository.h | 4 ++-- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 968d2ec8be..d5b14dc6aa 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1193,8 +1193,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) else { HeaderRequest req(mesh_params); - - pending_lod_map::iterator pending = mPendingLOD.find(mesh_params); + pending_lod_map::iterator pending = mPendingLOD.find(mesh_id); if (pending != mPendingLOD.end()) { //append this lod request to existing header request @@ -1204,7 +1203,7 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod) else { //if no header request is pending, fetch header mHeaderReqQ.push(req); - mPendingLOD[mesh_params].push_back(lod); + mPendingLOD[mesh_id].push_back(lod); } } } @@ -1805,16 +1804,19 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, } else { + LLMutexLock lock(mMutex); mUnavailableQ.push(LODRequest(mesh_params, lod)); } } else { + LLMutexLock lock(mMutex); mUnavailableQ.push(LODRequest(mesh_params, lod)); } } else { + LLMutexLock lock(mMutex); mUnavailableQ.push(LODRequest(mesh_params, lod)); } } @@ -1899,7 +1901,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time. //check for pending requests - pending_lod_map::iterator iter = mPendingLOD.find(mesh_params); + pending_lod_map::iterator iter = mPendingLOD.find(mesh_id); if (iter != mPendingLOD.end()) { for (U32 i = 0; i < iter->second.size(); ++i) @@ -3605,15 +3607,19 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes - mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_params); + const auto& mesh_id = mesh_params.getSculptID(); + mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id); if (iter != mLoadingMeshes[detail].end()) { //request pending for this mesh, append volume id to list - iter->second.insert(vobj->getID()); + auto it = std::find(iter->second.begin(), iter->second.end(), vobj->getID()); + if (it == iter->second.end()) { + iter->second.push_back(vobj->getID()); + } } else { //first request for this mesh - mLoadingMeshes[detail][mesh_params].insert(vobj->getID()); + mLoadingMeshes[detail][mesh_id].push_back(vobj->getID()); mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail)); LLMeshRepository::sLODPending++; } @@ -3840,7 +3846,7 @@ void LLMeshRepository::notifyLoadedMeshes() for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) { F32 max_score = 0.f; - for (std::set::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) + for (std::vector::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) { LLViewerObject* object = gObjectList.findObject(*obj_iter); @@ -3855,7 +3861,7 @@ void LLMeshRepository::notifyLoadedMeshes() } } - score_map[iter->first.getSculptID()] = max_score; + score_map[iter->first] = max_score; } } @@ -3953,14 +3959,15 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol S32 detail = LLVolumeLODGroup::getVolumeDetailFromScale(volume->getDetail()); //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_params); + const auto& mesh_id = mesh_params.getSculptID(); + mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh_id); if (volume && obj_iter != mLoadingMeshes[detail].end()) { //make sure target volume is still valid if (volume->getNumVolumeFaces() <= 0) { - LL_WARNS(LOG_MESH) << "Mesh loading returned empty volume. ID: " << mesh_params.getSculptID() + LL_WARNS(LOG_MESH) << "Mesh loading returned empty volume. ID: " << mesh_id << LL_ENDL; } @@ -3974,13 +3981,13 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } else { - LL_WARNS(LOG_MESH) << "Couldn't find system volume for mesh " << mesh_params.getSculptID() + LL_WARNS(LOG_MESH) << "Couldn't find system volume for mesh " << mesh_id << LL_ENDL; } } //notify waiting LLVOVolume instances that their requested mesh is available - for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + for (std::vector::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) { LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) @@ -3989,20 +3996,20 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } } - mLoadingMeshes[detail].erase(mesh_params); + mLoadingMeshes[detail].erase(obj_iter); } } void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod) { //called from main thread //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_params); - - F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); - + const auto& mesh_id = mesh_params.getSculptID(); + mesh_load_map::iterator obj_iter = mLoadingMeshes[lod].find(mesh_id); if (obj_iter != mLoadingMeshes[lod].end()) { - for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); + + for (std::vector::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) { LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) @@ -4018,7 +4025,7 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, } } - mLoadingMeshes[lod].erase(mesh_params); + mLoadingMeshes[lod].erase(obj_iter); } } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 6f43b0aa83..2cade8f01e 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -308,7 +308,7 @@ public: std::queue mLoadedQ; //map of pending header requests and currently desired LODs - typedef std::map > pending_lod_map; + typedef boost::unordered_map > pending_lod_map; pending_lod_map mPendingLOD; // llcorehttp library interface objects. @@ -611,7 +611,7 @@ public: static void metricsProgress(unsigned int count); static void metricsUpdate(); - typedef std::map > mesh_load_map; + typedef boost::unordered_map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; typedef std::unordered_map skin_map; -- cgit v1.2.3 From e83146ce0c4310c7a0c03a10b562e7317df034f6 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 16:26:18 -0400 Subject: Optimize away constant map finds in getSkinInfo by caching mesh skin into in vovolume --- indra/llprimitive/llmodel.cpp | 10 ++++++ indra/llprimitive/llmodel.h | 3 +- indra/newview/llmeshrepository.cpp | 71 +++++++++++++++++++++++++++++++------- indra/newview/llmeshrepository.h | 9 +++-- indra/newview/llvovolume.cpp | 36 ++++++++++++++++++- indra/newview/llvovolume.h | 4 +++ 6 files changed, 116 insertions(+), 17 deletions(-) diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 555164f3b0..444d9a5366 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -1389,6 +1389,16 @@ LLMeshSkinInfo::LLMeshSkinInfo(LLSD& skin): fromLLSD(skin); } +LLMeshSkinInfo::LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& skin) : + mMeshID(mesh_id), + mPelvisOffset(0.0), + mLockScaleIfJointPosition(false), + mInvalidJointsScrubbed(false), + mJointNumsInitialized(false) +{ + fromLLSD(skin); +} + void LLMeshSkinInfo::fromLLSD(LLSD& skin) { if (skin.has("joint_names")) diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index a6ab96ab18..9c99bb75a0 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -41,12 +41,13 @@ class domMesh; #define MAX_MODEL_FACES 8 LL_ALIGN_PREFIX(16) -class LLMeshSkinInfo +class LLMeshSkinInfo : public LLRefCount { LL_ALIGN_NEW public: LLMeshSkinInfo(); LLMeshSkinInfo(LLSD& data); + LLMeshSkinInfo(const LLUUID& mesh_id, LLSD& data); void fromLLSD(LLSD& data); LLSD asLLSD(bool include_joints, bool lock_scale_if_joint_position) const; void updateHash(); diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index d5b14dc6aa..ced64b655e 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1972,8 +1972,16 @@ bool LLMeshRepoThread::skinInfoReceived(const LLUUID& mesh_id, U8* data, S32 dat } { - LLMeshSkinInfo info(skin); - info.mMeshID = mesh_id; + LLMeshSkinInfo* info = nullptr; + try + { + info = new LLMeshSkinInfo(mesh_id, skin); + } + catch (const std::bad_alloc& ex) + { + LL_WARNS() << "Failed to allocate skin info with exception: " << ex.what() << LL_ENDL; + return false; + } // LL_DEBUGS(LOG_MESH) << "info pelvis offset" << info.mPelvisOffset << LL_ENDL; { @@ -2898,7 +2906,7 @@ void LLMeshRepoThread::notifyLoadedMeshes() { if (mMutex->trylock()) { - std::list skin_info_q; + std::list skin_info_q; std::list decomp_q; if (! mSkinInfoQ.empty()) @@ -3491,7 +3499,7 @@ LLMeshRepository::LLMeshRepository() mMeshThreadCount(0), mThread(NULL) { - + mSkinInfoCullTimer.resetWithExpiry(10.f); } void LLMeshRepository::init() @@ -3776,6 +3784,28 @@ void LLMeshRepository::notifyLoadedMeshes() //call completed callbacks on finished decompositions mDecompThread->notifyCompleted(); + if (mSkinInfoCullTimer.checkExpirationAndReset(10.f)) + { + //// Clean up dead skin info + //U64Bytes skinbytes(0); + for (auto iter = mSkinMap.begin(), ender = mSkinMap.end(); iter != ender;) + { + auto copy_iter = iter++; + + //skinbytes += U64Bytes(sizeof(LLMeshSkinInfo)); + //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(std::string)); + //skinbytes += U64Bytes(copy_iter->second->mJointNums.size() * sizeof(S32)); + //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(LLMatrix4a)); + //skinbytes += U64Bytes(copy_iter->second->mJointNames.size() * sizeof(LLMatrix4)); + + if (copy_iter->second->getNumRefs() == 1) + { + mSkinMap.erase(copy_iter); + } + } + //LL_INFOS() << "Skin info cache elements:" << mSkinMap.size() << " Memory: " << U64Kilobytes(skinbytes) << LL_ENDL; + } + // For major operations, attempt to get the required locks // without blocking and punt if they're not available. The // longest run of holdoffs is kept in sMaxLockHoldoffs just @@ -3913,13 +3943,13 @@ void LLMeshRepository::notifyLoadedMeshes() mThread->mSignal->signal(); } -void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info) +void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info) { - mSkinMap[info.mMeshID] = info; + mSkinMap[info->mMeshID] = info; // Cache into LLPointer // Alternative: We can get skin size from header - sCacheBytesSkins += info.sizeBytes(); + sCacheBytesSkins += info->sizeBytes(); - skin_load_map::iterator iter = mLoadingSkins.find(info.mMeshID); + skin_load_map::iterator iter = mLoadingSkins.find(info->mMeshID); if (iter != mLoadingSkins.end()) { for (std::set::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) @@ -3927,10 +3957,27 @@ void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo& info) LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); if (vobj) { - vobj->notifyMeshLoaded(); + vobj->notifySkinInfoLoaded(info); + } + } + mLoadingSkins.erase(iter); + } +} + +void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id) +{ + skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); + if (iter != mLoadingSkins.end()) + { + for (std::set::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) + { + LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); + if (vobj) + { + vobj->notifySkinInfoUnavailable(); } } - mLoadingSkins.erase(info.mMeshID); + mLoadingSkins.erase(iter); } } @@ -4042,7 +4089,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const skin_map::iterator iter = mSkinMap.find(mesh_id); if (iter != mSkinMap.end()) { - return &(iter->second); + return iter->second; } //no skin info known about given mesh, try to fetch it @@ -4058,7 +4105,7 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const mLoadingSkins[mesh_id].insert(requesting_obj->getID()); } } - return NULL; + return nullptr; } void LLMeshRepository::fetchPhysicsShape(const LLUUID& mesh_id) diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 2cade8f01e..a5b985ee76 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -284,7 +284,7 @@ public: std::set mSkinRequests; // list of completed skin info requests - std::list mSkinInfoQ; + std::list mSkinInfoQ; //set of requested decompositions std::set mDecompositionRequests; @@ -581,7 +581,8 @@ public: void notifyLoadedMeshes(); void notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVolume* volume); void notifyMeshUnavailable(const LLVolumeParams& mesh_params, S32 lod); - void notifySkinInfoReceived(LLMeshSkinInfo& info); + void notifySkinInfoReceived(LLMeshSkinInfo* info); + void notifySkinInfoUnavailable(const LLUUID& info); void notifyDecompositionReceived(LLModel::Decomposition* info); S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); @@ -614,7 +615,7 @@ public: typedef boost::unordered_map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; - typedef std::unordered_map skin_map; + typedef std::unordered_map> skin_map; skin_map mSkinMap; typedef std::map decomposition_map; @@ -650,6 +651,8 @@ public: std::vector mUploadWaitList; LLPhysicsDecomp* mDecompThread; + + LLFrameTimer mSkinInfoCullTimer; class inventory_data { diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index f4a938e57d..d5583f05f3 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -228,6 +228,9 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mColorChanged = FALSE; mSpotLightPriority = 0.f; + mSkinInfoFailed = false; + mSkinInfo = NULL; + mMediaImplList.resize(getNumTEs()); mLastFetchedMediaVersion = -1; mServerDrawableUpdateCount = 0; @@ -1095,6 +1098,12 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo // if it's a mesh if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH) { + if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID()) + { + mSkinInfo = NULL; + mSkinInfoFailed = false; + } + if (!getVolume()->isMeshAssetLoaded()) { //load request not yet issued, request pipeline load this mesh @@ -1106,6 +1115,14 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } + if (!mSkinInfo && !mSkinInfoFailed) + { + const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this); + if (skin_info) + { + notifySkinInfoLoaded(skin_info); + } + } } else // otherwise is sculptie { @@ -1158,6 +1175,9 @@ void LLVOVolume::updateSculptTexture() { mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); } + + mSkinInfoFailed = false; + mSkinInfo = NULL; } else { @@ -1212,6 +1232,20 @@ void LLVOVolume::notifyMeshLoaded() updateVisualComplexity(); } +void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin) +{ + mSkinInfoFailed = false; + mSkinInfo = skin; + + notifyMeshLoaded(); +} + +void LLVOVolume::notifySkinInfoUnavailable() +{ + mSkinInfoFailed = true; + mSkinInfo = nullptr; +} + // sculpt replaces generate() for sculpted surfaces void LLVOVolume::sculpt() { @@ -3645,7 +3679,7 @@ const LLMeshSkinInfo* LLVOVolume::getSkinInfo() const { if (getVolume()) { - return gMeshRepo.getSkinInfo(getMeshID(), this); + return mSkinInfo; } else { diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 4136c13315..12681e2bd9 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -350,6 +350,8 @@ public: void updateVisualComplexity(); void notifyMeshLoaded(); + void notifySkinInfoLoaded(const LLMeshSkinInfo* skin); + void notifySkinInfoUnavailable(); // Returns 'true' iff the media data for this object is in flight bool isMediaDataBeingFetched() const; @@ -433,6 +435,8 @@ private: LLPointer mRiggedVolume; + bool mSkinInfoFailed; + LLConstPointer mSkinInfo; // statics public: static F32 sLODSlopDistanceFactor;// Changing this to zero, effectively disables the LOD transition slop -- cgit v1.2.3 From bd20b61b8261623d75bbb22e7d368743d7bd971a Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 17:14:19 -0400 Subject: Optimize away gObjectList finds during mesh load --- indra/newview/llmeshrepository.cpp | 55 +++++++++++++++++++++++++------------- indra/newview/llmeshrepository.h | 7 ++--- indra/newview/llvovolume.cpp | 2 ++ 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index ced64b655e..ed942eca31 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -3600,6 +3600,22 @@ S32 LLMeshRepository::update() return size ; } +void LLMeshRepository::unregisterMesh(LLVOVolume* vobj) +{ + for (auto& lod : mLoadingMeshes) + { + for (auto& param : lod) + { + vector_replace_with_last(param.second, vobj); + } + } + + for (auto& skin_pair : mLoadingSkins) + { + vector_replace_with_last(skin_pair.second, vobj); + } +} + S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_params, S32 detail, S32 last_lod) { LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH); @@ -3619,15 +3635,15 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id); if (iter != mLoadingMeshes[detail].end()) { //request pending for this mesh, append volume id to list - auto it = std::find(iter->second.begin(), iter->second.end(), vobj->getID()); + auto it = std::find(iter->second.begin(), iter->second.end(), vobj); if (it == iter->second.end()) { - iter->second.push_back(vobj->getID()); + iter->second.push_back(vobj); } } else { //first request for this mesh - mLoadingMeshes[detail][mesh_id].push_back(vobj->getID()); + mLoadingMeshes[detail][mesh_id].push_back(vobj); mPendingRequests.push_back(LLMeshRepoThread::LODRequest(mesh_params, detail)); LLMeshRepository::sLODPending++; } @@ -3876,10 +3892,9 @@ void LLMeshRepository::notifyLoadedMeshes() for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter) { F32 max_score = 0.f; - for (std::vector::iterator obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) + for (auto obj_iter = iter->second.begin(); obj_iter != iter->second.end(); ++obj_iter) { - LLViewerObject* object = gObjectList.findObject(*obj_iter); - + LLVOVolume* object = *obj_iter; if (object) { LLDrawable* drawable = object->mDrawable; @@ -3952,9 +3967,8 @@ void LLMeshRepository::notifySkinInfoReceived(LLMeshSkinInfo* info) skin_load_map::iterator iter = mLoadingSkins.find(info->mMeshID); if (iter != mLoadingSkins.end()) { - for (std::set::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) + for (LLVOVolume* vobj : iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); if (vobj) { vobj->notifySkinInfoLoaded(info); @@ -3969,9 +3983,8 @@ void LLMeshRepository::notifySkinInfoUnavailable(const LLUUID& mesh_id) skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); if (iter != mLoadingSkins.end()) { - for (std::set::iterator obj_id = iter->second.begin(); obj_id != iter->second.end(); ++obj_id) + for (LLVOVolume* vobj : iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*obj_id); if (vobj) { vobj->notifySkinInfoUnavailable(); @@ -4034,9 +4047,8 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol } //notify waiting LLVOVolume instances that their requested mesh is available - for (std::vector::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + for (LLVOVolume* vobj : obj_iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) { vobj->notifyMeshLoaded(); @@ -4056,9 +4068,8 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params, { F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod); - for (std::vector::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + for (LLVOVolume* vobj : obj_iter->second) { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); if (vobj) { LLVolume* obj_volume = vobj->getVolume(); @@ -4081,7 +4092,7 @@ S32 LLMeshRepository::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo return mThread->getActualMeshLOD(mesh_params, lod); } -const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj) +const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj) { LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR; if (mesh_id.notNull()) @@ -4098,11 +4109,19 @@ const LLMeshSkinInfo* LLMeshRepository::getSkinInfo(const LLUUID& mesh_id, const LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes skin_load_map::iterator iter = mLoadingSkins.find(mesh_id); - if (iter == mLoadingSkins.end()) - { //no request pending for this skin info + if (iter != mLoadingSkins.end()) + { //request pending for this mesh, append volume id to list + auto it = std::find(iter->second.begin(), iter->second.end(), requesting_obj); + if (it == iter->second.end()) { + iter->second.push_back(requesting_obj); + } + } + else + { + //first request for this mesh + mLoadingSkins[mesh_id].push_back(requesting_obj); mPendingSkinRequests.push(mesh_id); } - mLoadingSkins[mesh_id].insert(requesting_obj->getID()); } } return nullptr; diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index a5b985ee76..01a8427757 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -575,6 +575,7 @@ public: void shutdown(); S32 update(); + void unregisterMesh(LLVOVolume* volume); //mesh management functions S32 loadMesh(LLVOVolume* volume, const LLVolumeParams& mesh_params, S32 detail = 0, S32 last_lod = -1); @@ -587,7 +588,7 @@ public: S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod); static S32 getActualMeshLOD(LLSD& header, S32 lod); - const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, const LLVOVolume* requesting_obj = nullptr); + const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr); LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id); void fetchPhysicsShape(const LLUUID& mesh_id); bool hasPhysicsShape(const LLUUID& mesh_id); @@ -612,7 +613,7 @@ public: static void metricsProgress(unsigned int count); static void metricsUpdate(); - typedef boost::unordered_map > mesh_load_map; + typedef boost::unordered_map > mesh_load_map; mesh_load_map mLoadingMeshes[4]; typedef std::unordered_map> skin_map; @@ -626,7 +627,7 @@ public: std::vector mPendingRequests; //list of mesh ids awaiting skin info - typedef std::map > skin_load_map; + typedef boost::unordered_map > skin_load_map; skin_load_map mLoadingSkins; //list of mesh ids that need to send skin info fetch requests diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d5583f05f3..8cfa83ba46 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -247,6 +247,8 @@ LLVOVolume::~LLVOVolume() delete mVolumeImpl; mVolumeImpl = NULL; + gMeshRepo.unregisterMesh(this); + if(!mMediaImplList.empty()) { for(U32 i = 0 ; i < mMediaImplList.size() ; i++) -- cgit v1.2.3 From 9ec86c84e3d75feb5505a98e96db542b054e162e Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 17:35:23 -0400 Subject: Add proper retry support to skin info fetch --- indra/newview/llmeshrepository.cpp | 115 +++++++++++++++++++++++++------------ indra/newview/llmeshrepository.h | 9 ++- 2 files changed, 83 insertions(+), 41 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index ed942eca31..53ce952739 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -857,6 +857,12 @@ LLMeshRepoThread::~LLMeshRepoThread() mHttpRequestSet.clear(); mHttpHeaders.reset(); + while (!mSkinInfoQ.empty()) + { + delete mSkinInfoQ.front(); + mSkinInfoQ.pop_front(); + } + while (!mDecompositionQ.empty()) { delete mDecompositionQ.front(); @@ -946,6 +952,7 @@ void LLMeshRepoThread::run() else { // too many fails + LLMutexLock lock(mMutex); mUnavailableQ.push(req); LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL; } @@ -1022,37 +1029,42 @@ void LLMeshRepoThread::run() if (!mSkinRequests.empty()) { - std::set incomplete; - while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) - { - mMutex->lock(); - std::set::iterator iter = mSkinRequests.begin(); - UUIDBasedRequest req = *iter; - mSkinRequests.erase(iter); - mMutex->unlock(); - if (req.isDelayed()) - { - incomplete.insert(req); - } - else if (!fetchMeshSkinInfo(req.mId)) - { - if (req.canRetry()) - { - req.updateTime(); - incomplete.insert(req); - } - else - { - LL_DEBUGS() << "mSkinRequests failed: " << req.mId << LL_ENDL; - } - } - } + std::list incomplete; + while (!mSkinRequests.empty() && mHttpRequestSet.size() < sRequestHighWater) + { - if (!incomplete.empty()) - { - LLMutexLock locker(mMutex); - mSkinRequests.insert(incomplete.begin(), incomplete.end()); - } + mMutex->lock(); + auto req = mSkinRequests.front(); + mSkinRequests.pop_front(); + mMutex->unlock(); + if (req.isDelayed()) + { + incomplete.emplace_back(req); + } + else if (!fetchMeshSkinInfo(req.mId, req.canRetry())) + { + if (req.canRetry()) + { + req.updateTime(); + incomplete.emplace_back(req); + } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.push_back(req); + LL_DEBUGS() << "mSkinReqQ failed: " << req.mId << LL_ENDL; + } + } + } + + if (!incomplete.empty()) + { + LLMutexLock locker(mMutex); + for (const auto& req : incomplete) + { + mSkinRequests.push_back(req); + } + } } // holding lock, try next list @@ -1151,7 +1163,7 @@ void LLMeshRepoThread::run() // Mutex: LLMeshRepoThread::mMutex must be held on entry void LLMeshRepoThread::loadMeshSkinInfo(const LLUUID& mesh_id) { - mSkinRequests.insert(UUIDBasedRequest(mesh_id)); + mSkinRequests.push_back(UUIDBasedRequest(mesh_id)); } // Mutex: LLMeshRepoThread::mMutex must be held on entry @@ -1308,7 +1320,7 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, } -bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) +bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry) { if (!mHeaderMutex) @@ -1390,13 +1402,28 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id) << LL_ENDL; ret = false; } - else + else if(can_retry) { handler->mHttpHandle = handle; mHttpRequestSet.insert(handler); } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.emplace_back(mesh_id); + } + } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.emplace_back(mesh_id); } } + else + { + LLMutexLock locker(mMutex); + mSkinUnavailableQ.emplace_back(mesh_id); + } } else { @@ -2906,13 +2933,20 @@ void LLMeshRepoThread::notifyLoadedMeshes() { if (mMutex->trylock()) { - std::list skin_info_q; + std::deque skin_info_q; + std::deque skin_info_unavail_q; std::list decomp_q; if (! mSkinInfoQ.empty()) { skin_info_q.swap(mSkinInfoQ); } + + if (! mSkinUnavailableQ.empty()) + { + skin_info_unavail_q.swap(mSkinUnavailableQ); + } + if (! mDecompositionQ.empty()) { decomp_q.swap(mDecompositionQ); @@ -2926,6 +2960,11 @@ void LLMeshRepoThread::notifyLoadedMeshes() gMeshRepo.notifySkinInfoReceived(skin_info_q.front()); skin_info_q.pop_front(); } + while (! skin_info_unavail_q.empty()) + { + gMeshRepo.notifySkinInfoUnavailable(skin_info_unavail_q.front().mId); + skin_info_unavail_q.pop_front(); + } while (! decomp_q.empty()) { @@ -3357,9 +3396,8 @@ void LLMeshSkinInfoHandler::processFailure(LLCore::HttpStatus status) << ", Reason: " << status.toString() << " (" << status.toTerseString() << "). Not retrying." << LL_ENDL; - - // *TODO: Mark mesh unavailable on error. For now, simply leave - // request unfulfilled rather than retry forever. + LLMutexLock lock(gMeshRepo.mThread->mMutex); + gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID); } void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, @@ -3390,7 +3428,8 @@ void LLMeshSkinInfoHandler::processData(LLCore::BufferArray * /* body */, S32 /* LL_WARNS(LOG_MESH) << "Error during mesh skin info processing. ID: " << mMeshID << ", Unknown reason. Not retrying." << LL_ENDL; - // *TODO: Mark mesh unavailable on error + LLMutexLock lock(gMeshRepo.mThread->mMutex); + gMeshRepo.mThread->mSkinUnavailableQ.emplace_back(mMeshID); } } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 01a8427757..f62216d8ba 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -281,10 +281,13 @@ public: }; //set of requested skin info - std::set mSkinRequests; + std::deque mSkinRequests; // list of completed skin info requests - std::list mSkinInfoQ; + std::deque mSkinInfoQ; + + // list of skin info requests that have failed or are unavailaibe + std::deque mSkinUnavailableQ; //set of requested decompositions std::set mDecompositionRequests; @@ -352,7 +355,7 @@ public: //send request for skin info, returns true if header info exists // (should hold onto mesh_id and try again later if header info does not exist) - bool fetchMeshSkinInfo(const LLUUID& mesh_id); + bool fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry = true); //send request for decomposition, returns true if header info exists // (should hold onto mesh_id and try again later if header info does not exist) -- cgit v1.2.3 From 07449892df0cfcfa22583d7d7c7b29098e3af499 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 17:54:30 -0400 Subject: Optimize mesh queue processing on main thread to reduce mutex contention --- indra/newview/llmeshrepository.cpp | 83 +++++++++++++++++++++----------------- indra/newview/llmeshrepository.h | 4 +- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 53ce952739..8c85b30e04 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -953,7 +953,7 @@ void LLMeshRepoThread::run() { // too many fails LLMutexLock lock(mMutex); - mUnavailableQ.push(req); + mUnavailableQ.push_back(req); LL_WARNS() << "Failed to load " << req.mMeshParams << " , skip" << LL_ENDL; } } @@ -1832,19 +1832,19 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod, else { LLMutexLock lock(mMutex); - mUnavailableQ.push(LODRequest(mesh_params, lod)); + mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else { LLMutexLock lock(mMutex); - mUnavailableQ.push(LODRequest(mesh_params, lod)); + mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else { LLMutexLock lock(mMutex); - mUnavailableQ.push(LODRequest(mesh_params, lod)); + mUnavailableQ.push_back(LODRequest(mesh_params, lod)); } } else @@ -1959,7 +1959,7 @@ EMeshProcessingResult LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_p LoadedMesh mesh(volume, mesh_params, lod); { LLMutexLock lock(mMutex); - mLoadedQ.push(mesh); + mLoadedQ.push_back(mesh); // LLPointer is not thread safe, since we added this pointer into // threaded list, make sure counter gets decreased inside mutex lock // and won't affect mLoadedQ processing @@ -2888,45 +2888,52 @@ void LLMeshRepoThread::notifyLoadedMeshes() return; } - while (!mLoadedQ.empty()) + if (!mLoadedQ.empty()) { + std::deque loaded_queue; + mMutex->lock(); - if (mLoadedQ.empty()) + if (!mLoadedQ.empty()) { + loaded_queue.swap(mLoadedQ); mMutex->unlock(); - break; - } - LoadedMesh mesh = mLoadedQ.front(); // make sure nothing else owns volume pointer by this point - mLoadedQ.pop(); - mMutex->unlock(); - - update_metrics = true; - if (mesh.mVolume->getNumVolumeFaces() > 0) - { - gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume); - } - else - { - gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams, - LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail())); + + update_metrics = true; + + // Process the elements free of the lock + for (const auto& mesh : loaded_queue) + { + if (mesh.mVolume->getNumVolumeFaces() > 0) + { + gMeshRepo.notifyMeshLoaded(mesh.mMeshParams, mesh.mVolume); + } + else + { + gMeshRepo.notifyMeshUnavailable(mesh.mMeshParams, + LLVolumeLODGroup::getVolumeDetailFromScale(mesh.mVolume->getDetail())); + } + } } } - while (!mUnavailableQ.empty()) + if (!mUnavailableQ.empty()) { + std::deque unavil_queue; + mMutex->lock(); - if (mUnavailableQ.empty()) + if (!mUnavailableQ.empty()) { + unavil_queue.swap(mUnavailableQ); mMutex->unlock(); - break; - } - - LODRequest req = mUnavailableQ.front(); - mUnavailableQ.pop(); - mMutex->unlock(); - update_metrics = true; - gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD); + update_metrics = true; + + // Process the elements free of the lock + for (const auto& req : unavil_queue) + { + gMeshRepo.notifyMeshUnavailable(req.mMeshParams, req.mLOD); + } + } } if (! mSkinInfoQ.empty() || ! mDecompositionQ.empty()) @@ -3192,7 +3199,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status) LLMutexLock lock(gMeshRepo.mThread->mMutex); for (int i(0); i < 4; ++i) { - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } } @@ -3221,7 +3228,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMutexLock lock(gMeshRepo.mThread->mMutex); for (int i(0); i < 4; ++i) { - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } } else if (data && data_size > 0) @@ -3303,7 +3310,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b LLMutexLock lock(gMeshRepo.mThread->mMutex); for (int i(0); i < 4; ++i) { - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i)); } } } @@ -3330,7 +3337,7 @@ void LLMeshLODHandler::processFailure(LLCore::HttpStatus status) << LL_ENDL; LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body_offset */, @@ -3367,7 +3374,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body << " Not retrying." << LL_ENDL; LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } } else @@ -3378,7 +3385,7 @@ void LLMeshLODHandler::processData(LLCore::BufferArray * /* body */, S32 /* body << " Data size: " << data_size << LL_ENDL; LLMutexLock lock(gMeshRepo.mThread->mMutex); - gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); + gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, mLOD)); } } diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index f62216d8ba..e3688ff243 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -305,10 +305,10 @@ public: std::queue mLODReqQ; //queue of unavailable LODs (either asset doesn't exist or asset doesn't have desired LOD) - std::queue mUnavailableQ; + std::deque mUnavailableQ; //queue of successfully loaded meshes - std::queue mLoadedQ; + std::deque mLoadedQ; //map of pending header requests and currently desired LODs typedef boost::unordered_map > pending_lod_map; -- cgit v1.2.3 From 9f633e087fa0855ee8358e3e84924872ec5d965f Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 27 Sep 2022 17:58:01 -0400 Subject: Optimize away many string copies in mesh header processing with boost iostream array adapters --- indra/newview/llmeshrepository.cpp | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 8c85b30e04..3ed7e9289d 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -77,6 +77,8 @@ #include "lluploaddialog.h" #include "llfloaterreg.h" +#include "boost/iostreams/device/array.hpp" +#include "boost/iostreams/stream.hpp" #include "boost/lexical_cast.hpp" #ifndef LL_WINDOWS @@ -1863,27 +1865,12 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes U32 header_size = 0; if (data_size > 0) { - std::istringstream stream; - try - { - std::string res_str((char*)data, data_size); - - std::string deprecated_header(""); + U32 dsize = data_size; + char* result_ptr = strip_deprecated_header((char*)data, dsize, &header_size); - if (res_str.substr(0, deprecated_header.size()) == deprecated_header) - { - res_str = res_str.substr(deprecated_header.size() + 1, data_size); - header_size = deprecated_header.size() + 1; - } - data_size = res_str.size(); + data_size = dsize; - stream.str(res_str); - } - catch (std::bad_alloc&) - { - // out of memory, we won't be able to process this mesh - return MESH_OUT_OF_MEMORY; - } + boost::iostreams::stream stream(result_ptr, data_size); if (!LLSDSerialize::fromBinary(header, stream, data_size)) { -- cgit v1.2.3 From d1701fb5b1a1cef281b04a8004f133ff7efa7db3 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Wed, 28 Sep 2022 09:55:57 -0400 Subject: Fix small bug in unavail skin info processing --- indra/newview/llmeshrepository.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 3ed7e9289d..f937754368 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2923,7 +2923,7 @@ void LLMeshRepoThread::notifyLoadedMeshes() } } - if (! mSkinInfoQ.empty() || ! mDecompositionQ.empty()) + if (!mSkinInfoQ.empty() || !mSkinUnavailableQ.empty() || ! mDecompositionQ.empty()) { if (mMutex->trylock()) { -- cgit v1.2.3 From 6614a6ee9987ac2b199aaabe7d9cd520c613c13f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 28 Sep 2022 18:42:10 +0300 Subject: SL-18249 Optimizations to mesh and material loading --- doc/contributions.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/contributions.txt b/doc/contributions.txt index 2c1e5487ce..d74ec13637 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -1384,6 +1384,7 @@ Sovereign Engineer SL-14732 SL-15096 SL-16127 + SL-18249 SpacedOut Frye VWR-34 VWR-45 -- cgit v1.2.3 From 9104b899961a9ceb61de73528e85f1a240f30cb5 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 30 Sep 2022 00:26:44 +0300 Subject: SL-18235 Remove outfit buttons from unpacking dialog --- indra/newview/llfloateropenobject.cpp | 14 ------ indra/newview/llfloateropenobject.h | 2 - indra/newview/llpanelobjectinventory.cpp | 21 ++++++--- indra/newview/llpanelobjectinventory.h | 11 ++++- .../skins/default/xui/en/floater_openobject.xml | 52 ++-------------------- 5 files changed, 28 insertions(+), 72 deletions(-) diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp index 2a1749bd42..a682064dad 100644 --- a/indra/newview/llfloateropenobject.cpp +++ b/indra/newview/llfloateropenobject.cpp @@ -56,8 +56,6 @@ LLFloaterOpenObject::LLFloaterOpenObject(const LLSD& key) mDirty(TRUE) { mCommitCallbackRegistrar.add("OpenObject.MoveToInventory", boost::bind(&LLFloaterOpenObject::onClickMoveToInventory, this)); - mCommitCallbackRegistrar.add("OpenObject.MoveAndWear", boost::bind(&LLFloaterOpenObject::onClickMoveAndWear, this)); - mCommitCallbackRegistrar.add("OpenObject.ReplaceOutfit", boost::bind(&LLFloaterOpenObject::onClickReplace, this)); mCommitCallbackRegistrar.add("OpenObject.Cancel", boost::bind(&LLFloaterOpenObject::onClickCancel, this)); } @@ -243,18 +241,6 @@ void LLFloaterOpenObject::onClickMoveToInventory() closeFloater(); } -void LLFloaterOpenObject::onClickMoveAndWear() -{ - moveToInventory(true, false); - closeFloater(); -} - -void LLFloaterOpenObject::onClickReplace() -{ - moveToInventory(true, true); - closeFloater(); -} - void LLFloaterOpenObject::onClickCancel() { closeFloater(); diff --git a/indra/newview/llfloateropenobject.h b/indra/newview/llfloateropenobject.h index 2e761f99bf..745753316b 100644 --- a/indra/newview/llfloateropenobject.h +++ b/indra/newview/llfloateropenobject.h @@ -63,8 +63,6 @@ protected: void moveToInventory(bool wear, bool replace = false); void onClickMoveToInventory(); - void onClickMoveAndWear(); - void onClickReplace(); void onClickCancel(); static void callbackCreateInventoryCategory(const LLUUID& category_id, LLUUID object_id, bool wear, bool replace = false); static void callbackMoveInventory(S32 result, void* data); diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index cfaa9456be..5ac5f0d429 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1275,7 +1275,8 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par mHaveInventory(FALSE), mIsInventoryEmpty(TRUE), mInventoryNeedsUpdate(FALSE), - mInventoryViewModel(p.name) + mInventoryViewModel(p.name), + mShowRootFolder(p.show_root_folder) { // Setup context menu callbacks mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLPanelObjectInventory::doToSelected, this, _2)); @@ -1526,15 +1527,23 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root p.font_highlight_color = item_color; LLFolderViewFolder* new_folder = LLUICtrlFactory::create(p); - new_folder->addToFolder(mFolders); - new_folder->toggleOpen(); + + if (mShowRootFolder) + { + new_folder->addToFolder(mFolders); + new_folder->toggleOpen(); + } if (!contents.empty()) { - createViewsForCategory(&contents, inventory_root, new_folder); + createViewsForCategory(&contents, inventory_root, mShowRootFolder ? new_folder : mFolders); } - // Refresh for label to add item count - new_folder->refresh(); + + if (mShowRootFolder) + { + // Refresh for label to add item count + new_folder->refresh(); + } } } diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h index 7b9ecfb8f3..0e450d8ce9 100644 --- a/indra/newview/llpanelobjectinventory.h +++ b/indra/newview/llpanelobjectinventory.h @@ -48,8 +48,14 @@ class LLViewerObject; class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener { public: - // dummy param block for template registration purposes - struct Params : public LLPanel::Params {}; + struct Params : public LLInitParam::Block + { + Optional show_root_folder; + + Params() + : show_root_folder("show_root_folder", true) + {} + }; LLPanelObjectInventory(const Params&); virtual ~LLPanelObjectInventory(); @@ -110,6 +116,7 @@ private: BOOL mIsInventoryEmpty; // 'Empty' label BOOL mInventoryNeedsUpdate; // for idle, set on changed callback LLFolderViewModelInventory mInventoryViewModel; + bool mShowRootFolder; }; #endif // LL_LLPANELOBJECTINVENTORY_H diff --git a/indra/newview/skins/default/xui/en/floater_openobject.xml b/indra/newview/skins/default/xui/en/floater_openobject.xml index 912db80bcc..ec03d7d32c 100644 --- a/indra/newview/skins/default/xui/en/floater_openobject.xml +++ b/indra/newview/skins/default/xui/en/floater_openobject.xml @@ -3,7 +3,7 @@ legacy_header_height="18" can_resize="true" default_tab_group="1" - height="370" + height="350" layout="topleft" min_height="190" min_width="285" @@ -31,62 +31,18 @@ background_visible="false" draw_border="false" follows="all" - height="240" + height="265" layout="topleft" + show_root_folder="false" left="10" name="object_contents" top_pad="0" width="284" /> - - - Copy to inventory and wear - - - + + -- cgit v1.2.3 From 228f5b2f120cf7e5691dcb174a2d4f34c5340ef4 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Tue, 25 Oct 2022 09:48:51 -0400 Subject: Restore LLUUID to a plain old data type in a post-c++11 world --- indra/llcommon/lluuid.cpp | 30 ------------------------------ indra/llcommon/lluuid.h | 8 ++++---- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index acce8366ea..6f9e09a587 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -1009,36 +1009,6 @@ LLUUID::LLUUID() return !(word[0] | word[1] | word[2] | word[3]); } -// Copy constructor - LLUUID::LLUUID(const LLUUID& rhs) -{ - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - tmp[0] = rhstmp[0]; - tmp[1] = rhstmp[1]; - tmp[2] = rhstmp[2]; - tmp[3] = rhstmp[3]; -} - - LLUUID::~LLUUID() -{ -} - -// Assignment - LLUUID& LLUUID::operator=(const LLUUID& rhs) -{ - // No need to check the case where this==&rhs. The branch is slower than the write. - U32 *tmp = (U32 *)mData; - U32 *rhstmp = (U32 *)rhs.mData; - tmp[0] = rhstmp[0]; - tmp[1] = rhstmp[1]; - tmp[2] = rhstmp[2]; - tmp[3] = rhstmp[3]; - - return *this; -} - - LLUUID::LLUUID(const char *in_string) { if (!in_string || in_string[0] == 0) diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h index 86a396ab06..c139c4eb4e 100644 --- a/indra/llcommon/lluuid.h +++ b/indra/llcommon/lluuid.h @@ -55,10 +55,7 @@ public: LLUUID(); explicit LLUUID(const char *in_string); // Convert from string. explicit LLUUID(const std::string& in_string); // Convert from string. - LLUUID(const LLUUID &in); - LLUUID &operator=(const LLUUID &rhs); - - ~LLUUID(); + ~LLUUID() = default; // // MANIPULATORS @@ -131,6 +128,9 @@ public: U8 mData[UUID_BYTES]; }; +static_assert(std::is_trivially_copyable::value, "LLUUID must be trivial copy"); +static_assert(std::is_trivially_move_assignable::value, "LLUUID must be trivial move"); +static_assert(std::is_standard_layout::value, "LLUUID must be a standard layout type"); typedef std::vector uuid_vec_t; typedef std::set uuid_set_t; -- cgit v1.2.3 From 7b3bb0f9c9fd2649365b17fdcd415e366cf57745 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Tue, 25 Oct 2022 17:16:57 +0300 Subject: SL-17991 update tooltip over Clear History button --- indra/newview/skins/default/xui/en/panel_preferences_privacy.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml index 2ec5cef640..ef08fdf7c4 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml @@ -19,7 +19,7 @@ follows="left|top" height="23" label="Clear History" - tool_tip="Clear login image, last location, teleport history, web and texture cache" + tool_tip="Clear search and teleport history, web and texture cache" layout="topleft" left="30" name="clear_cache" -- cgit v1.2.3 From 3ac77d73380ced1a9ff940053f448d2794fcc512 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Tue, 25 Oct 2022 19:49:37 +0300 Subject: SL-18438 Mac build fix --- indra/llmessage/tests/llcoproceduremanager_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llmessage/tests/llcoproceduremanager_test.cpp b/indra/llmessage/tests/llcoproceduremanager_test.cpp index 6424117ef3..a1a4ce0520 100644 --- a/indra/llmessage/tests/llcoproceduremanager_test.cpp +++ b/indra/llmessage/tests/llcoproceduremanager_test.cpp @@ -92,7 +92,7 @@ namespace tut Sync sync; int foo = 0; LLCoprocedureManager::instance().initializePool("PoolName"); - LLUUID queueId = LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", + LLCoprocedureManager::instance().enqueueCoprocedure("PoolName", "ProcName", [&foo, &sync] (LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t & ptr, const LLUUID & id) { sync.bump(); foo = 1; -- cgit v1.2.3 From b2c5973fbd504039e1ef9d8fe6d853857e00fcad Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 27 Oct 2022 02:35:52 +0300 Subject: DRTVWR-570 Mac build fix --- indra/newview/llaccountingcostmanager.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp index e09527a34b..d3f988d715 100644 --- a/indra/newview/llaccountingcostmanager.cpp +++ b/indra/newview/llaccountingcostmanager.cpp @@ -96,11 +96,7 @@ void LLAccountingCostManager::accountingCostCoro(std::string url, LLSD dataToPost = LLSD::emptyMap(); dataToPost[keystr.c_str()] = objectList; - LLAccountingCostObserver* observer = observerHandle.get(); - LLUUID transactionId = observer->getTransactionID(); - observer = NULL; - - + LLAccountingCostObserver* observer = NULL; LLSD results = httpAdapter->postAndSuspend(httpRequest, url, dataToPost); -- cgit v1.2.3 From 91f9f2e9f789d0418107ed5d428e8f0be3a060e2 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Thu, 27 Oct 2022 23:08:09 +0300 Subject: DRTVWR-570 Mac build fix: unused variables cleanup --- indra/newview/llappearancemgr.cpp | 2 +- indra/newview/llenvironment.cpp | 1 - indra/newview/llfloatercreatelandmark.cpp | 1 - indra/newview/llfloateroutfitphotopreview.cpp | 1 - indra/newview/llfloaterscriptlimits.cpp | 1 - indra/newview/llimview.cpp | 6 ++---- indra/newview/llinventoryfilter.cpp | 1 - indra/newview/llinventoryfunctions.cpp | 3 --- indra/newview/llinventorymodel.cpp | 1 - indra/newview/lloutfitgallery.cpp | 2 +- indra/newview/lloutfitslist.cpp | 3 +-- indra/newview/llpanellandmedia.cpp | 1 - indra/newview/llpanelplaces.cpp | 1 - indra/newview/llpanelprofile.cpp | 1 - indra/newview/llspeakers.cpp | 1 - indra/newview/llviewermenu.cpp | 1 - indra/newview/llviewertexteditor.cpp | 1 - indra/newview/llviewerwindow.cpp | 1 - indra/newview/llvovolume.cpp | 6 +----- 19 files changed, 6 insertions(+), 29 deletions(-) diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp index 909f32cd21..3c93a9df7e 100644 --- a/indra/newview/llappearancemgr.cpp +++ b/indra/newview/llappearancemgr.cpp @@ -3987,7 +3987,7 @@ void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, boo // existence of AIS as an indicator the fix is present. Does // not actually use AIS to create the category. inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel); - LLUUID folder_id = gInventory.createNewCategory( + gInventory.createNewCategory( parent_id, LLFolderType::FT_OUTFIT, new_folder_name, diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 1300cf3658..9a23702c38 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -684,7 +684,6 @@ namespace if (!injection->mBlendIn) mix = 1.0 - mix; stringset_t dummy; - LLUUID cloud_noise_id = getCloudNoiseTextureId(); F64 value = this->mSettings[injection->mKeyName].asReal(); if (this->getCloudNoiseTextureId().isNull()) { diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp index 7def855d83..b82d8a29ba 100644 --- a/indra/newview/llfloatercreatelandmark.cpp +++ b/indra/newview/llfloatercreatelandmark.cpp @@ -316,7 +316,6 @@ void LLFloaterCreateLandmark::onSaveClicked() LLStringUtil::trim(current_title_value); LLStringUtil::trim(current_notes_value); - LLUUID item_id = mItem->getUUID(); LLUUID folder_id = mFolderCombo->getValue().asUUID(); bool change_parent = folder_id != mItem->getParentUUID(); diff --git a/indra/newview/llfloateroutfitphotopreview.cpp b/indra/newview/llfloateroutfitphotopreview.cpp index 6c39db730c..ade258aef7 100644 --- a/indra/newview/llfloateroutfitphotopreview.cpp +++ b/indra/newview/llfloateroutfitphotopreview.cpp @@ -234,7 +234,6 @@ void LLFloaterOutfitPhotoPreview::updateImageID() if(item) { mImageID = item->getAssetUUID(); - LLPermissions perm(item->getPermissions()); } else { diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp index 3746b9b6c2..40fe11b309 100644 --- a/indra/newview/llfloaterscriptlimits.cpp +++ b/indra/newview/llfloaterscriptlimits.cpp @@ -421,7 +421,6 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content) for(S32 i = 0; i < number_parcels; i++) { std::string parcel_name = content["parcels"][i]["name"].asString(); - LLUUID parcel_id = content["parcels"][i]["id"].asUUID(); S32 number_objects = content["parcels"][i]["objects"].size(); S32 local_id = 0; diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp index 4d6ebf9cbb..afd68a6a38 100644 --- a/indra/newview/llimview.cpp +++ b/indra/newview/llimview.cpp @@ -2114,8 +2114,6 @@ void LLOutgoingCallDialog::show(const LLSD& key) std::string callee_name = mPayload["session_name"].asString(); - LLUUID session_id = mPayload["session_id"].asUUID(); - if (callee_name == "anonymous") // obsolete? Likely was part of avaline support { callee_name = getString("anonymous"); @@ -2499,7 +2497,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload } } - LLUUID new_session_id = gIMMgr->addSession(correct_session_name, type, session_id, true); + gIMMgr->addSession(correct_session_name, type, session_id, true); std::string url = gAgent.getRegion()->getCapability( "ChatSessionRequest"); @@ -2585,7 +2583,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response) } else { - LLUUID new_session_id = gIMMgr->addSession( + gIMMgr->addSession( payload["session_name"].asString(), type, session_id, true); diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp index 707ff2b7b6..e3a6b2dc85 100644 --- a/indra/newview/llinventoryfilter.cpp +++ b/indra/newview/llinventoryfilter.cpp @@ -437,7 +437,6 @@ bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInvent bool LLInventoryFilter::checkAgainstFilterType(const LLInventoryItem* item) const { LLInventoryType::EType object_type = item->getInventoryType(); - const LLUUID object_id = item->getUUID(); const U32 filterTypes = mFilterOps.mFilterTypes; diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp index 27edc8148e..2c8d372eff 100644 --- a/indra/newview/llinventoryfunctions.cpp +++ b/indra/newview/llinventoryfunctions.cpp @@ -1403,9 +1403,6 @@ bool move_item_to_marketplacelistings(LLInventoryItem* inv_item, LLUUID dest_fol LLNotificationsUtil::add("MerchantPasteFailed", subs); return false; } - - // Get the parent folder of the moved item : we may have to update it - LLUUID src_folder = viewer_inv_item->getParentUUID(); if (copy) { diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp index 06351dc540..87fd91b23a 100644 --- a/indra/newview/llinventorymodel.cpp +++ b/indra/newview/llinventorymodel.cpp @@ -2711,7 +2711,6 @@ void LLInventoryModel::buildParentChildMap() // some accounts has pbroken inventory root folders std::string name = "My Inventory"; - LLUUID prev_root_id = mRootFolderID; for (parent_cat_map_t::const_iterator it = mParentChildCategoryTree.begin(), it_end = mParentChildCategoryTree.end(); it != it_end; ++it) { diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp index f419e2e06d..5d139ff75f 100644 --- a/indra/newview/lloutfitgallery.cpp +++ b/indra/newview/lloutfitgallery.cpp @@ -1226,7 +1226,7 @@ void LLOutfitGallery::uploadOutfitImage(const std::vector& filename checkRemovePhoto(outfit_id); std::string upload_pending_name = outfit_id.asString(); std::string upload_pending_desc = ""; - LLUUID photo_id = upload_new_resource(filename, // file + upload_new_resource(filename, // file upload_pending_name, upload_pending_desc, 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE, diff --git a/indra/newview/lloutfitslist.cpp b/indra/newview/lloutfitslist.cpp index 7270580032..4171fd8822 100644 --- a/indra/newview/lloutfitslist.cpp +++ b/indra/newview/lloutfitslist.cpp @@ -823,8 +823,7 @@ void LLOutfitListBase::onOpen(const LLSD& info) mCategoriesObserver->addCategory(outfits, boost::bind(&LLOutfitListBase::refreshList, this, outfits)); - const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); - + //const LLUUID cof = gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); // Start observing changes in Current Outfit category. //mCategoriesObserver->addCategory(cof, boost::bind(&LLOutfitsList::onCOFChanged, this)); diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp index 26cd3ff1c1..e379d67e37 100644 --- a/indra/newview/llpanellandmedia.cpp +++ b/indra/newview/llpanellandmedia.cpp @@ -179,7 +179,6 @@ void LLPanelLandMedia::refresh() // enable/disable for text label for completeness mMediaSizeCtrlLabel->setEnabled( can_change_media && allow_resize ); - LLUUID tmp = parcel->getMediaID(); mMediaTextureCtrl->setImageAssetID ( parcel->getMediaID() ); mMediaTextureCtrl->setEnabled( can_change_media ); diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp index 74ec576554..0f00231643 100644 --- a/indra/newview/llpanelplaces.cpp +++ b/indra/newview/llpanelplaces.cpp @@ -800,7 +800,6 @@ void LLPanelPlaces::onSaveButtonClicked() LLStringUtil::trim(current_title_value); LLStringUtil::trim(current_notes_value); - LLUUID item_id = mItem->getUUID(); LLUUID folder_id = mLandmarkInfo->getLandmarkFolder(); bool change_parent = folder_id != mItem->getParentUUID(); diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index deebf0cd1b..708ff26ced 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1055,7 +1055,6 @@ void LLPanelProfileSecondLife::resetData() void LLPanelProfileSecondLife::processProfileProperties(const LLAvatarData* avatar_data) { - LLUUID avatar_id = getAvatarId(); const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId()); if ((relationship != NULL || gAgent.isGodlike()) && !getSelfProfile()) { diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp index ea671a130e..60bada8f58 100644 --- a/indra/newview/llspeakers.cpp +++ b/indra/newview/llspeakers.cpp @@ -982,7 +982,6 @@ void LLActiveSpeakerMgr::updateSpeakerList() // clean up text only speakers for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); ++speaker_it) { - LLUUID speaker_id = speaker_it->first; LLSpeaker* speakerp = speaker_it->second; if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 3bff01625b..01e4734b3c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7651,7 +7651,6 @@ void handle_selected_texture_info(void*) map_t::iterator it; for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it) { - LLUUID image_id = it->first; U8 te = it->second[0]; LLViewerTexture* img = node->getObject()->getTEImage(te); S32 height = img->getHeight(); diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index e2de7ac825..7abb42dd8a 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -1252,7 +1252,6 @@ bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD& S32 option = LLNotificationsUtil::getSelectedOption(notification, response); if( 0 == option ) { - LLUUID item_id = notification["payload"]["item_id"].asUUID(); llwchar wc = llwchar(notification["payload"]["item_wc"].asInteger()); LLInventoryItem* itemp = LLEmbeddedItems::getEmbeddedItemPtr(wc); if (itemp) diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 588fb4eb1b..f4d8eb6035 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1307,7 +1307,6 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi TRUE /* pick_transparent */, FALSE /* pick_rigged */); - LLUUID object_id = pick_info.getObjectID(); S32 object_face = pick_info.mObjectFace; std::string url = data; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d98a40d188..2e7ccc8334 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -856,10 +856,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) if (isSculpted()) { - LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT); - LLUUID id = sculpt_params->getSculptTexture(); - - updateSculptTexture(); + updateSculptTexture(); @@ -1109,7 +1106,6 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo if (!getVolume()->isMeshAssetLoaded()) { //load request not yet issued, request pipeline load this mesh - LLUUID asset_id = volume_params.getSculptID(); S32 available_lod = gMeshRepo.loadMesh(this, volume_params, lod, last_lod); if (available_lod != lod) { -- cgit v1.2.3 From fabfbb93e666326a9daad7c14e690a23e4567d23 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 15:45:25 -0400 Subject: Harden LLDataPackerBinaryBuffer from performing invalid memcpy in case buffer is too small --- indra/llmessage/lldatapacker.cpp | 258 +++++++++++++++++++++++---------------- 1 file changed, 156 insertions(+), 102 deletions(-) diff --git a/indra/llmessage/lldatapacker.cpp b/indra/llmessage/lldatapacker.cpp index b6adc102d2..9f7768f78e 100644 --- a/indra/llmessage/lldatapacker.cpp +++ b/indra/llmessage/lldatapacker.cpp @@ -116,9 +116,8 @@ BOOL LLDataPacker::packFixed(const F32 value, const char *name, BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, const BOOL is_signed, const U32 int_bits, const U32 frac_bits) { - //BOOL success = TRUE; + BOOL success = TRUE; //LL_INFOS() << "unpackFixed:" << name << " int:" << int_bits << " frac:" << frac_bits << LL_ENDL; - BOOL ok = FALSE; S32 unsigned_bits = int_bits + frac_bits; S32 total_bits = unsigned_bits; @@ -134,19 +133,19 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, if (total_bits <= 8) { U8 fixed_8; - ok = unpackU8(fixed_8, name); + success = unpackU8(fixed_8, name); fixed_val = (F32)fixed_8; } else if (total_bits <= 16) { U16 fixed_16; - ok = unpackU16(fixed_16, name); + success = unpackU16(fixed_16, name); fixed_val = (F32)fixed_16; } else if (total_bits <= 31) { U32 fixed_32; - ok = unpackU32(fixed_32, name); + success = unpackU32(fixed_32, name); fixed_val = (F32)fixed_32; } else @@ -164,7 +163,7 @@ BOOL LLDataPacker::unpackFixed(F32 &value, const char *name, } value = fixed_val; //LL_INFOS() << "Value: " << value << LL_ENDL; - return ok; + return success; } BOOL LLDataPacker::unpackU16s(U16 *values, S32 count, const char *name) @@ -238,37 +237,43 @@ BOOL LLDataPacker::unpackUUIDs(LLUUID *values, S32 count, const char *name) BOOL LLDataPackerBinaryBuffer::packString(const std::string& value, const char *name) { - BOOL success = TRUE; S32 length = value.length()+1; - success &= verifyLength(length, name); + if (!verifyLength(length, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.c_str(), MVT_VARIABLE, length); } mCurBufferp += length; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackString(std::string& value, const char *name) { - BOOL success = TRUE; S32 length = (S32)strlen((char *)mCurBufferp) + 1; /*Flawfinder: ignore*/ - success &= verifyLength(length, name); + if (!verifyLength(length, name)) + { + return FALSE; + } value = std::string((char*)mCurBufferp); // We already assume NULL termination calling strlen() mCurBufferp += length; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(size + 4, name); + if (!verifyLength(size + 4, name)) + { + return FALSE; + } if (mWriteEnabled) { @@ -280,102 +285,117 @@ BOOL LLDataPackerBinaryBuffer::packBinaryData(const U8 *value, S32 size, const c htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); } mCurBufferp += size; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackBinaryData(U8 *value, S32 &size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(4, name); - htolememcpy(&size, mCurBufferp, MVT_S32, 4); - mCurBufferp += 4; - success &= verifyLength(size, name); - if (success) + if (!verifyLength(4, name)) { - htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); - mCurBufferp += size; + LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; + return FALSE; } - else + + htolememcpy(&size, mCurBufferp, MVT_S32, 4); + mCurBufferp += 4; + + if (!verifyLength(size, name)) { LL_WARNS() << "LLDataPackerBinaryBuffer::unpackBinaryData would unpack invalid data, aborting!" << LL_ENDL; - success = FALSE; + return FALSE; } - return success; + + htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); + mCurBufferp += size; + + return TRUE; } BOOL LLDataPackerBinaryBuffer::packBinaryDataFixed(const U8 *value, S32 size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(size, name); + if (!verifyLength(size, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value, MVT_VARIABLE, size); } mCurBufferp += size; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackBinaryDataFixed(U8 *value, S32 size, const char *name) { - BOOL success = TRUE; - success &= verifyLength(size, name); + if (!verifyLength(size, name)) + { + return FALSE; + } htolememcpy(value, mCurBufferp, MVT_VARIABLE, size); mCurBufferp += size; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packU8(const U8 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U8), name); + if (!verifyLength(sizeof(U8), name)) + { + return FALSE; + } if (mWriteEnabled) { *mCurBufferp = value; } mCurBufferp++; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackU8(U8 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U8), name); + if (!verifyLength(sizeof(U8), name)) + { + return FALSE; + } value = *mCurBufferp; mCurBufferp++; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packU16(const U16 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U16), name); + if (!verifyLength(sizeof(U16), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_U16, 2); } mCurBufferp += 2; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackU16(U16 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U16), name); + if (!verifyLength(sizeof(U16), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_U16, 2); mCurBufferp += 2; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packS16(const S16 value, const char *name) @@ -404,134 +424,156 @@ BOOL LLDataPackerBinaryBuffer::unpackS16(S16 &value, const char *name) BOOL LLDataPackerBinaryBuffer::packU32(const U32 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U32), name); + if (!verifyLength(sizeof(U32), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_U32, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackU32(U32 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(U32), name); + if (!verifyLength(sizeof(U32), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_U32, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packS32(const S32 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(S32), name); + if (!verifyLength(sizeof(S32), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_S32, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackS32(S32 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(S32), name); + if(!verifyLength(sizeof(S32), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_S32, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packF32(const F32 value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(F32), name); + if (!verifyLength(sizeof(F32), name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, &value, MVT_F32, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackF32(F32 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(sizeof(F32), name); + if (!verifyLength(sizeof(F32), name)) + { + return FALSE; + } htolememcpy(&value, mCurBufferp, MVT_F32, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packColor4(const LLColor4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); } mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackColor4(LLColor4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packColor4U(const LLColor4U &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(4, name); + if (!verifyLength(4, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_VARIABLE, 4); } mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackColor4U(LLColor4U &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(4, name); + if (!verifyLength(4, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_VARIABLE, 4); mCurBufferp += 4; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(8, name); + if (!verifyLength(8, name)) + { + return FALSE; + } if (mWriteEnabled) { @@ -539,92 +581,106 @@ BOOL LLDataPackerBinaryBuffer::packVector2(const LLVector2 &value, const char *n htolememcpy(mCurBufferp+4, &value.mV[1], MVT_F32, 4); } mCurBufferp += 8; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackVector2(LLVector2 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(8, name); + if (!verifyLength(8, name)) + { + return FALSE; + } htolememcpy(&value.mV[0], mCurBufferp, MVT_F32, 4); htolememcpy(&value.mV[1], mCurBufferp+4, MVT_F32, 4); mCurBufferp += 8; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packVector3(const LLVector3 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(12, name); + if (!verifyLength(12, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_LLVector3, 12); } mCurBufferp += 12; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackVector3(LLVector3 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(12, name); + if (!verifyLength(12, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_LLVector3, 12); mCurBufferp += 12; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packVector4(const LLVector4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mV, MVT_LLVector4, 16); } mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackVector4(LLVector4 &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } htolememcpy(value.mV, mCurBufferp, MVT_LLVector4, 16); mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::packUUID(const LLUUID &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } if (mWriteEnabled) { htolememcpy(mCurBufferp, value.mData, MVT_LLUUID, 16); } mCurBufferp += 16; - return success; + return TRUE; } BOOL LLDataPackerBinaryBuffer::unpackUUID(LLUUID &value, const char *name) { - BOOL success = TRUE; - success &= verifyLength(16, name); + if (!verifyLength(16, name)) + { + return FALSE; + } htolememcpy(value.mData, mCurBufferp, MVT_LLUUID, 16); mCurBufferp += 16; - return success; + return TRUE; } const LLDataPackerBinaryBuffer& LLDataPackerBinaryBuffer::operator=(const LLDataPackerBinaryBuffer &a) @@ -698,15 +754,13 @@ BOOL LLDataPackerAsciiBuffer::packString(const std::string& value, const char *n BOOL LLDataPackerAsciiBuffer::unpackString(std::string& value, const char *name) { - BOOL success = TRUE; char valuestr[DP_BUFSIZE]; /*Flawfinder: ignore*/ - BOOL res = getValueStr(name, valuestr, DP_BUFSIZE); // NULL terminated - if (!res) // + if (!getValueStr(name, valuestr, DP_BUFSIZE)) // NULL terminated { return FALSE; } value = valuestr; - return success; + return TRUE; } -- cgit v1.2.3 From 129301c8e9d48e29466597f6baee6d3566fac9dc Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 15:46:42 -0400 Subject: Fix multiple leaks in the case of failure to deserialize animations --- indra/llcharacter/llkeyframemotion.cpp | 185 +++++++++++++++++---------------- 1 file changed, 97 insertions(+), 88 deletions(-) diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp index ebf7454a61..403d5bcf49 100644 --- a/indra/llcharacter/llkeyframemotion.cpp +++ b/indra/llcharacter/llkeyframemotion.cpp @@ -1229,7 +1229,7 @@ void LLKeyframeMotion::applyConstraint(JointConstraint* constraint, F32 time, U8 BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, bool allow_invalid_joints) { BOOL old_version = FALSE; - mJointMotionList = new LLKeyframeMotion::JointMotionList; + std::unique_ptr joint_motion_list(new LLKeyframeMotion::JointMotionList); //------------------------------------------------------------------------- // get base priority @@ -1272,16 +1272,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo << " for animation " << asset_id << LL_ENDL; return FALSE; } - mJointMotionList->mBasePriority = (LLJoint::JointPriority) temp_priority; + joint_motion_list->mBasePriority = (LLJoint::JointPriority) temp_priority; - if (mJointMotionList->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) + if (joint_motion_list->mBasePriority >= LLJoint::ADDITIVE_PRIORITY) { - mJointMotionList->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); - mJointMotionList->mMaxPriority = mJointMotionList->mBasePriority; + joint_motion_list->mBasePriority = (LLJoint::JointPriority)((S32)LLJoint::ADDITIVE_PRIORITY-1); + joint_motion_list->mMaxPriority = joint_motion_list->mBasePriority; } - else if (mJointMotionList->mBasePriority < LLJoint::USE_MOTION_PRIORITY) + else if (joint_motion_list->mBasePriority < LLJoint::USE_MOTION_PRIORITY) { - LL_WARNS() << "bad animation base_priority " << mJointMotionList->mBasePriority + LL_WARNS() << "bad animation base_priority " << joint_motion_list->mBasePriority << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1289,15 +1289,15 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get duration //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mDuration, "duration")) + if (!dp.unpackF32(joint_motion_list->mDuration, "duration")) { LL_WARNS() << "can't read duration" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (mJointMotionList->mDuration > MAX_ANIM_DURATION || - !llfinite(mJointMotionList->mDuration)) + if (joint_motion_list->mDuration > MAX_ANIM_DURATION || + !llfinite(joint_motion_list->mDuration)) { LL_WARNS() << "invalid animation duration" << " for animation " << asset_id << LL_ENDL; @@ -1307,14 +1307,14 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get emote (optional) //------------------------------------------------------------------------- - if (!dp.unpackString(mJointMotionList->mEmoteName, "emote_name")) + if (!dp.unpackString(joint_motion_list->mEmoteName, "emote_name")) { LL_WARNS() << "can't read optional_emote_animation" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if(mJointMotionList->mEmoteName==mID.asString()) + if(joint_motion_list->mEmoteName==mID.asString()) { LL_WARNS() << "Malformed animation mEmoteName==mID" << " for animation " << asset_id << LL_ENDL; @@ -1324,23 +1324,23 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo //------------------------------------------------------------------------- // get loop //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mLoopInPoint, "loop_in_point") || - !llfinite(mJointMotionList->mLoopInPoint)) + if (!dp.unpackF32(joint_motion_list->mLoopInPoint, "loop_in_point") || + !llfinite(joint_motion_list->mLoopInPoint)) { LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mLoopOutPoint, "loop_out_point") || - !llfinite(mJointMotionList->mLoopOutPoint)) + if (!dp.unpackF32(joint_motion_list->mLoopOutPoint, "loop_out_point") || + !llfinite(joint_motion_list->mLoopOutPoint)) { LL_WARNS() << "can't read loop point" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackS32(mJointMotionList->mLoop, "loop")) + if (!dp.unpackS32(joint_motion_list->mLoop, "loop")) { LL_WARNS() << "can't read loop" << " for animation " << asset_id << LL_ENDL; @@ -1353,22 +1353,22 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (female_land_anim == asset_id || formal_female_land_anim == asset_id) { LL_WARNS() << "Animation(" << asset_id << ") won't be looped." << LL_ENDL; - mJointMotionList->mLoop = FALSE; + joint_motion_list->mLoop = FALSE; } //------------------------------------------------------------------------- // get easeIn and easeOut //------------------------------------------------------------------------- - if (!dp.unpackF32(mJointMotionList->mEaseInDuration, "ease_in_duration") || - !llfinite(mJointMotionList->mEaseInDuration)) + if (!dp.unpackF32(joint_motion_list->mEaseInDuration, "ease_in_duration") || + !llfinite(joint_motion_list->mEaseInDuration)) { LL_WARNS() << "can't read easeIn" << " for animation " << asset_id << LL_ENDL; return FALSE; } - if (!dp.unpackF32(mJointMotionList->mEaseOutDuration, "ease_out_duration") || - !llfinite(mJointMotionList->mEaseOutDuration)) + if (!dp.unpackF32(joint_motion_list->mEaseOutDuration, "ease_out_duration") || + !llfinite(joint_motion_list->mEaseOutDuration)) { LL_WARNS() << "can't read easeOut" << " for animation " << asset_id << LL_ENDL; @@ -1393,7 +1393,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - mJointMotionList->mHandPose = (LLHandMotion::eHandPose)word; + joint_motion_list->mHandPose = (LLHandMotion::eHandPose)word; //------------------------------------------------------------------------- // get number of joint motions @@ -1419,8 +1419,8 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - mJointMotionList->mJointMotionArray.clear(); - mJointMotionList->mJointMotionArray.reserve(num_motions); + joint_motion_list->mJointMotionArray.clear(); + joint_motion_list->mJointMotionArray.reserve(num_motions); mJointStates.clear(); mJointStates.reserve(num_motions); @@ -1431,7 +1431,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo for(U32 i=0; imJointMotionArray.push_back(joint_motion); + joint_motion_list->mJointMotionArray.push_back(joint_motion); std::string joint_name; if (!dp.unpackString(joint_name, "joint_name")) @@ -1503,9 +1503,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo joint_motion->mPriority = (LLJoint::JointPriority)joint_priority; if (joint_priority != LLJoint::USE_MOTION_PRIORITY && - joint_priority > mJointMotionList->mMaxPriority) + joint_priority > joint_motion_list->mMaxPriority) { - mJointMotionList->mMaxPriority = (LLJoint::JointPriority)joint_priority; + joint_motion_list->mMaxPriority = (LLJoint::JointPriority)joint_priority; } joint_state->setPriority((LLJoint::JointPriority)joint_priority); @@ -1556,9 +1556,9 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - time = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + time = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); - if (time < 0 || time > mJointMotionList->mDuration) + if (time < 0 || time > joint_motion_list->mDuration) { LL_WARNS() << "invalid frame time" << " for animation " << asset_id << LL_ENDL; @@ -1571,38 +1571,57 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo LLVector3 rot_angles; U16 x, y, z; - BOOL success = TRUE; - if (old_version) { - success = dp.unpackVector3(rot_angles, "rot_angles") && rot_angles.isFinite(); + if (!dp.unpackVector3(rot_angles, "rot_angles")) + { + LL_WARNS() << "can't read rot_angles in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!rot_angles.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } LLQuaternion::Order ro = StringToOrder("ZYX"); rot_key.mRotation = mayaQ(rot_angles.mV[VX], rot_angles.mV[VY], rot_angles.mV[VZ], ro); } else { - success &= dp.unpackU16(x, "rot_angle_x"); - success &= dp.unpackU16(y, "rot_angle_y"); - success &= dp.unpackU16(z, "rot_angle_z"); + if (!dp.unpackU16(x, "rot_angle_x")) + { + LL_WARNS() << "can't read rot_angle_x in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "rot_angle_y")) + { + LL_WARNS() << "can't read rot_angle_y in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "rot_angle_z")) + { + LL_WARNS() << "can't read rot_angle_z in rotation key (" << k << ")" << LL_ENDL; + return FALSE; + } LLVector3 rot_vec; rot_vec.mV[VX] = U16_to_F32(x, -1.f, 1.f); rot_vec.mV[VY] = U16_to_F32(y, -1.f, 1.f); rot_vec.mV[VZ] = U16_to_F32(z, -1.f, 1.f); + + if(!rot_vec.isFinite()) + { + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" + << " for animation " << asset_id << LL_ENDL; + return FALSE; + } rot_key.mRotation.unpackFromVector3(rot_vec); } - if( !(rot_key.mRotation.isFinite()) ) - { - LL_WARNS() << "non-finite angle in rotation key" - << " for animation " << asset_id << LL_ENDL; - success = FALSE; - } - - if (!success) + if(!rot_key.mRotation.isFinite()) { - LL_WARNS() << "can't read rotation key (" << k << ")" + LL_WARNS() << "non-finite angle in rotation key (" << k << ")" << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1655,14 +1674,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo return FALSE; } - pos_key.mTime = U16_to_F32(time_short, 0.f, mJointMotionList->mDuration); + pos_key.mTime = U16_to_F32(time_short, 0.f, joint_motion_list->mDuration); } - BOOL success = TRUE; - if (old_version) { - success = dp.unpackVector3(pos_key.mPosition, "pos"); + if (!dp.unpackVector3(pos_key.mPosition, "pos")) + { + LL_WARNS() << "can't read pos in position key (" << k << ")" << LL_ENDL; + return FALSE; + } //MAINT-6162 pos_key.mPosition.mV[VX] = llclamp( pos_key.mPosition.mV[VX], -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); @@ -1674,25 +1695,30 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { U16 x, y, z; - success &= dp.unpackU16(x, "pos_x"); - success &= dp.unpackU16(y, "pos_y"); - success &= dp.unpackU16(z, "pos_z"); + if (!dp.unpackU16(x, "pos_x")) + { + LL_WARNS() << "can't read pos_x in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(y, "pos_y")) + { + LL_WARNS() << "can't read pos_y in position key (" << k << ")" << LL_ENDL; + return FALSE; + } + if (!dp.unpackU16(z, "pos_z")) + { + LL_WARNS() << "can't read pos_z in position key (" << k << ")" << LL_ENDL; + return FALSE; + } pos_key.mPosition.mV[VX] = U16_to_F32(x, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VY] = U16_to_F32(y, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); pos_key.mPosition.mV[VZ] = U16_to_F32(z, -LL_MAX_PELVIS_OFFSET, LL_MAX_PELVIS_OFFSET); } - if( !(pos_key.mPosition.isFinite()) ) + if(!pos_key.mPosition.isFinite()) { LL_WARNS() << "non-finite position in key" - << " for animation " << asset_id << LL_ENDL; - success = FALSE; - } - - if (!success) - { - LL_WARNS() << "can't read position key (" << k << ")" << " for animation " << asset_id << LL_ENDL; return FALSE; } @@ -1701,7 +1727,7 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo if (is_pelvis) { - mJointMotionList->mPelvisBBox.addPoint(pos_key.mPosition); + joint_motion_list->mPelvisBBox.addPoint(pos_key.mPosition); } } @@ -1733,23 +1759,21 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo for(S32 i = 0; i < num_constraints; ++i) { // read in constraint data - JointConstraintSharedData* constraintp = new JointConstraintSharedData; + std::unique_ptr constraintp(new JointConstraintSharedData); U8 byte = 0; if (!dp.unpackU8(byte, "chain_length")) { LL_WARNS() << "can't read constraint chain length" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } constraintp->mChainLength = (S32) byte; - if((U32)constraintp->mChainLength > mJointMotionList->getNumJointMotions()) + if((U32)constraintp->mChainLength > joint_motion_list->getNumJointMotions()) { LL_WARNS() << "invalid constraint chain length" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1757,7 +1781,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint type" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1765,7 +1788,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "invalid constraint type" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } constraintp->mConstraintType = (EConstraintType)byte; @@ -1776,7 +1798,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read source volume name" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1787,7 +1808,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "not a valid source constraint volume " << str << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1795,7 +1815,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint source offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1803,7 +1822,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint source offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1811,7 +1829,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read target volume name" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1830,7 +1847,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "not a valid target constraint volume " << str << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } } @@ -1839,7 +1855,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint target offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1847,7 +1862,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint target offset" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1855,7 +1869,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint target direction" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1863,7 +1876,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "non-finite constraint target direction" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1877,7 +1889,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease in start time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1885,7 +1896,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease in stop time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1893,7 +1903,6 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease out start time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } @@ -1901,33 +1910,31 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "can't read constraint ease out stop time" << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } - mJointMotionList->mConstraints.push_front(constraintp); - - constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte - LLJoint* joint = mCharacter->findCollisionVolume(constraintp->mSourceConstraintVolume); // get joint to which this collision volume is attached if (!joint) { return FALSE; } + + constraintp->mJointStateIndices = new S32[constraintp->mChainLength + 1]; // note: mChainLength is size-limited - comes from a byte + for (S32 i = 0; i < constraintp->mChainLength + 1; i++) { LLJoint* parent = joint->getParent(); if (!parent) { LL_WARNS() << "Joint with no parent: " << joint->getName() - << " Emote: " << mJointMotionList->mEmoteName + << " Emote: " << joint_motion_list->mEmoteName << " for animation " << asset_id << LL_ENDL; return FALSE; } joint = parent; constraintp->mJointStateIndices[i] = -1; - for (U32 j = 0; j < mJointMotionList->getNumJointMotions(); j++) + for (U32 j = 0; j < joint_motion_list->getNumJointMotions(); j++) { LLJoint* constraint_joint = getJoint(j); @@ -1948,14 +1955,16 @@ BOOL LLKeyframeMotion::deserialize(LLDataPacker& dp, const LLUUID& asset_id, boo { LL_WARNS() << "No joint index for constraint " << i << " for animation " << asset_id << LL_ENDL; - delete constraintp; return FALSE; } } + + joint_motion_list->mConstraints.push_front(constraintp.release()); } } // *FIX: support cleanup of old keyframe data + mJointMotionList = joint_motion_list.release(); // release from unique_ptr to member; LLKeyframeDataCache::addKeyframeData(getID(), mJointMotionList); mAssetStatus = ASSET_LOADED; -- cgit v1.2.3 From 3dd874a99b81b6c392f1ab4c40015ba43f7801e6 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:47:32 -0400 Subject: Fix memory leaks in lldir objc/mac --- indra/llfilesystem/lldir_mac.cpp | 32 ++++++------- indra/llfilesystem/lldir_utils_objc.h | 10 ++--- indra/llfilesystem/lldir_utils_objc.mm | 82 +++++++++++++++++----------------- 3 files changed, 60 insertions(+), 64 deletions(-) diff --git a/indra/llfilesystem/lldir_mac.cpp b/indra/llfilesystem/lldir_mac.cpp index 3bc4ee844e..9ad8e274b6 100644 --- a/indra/llfilesystem/lldir_mac.cpp +++ b/indra/llfilesystem/lldir_mac.cpp @@ -66,16 +66,16 @@ LLDir_Mac::LLDir_Mac() const std::string secondLifeString = "SecondLife"; - std::string *executablepathstr = getSystemExecutableFolder(); + std::string executablepathstr = getSystemExecutableFolder(); //NOTE: LLINFOS/LLERRS will not output to log here. The streams are not initialized. - if (executablepathstr) + if (!executablepathstr.empty()) { // mExecutablePathAndName - mExecutablePathAndName = *executablepathstr; + mExecutablePathAndName = executablepathstr; - boost::filesystem::path executablepath(*executablepathstr); + boost::filesystem::path executablepath(executablepathstr); # ifndef BOOST_SYSTEM_NO_DEPRECATED #endif @@ -83,8 +83,8 @@ LLDir_Mac::LLDir_Mac() mExecutableDir = executablepath.parent_path().string(); // mAppRODataDir - std::string *resourcepath = getSystemResourceFolder(); - mAppRODataDir = *resourcepath; + std::string resourcepath = getSystemResourceFolder(); + mAppRODataDir = resourcepath; // *NOTE: When running in a dev tree, use the copy of // skins in indra/newview/ rather than in the application bundle. This @@ -110,11 +110,11 @@ LLDir_Mac::LLDir_Mac() } // mOSUserDir - std::string *appdir = getSystemApplicationSupportFolder(); + std::string appdir = getSystemApplicationSupportFolder(); std::string rootdir; //Create root directory - if (CreateDirectory(*appdir, secondLifeString, &rootdir)) + if (CreateDirectory(appdir, secondLifeString, &rootdir)) { // Save the full path to the folder @@ -128,12 +128,10 @@ LLDir_Mac::LLDir_Mac() } //mOSCacheDir - std::string *cachedir = getSystemCacheFolder(); - - if (cachedir) - + std::string cachedir = getSystemCacheFolder(); + if (!cachedir.empty()) { - mOSCacheDir = *cachedir; + mOSCacheDir = cachedir; //TODO: This changes from ~/Library/Cache/Secondlife to ~/Library/Cache/com.app.secondlife/Secondlife. Last dir level could go away. CreateDirectory(mOSCacheDir, secondLifeString, NULL); } @@ -143,12 +141,10 @@ LLDir_Mac::LLDir_Mac() // mTempDir //Aura 120920 boost::filesystem::temp_directory_path() not yet implemented on mac. :( - std::string *tmpdir = getSystemTempFolder(); - if (tmpdir) + std::string tmpdir = getSystemTempFolder(); + if (!tmpdir.empty()) { - - CreateDirectory(*tmpdir, secondLifeString, &mTempDir); - if (tmpdir) delete tmpdir; + CreateDirectory(tmpdir, secondLifeString, &mTempDir); } mWorkingDir = getCurPath(); diff --git a/indra/llfilesystem/lldir_utils_objc.h b/indra/llfilesystem/lldir_utils_objc.h index 12019c4284..59dbeb4aec 100644 --- a/indra/llfilesystem/lldir_utils_objc.h +++ b/indra/llfilesystem/lldir_utils_objc.h @@ -33,11 +33,11 @@ #include -std::string* getSystemTempFolder(); -std::string* getSystemCacheFolder(); -std::string* getSystemApplicationSupportFolder(); -std::string* getSystemResourceFolder(); -std::string* getSystemExecutableFolder(); +std::string getSystemTempFolder(); +std::string getSystemCacheFolder(); +std::string getSystemApplicationSupportFolder(); +std::string getSystemResourceFolder(); +std::string getSystemExecutableFolder(); #endif // LL_LLDIR_UTILS_OBJC_H diff --git a/indra/llfilesystem/lldir_utils_objc.mm b/indra/llfilesystem/lldir_utils_objc.mm index da55a2f897..20540fb93c 100644 --- a/indra/llfilesystem/lldir_utils_objc.mm +++ b/indra/llfilesystem/lldir_utils_objc.mm @@ -30,75 +30,75 @@ #include "lldir_utils_objc.h" #import -std::string* getSystemTempFolder() +std::string getSystemTempFolder() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSString * tempDir = NSTemporaryDirectory(); - if (tempDir == nil) - tempDir = @"/tmp"; - std::string *result = ( new std::string([tempDir UTF8String]) ); - [pool release]; + std::string result; + @autoreleasepool { + NSString * tempDir = NSTemporaryDirectory(); + if (tempDir == nil) + tempDir = @"/tmp"; + result = std::string([tempDir UTF8String]); + } return result; } //findSystemDirectory scoped exclusively to this file. -std::string* findSystemDirectory(NSSearchPathDirectory searchPathDirectory, +std::string findSystemDirectory(NSSearchPathDirectory searchPathDirectory, NSSearchPathDomainMask domainMask) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - std::string *result = nil; - NSString *path = nil; - - // Search for the path - NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory, - domainMask, - YES); - if ([paths count]) - { - path = [paths objectAtIndex:0]; - //HACK: Always attempt to create directory, ignore errors. - NSError *error = nil; - - [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; - + std::string result; + @autoreleasepool { + NSString *path = nil; - result = new std::string([path UTF8String]); + // Search for the path + NSArray* paths = NSSearchPathForDirectoriesInDomains(searchPathDirectory, + domainMask, + YES); + if ([paths count]) + { + path = [paths objectAtIndex:0]; + //HACK: Always attempt to create directory, ignore errors. + NSError *error = nil; + + [[NSFileManager defaultManager] createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:&error]; + + + result = std::string([path UTF8String]); + } } - [pool release]; return result; } -std::string* getSystemExecutableFolder() +std::string getSystemExecutableFolder() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *bundlePath = [[NSBundle mainBundle] executablePath]; - std::string *result = (new std::string([bundlePath UTF8String])); - [pool release]; + std::string result; + @autoreleasepool { + NSString *bundlePath = [[NSBundle mainBundle] executablePath]; + result = std::string([bundlePath UTF8String]); + } return result; } -std::string* getSystemResourceFolder() +std::string getSystemResourceFolder() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; - std::string *result = (new std::string([bundlePath UTF8String])); - [pool release]; + std::string result; + @autoreleasepool { + NSString *bundlePath = [[NSBundle mainBundle] resourcePath]; + result = std::string([bundlePath UTF8String]); + } return result; } -std::string* getSystemCacheFolder() +std::string getSystemCacheFolder() { return findSystemDirectory (NSCachesDirectory, NSUserDomainMask); } -std::string* getSystemApplicationSupportFolder() +std::string getSystemApplicationSupportFolder() { return findSystemDirectory (NSApplicationSupportDirectory, NSUserDomainMask); -- cgit v1.2.3 From 662dd44587796072b81b47f202597569f4e8c48d Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:49:32 -0400 Subject: Fix leaks in mac filepicker code --- indra/newview/llfilepicker.cpp | 10 +-- indra/newview/llfilepicker.h | 2 +- indra/newview/llfilepicker_mac.h | 4 +- indra/newview/llfilepicker_mac.mm | 157 +++++++++++++++++++------------------- 4 files changed, 88 insertions(+), 85 deletions(-) diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 3669fb1eeb..e3a695fc79 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -586,9 +586,9 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, #elif LL_DARWIN -std::vector* LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) +std::unique_ptr> LLFilePicker::navOpenFilterProc(ELoadFilter filter) //(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode) { - std::vector *allowedv = new std::vector< std::string >; + std::unique_ptr> allowedv(new std::vector< std::string >); switch(filter) { case FFLOAD_ALL: @@ -661,9 +661,9 @@ bool LLFilePicker::doNavChooseDialog(ELoadFilter filter) gViewerWindow->getWindow()->beforeDialog(); - std::vector *allowed_types=navOpenFilterProc(filter); + std::unique_ptr> allowed_types = navOpenFilterProc(filter); - std::vector *filev = doLoadDialog(allowed_types, + std::unique_ptr> filev = doLoadDialog(allowed_types.get(), mPickOptions); gViewerWindow->getWindow()->afterDialog(); @@ -780,7 +780,7 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena gViewerWindow->getWindow()->beforeDialog(); // Run the dialog - std::string* filev = doSaveDialog(&namestring, + std::unique_ptr filev = doSaveDialog(&namestring, &type, &creator, &extension, diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 04ba4416d7..73baeca1c0 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -167,7 +167,7 @@ private: bool doNavChooseDialog(ELoadFilter filter); bool doNavSaveDialog(ESaveFilter filter, const std::string& filename); - std::vector* navOpenFilterProc(ELoadFilter filter); + std::unique_ptr> navOpenFilterProc(ELoadFilter filter); #endif #if LL_GTK diff --git a/indra/newview/llfilepicker_mac.h b/indra/newview/llfilepicker_mac.h index e0b7e2e8ce..b2fb371afe 100644 --- a/indra/newview/llfilepicker_mac.h +++ b/indra/newview/llfilepicker_mac.h @@ -39,9 +39,9 @@ #include //void modelessPicker(); -std::vector* doLoadDialog(const std::vector* allowed_types, +std::unique_ptr> doLoadDialog(const std::vector* allowed_types, unsigned int flags); -std::string* doSaveDialog(const std::string* file, +std::unique_ptr doSaveDialog(const std::string* file, const std::string* type, const std::string* creator, const std::string* extension, diff --git a/indra/newview/llfilepicker_mac.mm b/indra/newview/llfilepicker_mac.mm index 1438e4dc0a..0ae5fc3f77 100644 --- a/indra/newview/llfilepicker_mac.mm +++ b/indra/newview/llfilepicker_mac.mm @@ -29,104 +29,107 @@ #include #include "llfilepicker_mac.h" -std::vector* doLoadDialog(const std::vector* allowed_types, +std::unique_ptr> doLoadDialog(const std::vector* allowed_types, unsigned int flags) { - int i, result; - - //Aura TODO: We could init a small window and release it at the end of this routine - //for a modeless interface. - - NSOpenPanel *panel = [NSOpenPanel openPanel]; - //NSString *fileName = nil; - NSMutableArray *fileTypes = nil; - - - if ( allowed_types && !allowed_types->empty()) - { - fileTypes = [[NSMutableArray alloc] init]; + std::unique_ptr> outfiles; + + @autoreleasepool { + int i, result; + //Aura TODO: We could init a small window and release it at the end of this routine + //for a modeless interface. + + NSOpenPanel *panel = [NSOpenPanel openPanel]; + //NSString *fileName = nil; + NSMutableArray *fileTypes = nil; - for (i=0;isize();++i) + if ( allowed_types && !allowed_types->empty()) { - [fileTypes addObject: - [NSString stringWithCString:(*allowed_types)[i].c_str() - encoding:[NSString defaultCStringEncoding]]]; + fileTypes = [[[NSMutableArray alloc] init] autorelease]; + + for (i=0;isize();++i) + { + [fileTypes addObject: + [NSString stringWithCString:(*allowed_types)[i].c_str() + encoding:[NSString defaultCStringEncoding]]]; + } } - } - //[panel setMessage:@"Import one or more files or directories."]; - [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ]; - [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ]; - [panel setCanCreateDirectories: true]; - [panel setResolvesAliases: true]; - [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )]; - [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; - - std::vector* outfiles = NULL; - - if (fileTypes) - { - [panel setAllowedFileTypes:fileTypes]; - result = [panel runModal]; - } - else - { - // I suggest it's better to open the last path and let this default to home dir as necessary - // for consistency with other OS X apps - // - //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ]; - result = [panel runModal]; - } - - if (result == NSOKButton) - { - NSArray *filesToOpen = [panel URLs]; - int i, count = [filesToOpen count]; + //[panel setMessage:@"Import one or more files or directories."]; + [panel setAllowsMultipleSelection: ( (flags & F_MULTIPLE)?true:false ) ]; + [panel setCanChooseDirectories: ( (flags & F_DIRECTORY)?true:false ) ]; + [panel setCanCreateDirectories: true]; + [panel setResolvesAliases: true]; + [panel setCanChooseFiles: ( (flags & F_FILE)?true:false )]; + [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; - if (count > 0) + if (fileTypes) + { + [panel setAllowedFileTypes:fileTypes]; + result = [panel runModal]; + } + else { - outfiles = new std::vector; + // I suggest it's better to open the last path and let this default to home dir as necessary + // for consistency with other OS X apps + // + //[panel setDirectoryURL: fileURLWithPath(NSHomeDirectory()) ]; + result = [panel runModal]; } - for (i=0; ipush_back(*afilestr); + if (result == NSOKButton) + { + NSArray *filesToOpen = [panel URLs]; + int i, count = [filesToOpen count]; + + if (count > 0) + { + outfiles.reset(new std::vector); + } + + for (i=0; ipush_back(afilestr); + } } } + return outfiles; } -std::string* doSaveDialog(const std::string* file, +std::unique_ptr doSaveDialog(const std::string* file, const std::string* type, const std::string* creator, const std::string* extension, unsigned int flags) { - NSSavePanel *panel = [NSSavePanel savePanel]; - - NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; - NSArray *fileType = [extensionns componentsSeparatedByString:@","]; - - //[panel setMessage:@"Save Image File"]; - [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; - [panel setCanSelectHiddenExtension:true]; - [panel setAllowedFileTypes:fileType]; - NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; - - std::string *outfile = NULL; - NSURL* url = [NSURL fileURLWithPath:fileName]; - [panel setNameFieldStringValue: fileName]; - [panel setDirectoryURL: url]; - if([panel runModal] == - NSFileHandlingPanelOKButton) - { - NSURL* url = [panel URL]; - NSString* p = [url path]; - outfile = new std::string( [p UTF8String] ); - // write the file - } + std::unique_ptr outfile; + @autoreleasepool { + NSSavePanel *panel = [NSSavePanel savePanel]; + + NSString *extensionns = [NSString stringWithCString:extension->c_str() encoding:[NSString defaultCStringEncoding]]; + NSArray *fileType = [extensionns componentsSeparatedByString:@","]; + + //[panel setMessage:@"Save Image File"]; + [panel setTreatsFilePackagesAsDirectories: ( flags & F_NAV_SUPPORT ) ]; + [panel setCanSelectHiddenExtension:true]; + [panel setAllowedFileTypes:fileType]; + NSString *fileName = [NSString stringWithCString:file->c_str() encoding:[NSString defaultCStringEncoding]]; + + NSURL* url = [NSURL fileURLWithPath:fileName]; + [panel setNameFieldStringValue: fileName]; + [panel setDirectoryURL: url]; + if([panel runModal] == + NSFileHandlingPanelOKButton) + { + NSURL* url = [panel URL]; + NSString* p = [url path]; + outfile.reset(new std::string([p UTF8String])); + // write the file + } + } return outfile; } -- cgit v1.2.3 From 97ea17e6e9fec4538868e3dc86b802c1117e012b Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:50:38 -0400 Subject: Fix leak of copy and paste on mac --- indra/llwindow/llwindowmacosx-objc.h | 2 +- indra/llwindow/llwindowmacosx-objc.mm | 45 ++++++++++++++++++----------------- indra/llwindow/llwindowmacosx.cpp | 7 ++++-- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/indra/llwindow/llwindowmacosx-objc.h b/indra/llwindow/llwindowmacosx-objc.h index 43edc0110d..77024d3a9c 100644 --- a/indra/llwindow/llwindowmacosx-objc.h +++ b/indra/llwindow/llwindowmacosx-objc.h @@ -83,7 +83,7 @@ int createNSApp(int argc, const char **argv); void setupCocoa(); bool pasteBoardAvailable(); bool copyToPBoard(const unsigned short *str, unsigned int len); -const unsigned short *copyFromPBoard(); +unsigned short *copyFromPBoard(); CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY); short releaseImageCursor(CursorRef ref); short setImageCursor(CursorRef ref); diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index 5ec9b017cf..acbcd1c281 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -64,13 +64,13 @@ void setupCocoa() bool copyToPBoard(const unsigned short *str, unsigned int len) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; - NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - [pboard clearContents]; - - NSArray *contentsToPaste = [[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil]; - [pool release]; - return [pboard writeObjects:contentsToPaste]; + @autoreleasepool { + NSPasteboard *pboard = [NSPasteboard generalPasteboard]; + [pboard clearContents]; + + NSArray *contentsToPaste = [[[NSArray alloc] initWithObjects:[NSString stringWithCharacters:str length:len], nil] autorelease]; + return [pboard writeObjects:contentsToPaste]; + } } bool pasteBoardAvailable() @@ -79,22 +79,23 @@ bool pasteBoardAvailable() return [[NSPasteboard generalPasteboard] canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; } -const unsigned short *copyFromPBoard() +unsigned short *copyFromPBoard() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init]; - NSPasteboard *pboard = [NSPasteboard generalPasteboard]; - NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; - NSString *str = NULL; - BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; - if (ok) - { - NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]]; - str = [objToPaste objectAtIndex:0]; - } - unichar* temp = (unichar*)calloc([str length]+1, sizeof(unichar)); - [str getCharacters:temp]; - [pool release]; - return temp; + @autoreleasepool { + NSPasteboard *pboard = [NSPasteboard generalPasteboard]; + NSArray *classArray = [NSArray arrayWithObject:[NSString class]]; + NSString *str = NULL; + BOOL ok = [pboard canReadObjectForClasses:classArray options:[NSDictionary dictionary]]; + if (ok) + { + NSArray *objToPaste = [pboard readObjectsForClasses:classArray options:[NSDictionary dictionary]]; + str = [objToPaste objectAtIndex:0]; + } + NSUInteger str_len = [str length]; + unichar* temp = (unichar*)calloc(str_len+1, sizeof(unichar)); + [str getCharacters:temp range:NSMakeRange(0, str_len)]; + return temp; + } } CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index c29131d60b..cf940bf68c 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1246,8 +1246,11 @@ BOOL LLWindowMacOSX::isClipboardTextAvailable() } BOOL LLWindowMacOSX::pasteTextFromClipboard(LLWString &dst) -{ - llutf16string str(copyFromPBoard()); +{ + unsigned short* pboard_data = copyFromPBoard(); // must free returned data + llutf16string str(pboard_data); + free(pboard_data); + dst = utf16str_to_wstring(str); if (dst != L"") { -- cgit v1.2.3 From d628a537f52b29dc1afd1dbea562f2abf48c7e4a Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:51:11 -0400 Subject: Fix leaks in mac IME --- indra/newview/llappdelegate-objc.mm | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm index 5214f4b838..1090888c1c 100644 --- a/indra/newview/llappdelegate-objc.mm +++ b/indra/newview/llappdelegate-objc.mm @@ -46,6 +46,7 @@ - (void)dealloc { + [currentInputLanguage release]; [super dealloc]; } @@ -199,12 +200,14 @@ - (bool) romanScript { - // How to add support for new languages with the input window: - // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.) - NSArray *nonRomanScript = [[NSArray alloc] initWithObjects:@"ja", @"ko", @"zh-Hant", @"zh-Hans", nil]; - if ([nonRomanScript containsObject:currentInputLanguage]) - { - return false; + @autoreleasepool { + // How to add support for new languages with the input window: + // Simply append this array with the language code (ja for japanese, ko for korean, zh for chinese, etc.) + NSArray* nonRomanScript = @[@"ja", @"ko", @"zh-Hant", @"zh-Hans"]; + if ([nonRomanScript containsObject:currentInputLanguage]) + { + return false; + } } return true; -- cgit v1.2.3 From 83466b301a34183a0d146d13bdc7973e02172588 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Fri, 28 Oct 2022 18:53:34 -0400 Subject: Clean up autorelease behavior in llwindowmac and additional leaks --- indra/llwindow/llwindowmacosx-objc.mm | 91 +++++++++++++++++------------------ 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm index acbcd1c281..57c3d86295 100644 --- a/indra/llwindow/llwindowmacosx-objc.mm +++ b/indra/llwindow/llwindowmacosx-objc.mm @@ -49,14 +49,12 @@ void setupCocoa() if(!inited) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. - // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' - // when init'ing the Cocoa App window. - [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; - - [pool release]; + @autoreleasepool { + // The following prevents the Cocoa command line parser from trying to open 'unknown' arguements as documents. + // ie. running './secondlife -set Language fr' would cause a pop-up saying can't open document 'fr' + // when init'ing the Cocoa App window. + [[NSUserDefaults standardUserDefaults] setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"]; + } inited = true; } @@ -100,19 +98,18 @@ unsigned short *copyFromPBoard() CursorRef createImageCursor(const char *fullpath, int hotspotX, int hotspotY) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - - // extra retain on the NSCursor since we want it to live for the lifetime of the app. - NSCursor *cursor = - [[[NSCursor alloc] - initWithImage: - [[[NSImage alloc] initWithContentsOfFile: - [NSString stringWithUTF8String:fullpath] - ]autorelease] - hotSpot:NSMakePoint(hotspotX, hotspotY) - ]retain]; - - [pool release]; + NSCursor *cursor = nil; + @autoreleasepool { + // extra retain on the NSCursor since we want it to live for the lifetime of the app. + cursor = + [[[NSCursor alloc] + initWithImage: + [[[NSImage alloc] initWithContentsOfFile: + [NSString stringWithUTF8String:fullpath] + ] autorelease] + hotSpot:NSMakePoint(hotspotX, hotspotY) + ] retain]; + } return (CursorRef)cursor; } @@ -179,10 +176,10 @@ OSErr releaseImageCursor(CursorRef ref) { if( ref != NULL ) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSCursor *cursor = (NSCursor*)ref; - [cursor release]; - [pool release]; + @autoreleasepool { + NSCursor *cursor = (NSCursor*)ref; + [cursor autorelease]; + } } else { @@ -196,10 +193,10 @@ OSErr setImageCursor(CursorRef ref) { if( ref != NULL ) { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSCursor *cursor = (NSCursor*)ref; - [cursor set]; - [pool release]; + @autoreleasepool { + NSCursor *cursor = (NSCursor*)ref; + [cursor set]; + } } else { @@ -420,24 +417,26 @@ void requestUserAttention() long showAlert(std::string text, std::string title, int type) { - NSAlert *alert = [[NSAlert alloc] init]; - - [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]]; - [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]]; - if (type == 0) - { - [alert addButtonWithTitle:@"Okay"]; - } else if (type == 1) - { - [alert addButtonWithTitle:@"Okay"]; - [alert addButtonWithTitle:@"Cancel"]; - } else if (type == 2) - { - [alert addButtonWithTitle:@"Yes"]; - [alert addButtonWithTitle:@"No"]; + long ret = 0; + @autoreleasepool { + NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + + [alert setMessageText:[NSString stringWithCString:title.c_str() encoding:[NSString defaultCStringEncoding]]]; + [alert setInformativeText:[NSString stringWithCString:text.c_str() encoding:[NSString defaultCStringEncoding]]]; + if (type == 0) + { + [alert addButtonWithTitle:@"Okay"]; + } else if (type == 1) + { + [alert addButtonWithTitle:@"Okay"]; + [alert addButtonWithTitle:@"Cancel"]; + } else if (type == 2) + { + [alert addButtonWithTitle:@"Yes"]; + [alert addButtonWithTitle:@"No"]; + } + ret = [alert runModal]; } - long ret = [alert runModal]; - [alert dealloc]; if (ret == NSAlertFirstButtonReturn) { -- cgit v1.2.3 From d89033420ef05b9b0a5751c3f254ce802e90df0b Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sat, 29 Oct 2022 23:18:03 -0400 Subject: Fix RenderAppleUseMultGL debug setting for enabling threaded GL engine --- indra/llwindow/llwindowmacosx.cpp | 4 ++-- indra/llwindow/llwindowmacosx.h | 1 + indra/newview/llappviewer.cpp | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index cf940bf68c..2fe0ed469e 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -668,11 +668,11 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits if (cgl_err != kCGLNoError ) { - LL_DEBUGS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; + LL_INFOS("GLInit") << "Multi-threaded OpenGL not available." << LL_ENDL; } else { - LL_DEBUGS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; + LL_INFOS("GLInit") << "Multi-threaded OpenGL enabled." << LL_ENDL; } } makeFirstResponder(mWindow, mGLView); diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h index b0f339e1db..851c860017 100644 --- a/indra/llwindow/llwindowmacosx.h +++ b/indra/llwindow/llwindowmacosx.h @@ -228,6 +228,7 @@ protected: BOOL mLanguageTextInputAllowed; LLPreeditor* mPreeditor; +public: static BOOL sUseMultGL; friend class LLWindowManager; diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 4f3e0b08e4..5d509fa4ff 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -135,6 +135,10 @@ #include "vlc/libvlc_version.h" #endif // LL_LINUX +#if LL_DARWIN +#include "llwindowmacosx.h" +#endif + // Third party library includes #include #include @@ -560,6 +564,7 @@ static void settings_to_globals() LLWorldMapView::setScaleSetting(gSavedSettings.getF32("MapScale")); #if LL_DARWIN + LLWindowMacOSX::sUseMultGL = gSavedSettings.getBOOL("RenderAppleUseMultGL"); gHiDPISupport = gSavedSettings.getBOOL("RenderHiDPI"); #endif } -- cgit v1.2.3 From 971fd6f8433b07bbd51ef83f2de518ef8b20d07f Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sat, 29 Oct 2022 23:18:35 -0400 Subject: Fix use of deprecated CGDisplayAvailableModes with CGDisplayCopyAllDisplayModes --- indra/llwindow/llwindowmacosx.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp index 2fe0ed469e..f924b17090 100644 --- a/indra/llwindow/llwindowmacosx.cpp +++ b/indra/llwindow/llwindowmacosx.cpp @@ -1283,7 +1283,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r { if (!mSupportedResolutions) { - CFArrayRef modes = CGDisplayAvailableModes(mDisplay); + CFArrayRef modes = CGDisplayCopyAllDisplayModes(mDisplay, nullptr); if(modes != NULL) { @@ -1322,6 +1322,7 @@ LLWindow::LLWindowResolution* LLWindowMacOSX::getSupportedResolutions(S32 &num_r } } } + CFRelease(modes); } } -- cgit v1.2.3 From d0e07c770b978d57210a5403bc42cc48e700ef63 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 06:56:16 -0400 Subject: Fix checks for empty LLSD maps to use size and not emptyMap which is for creating an empty LLSDMap type. --- indra/llcommon/llerror.cpp | 2 +- indra/llui/llmultislider.cpp | 2 +- indra/llwindow/lldxhardware.cpp | 2 +- indra/newview/llenvironment.cpp | 2 +- indra/newview/llfloatermodelpreview.cpp | 2 +- indra/newview/llimprocessing.cpp | 2 +- indra/newview/llpanelexperiencelog.cpp | 2 +- indra/newview/llpanelobject.cpp | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp index 919d2dabc4..56fb7c21ca 100644 --- a/indra/llcommon/llerror.cpp +++ b/indra/llcommon/llerror.cpp @@ -943,7 +943,7 @@ namespace LLError for (a = sets.beginArray(), end = sets.endArray(); a != end; ++a) { const LLSD& entry = *a; - if (entry.isMap() && !entry.emptyMap()) + if (entry.isMap() && entry.size() != 0) { ELevel level = decodeLevel(entry["level"]); diff --git a/indra/llui/llmultislider.cpp b/indra/llui/llmultislider.cpp index f89064d59a..604d246f12 100644 --- a/indra/llui/llmultislider.cpp +++ b/indra/llui/llmultislider.cpp @@ -92,7 +92,7 @@ LLMultiSlider::LLMultiSlider(const LLMultiSlider::Params& p) mMouseDownSignal(NULL), mMouseUpSignal(NULL) { - mValue.emptyMap(); + mValue = LLSD::emptyMap(); mCurSlider = LLStringUtil::null; if (mOrientation == HORIZONTAL) diff --git a/indra/llwindow/lldxhardware.cpp b/indra/llwindow/lldxhardware.cpp index 81e938edbe..391a377280 100644 --- a/indra/llwindow/lldxhardware.cpp +++ b/indra/llwindow/lldxhardware.cpp @@ -1098,7 +1098,7 @@ LLSD LLDXHardware::getDisplayInfo() } LCleanup: - if (ret.emptyMap()) + if (!ret.isMap() || (ret.size() == 0)) { LL_INFOS() << "Failed to get data, cleaning up" << LL_ENDL; } diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 1300cf3658..a01410e521 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -3086,7 +3086,7 @@ bool LLEnvironment::loadFromSettings() LL_INFOS("ENVIRONMENT") << "Unable to open previous session environment file " << user_filepath << LL_ENDL; } - if (!env_data.isMap() || env_data.emptyMap()) + if (!env_data.isMap() || (env_data.size() == 0)) { LL_DEBUGS("ENVIRONMENT") << "Empty map loaded from: " << user_filepath << LL_ENDL; return false; diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 66a245b779..6f8f73bca0 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -1740,7 +1740,7 @@ void LLFloaterModelPreview::toggleCalculateButton(bool visible) childSetTextArg("download_weight", "[ST]", tbd); childSetTextArg("server_weight", "[SIM]", tbd); childSetTextArg("physics_weight", "[PH]", tbd); - if (!mModelPhysicsFee.isMap() || mModelPhysicsFee.emptyMap()) + if (!mModelPhysicsFee.isMap() || (mModelPhysicsFee.size() == 0)) { childSetTextArg("upload_fee", "[FEE]", tbd); } diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp index 0524313a5c..57c0c7388e 100644 --- a/indra/newview/llimprocessing.cpp +++ b/indra/newview/llimprocessing.cpp @@ -1561,7 +1561,7 @@ void LLIMProcessing::requestOfflineMessagesCoro(std::string url) return; } - if (messages.emptyArray()) + if (messages.size() == 0) { // Nothing to process return; diff --git a/indra/newview/llpanelexperiencelog.cpp b/indra/newview/llpanelexperiencelog.cpp index 44b4728df7..e5c637938f 100644 --- a/indra/newview/llpanelexperiencelog.cpp +++ b/indra/newview/llpanelexperiencelog.cpp @@ -112,7 +112,7 @@ void LLPanelExperienceLog::refresh() int items = 0; bool moreItems = false; LLSD events_to_save = events; - if (!events.emptyMap()) + if (events.isMap() && events.size() != 0) { LLSD::map_const_iterator day = events.endMap(); do diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 0bfc1297d3..c04b402610 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2119,7 +2119,7 @@ bool LLPanelObject::menuEnableItem(const LLSD& userdata) } else if (command == "params_paste") { - return mClipboardParams.isMap() && !mClipboardParams.emptyMap(); + return mClipboardParams.isMap() && (mClipboardParams.size() != 0); } // copy options else if (command == "psr_copy") -- cgit v1.2.3 From 8669f3f4c207e913bc2f6e39438d92d76b3aa1c4 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 06:59:54 -0400 Subject: Fix line editors deselecting when pressing capslock --- indra/llui/lllineeditor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp index 33037b5001..4c7dd034fc 100644 --- a/indra/llui/lllineeditor.cpp +++ b/indra/llui/lllineeditor.cpp @@ -1567,7 +1567,7 @@ BOOL LLLineEditor::handleKeyHere(KEY key, MASK mask ) KEY_SHIFT != key && KEY_CONTROL != key && KEY_ALT != key && - KEY_CAPSLOCK ) + KEY_CAPSLOCK != key) { deselect(); } -- cgit v1.2.3 From f3dd2bf95f942653123ec7a1011cf873fa7b4fb3 Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 06:59:08 -0400 Subject: Fix menu checks for enabling object sit and touch to not traverse the entire menu holder to update labels --- indra/newview/llviewermenu.cpp | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 3573af40cb..fa2ec5fbec 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2803,14 +2803,15 @@ void handle_object_show_original() } -static void init_default_item_label(const std::string& item_name) +static void init_default_item_label(LLUICtrl* ctrl) { + const std::string& item_name = ctrl->getName(); boost::unordered_map::iterator it = sDefaultItemLabels.find(item_name); if (it == sDefaultItemLabels.end()) { // *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value // (doesn't seem to matter much ATM). - LLStringExplicit default_label = gMenuHolder->childGetValue(item_name).asString(); + LLStringExplicit default_label = ctrl->getValue().asString(); if (!default_label.empty()) { sDefaultItemLabels.insert(std::pair(item_name, default_label)); @@ -2841,18 +2842,17 @@ bool enable_object_touch(LLUICtrl* ctrl) new_value = obj->flagHandleTouch() || (parent && parent->flagHandleTouch()); } - std::string item_name = ctrl->getName(); - init_default_item_label(item_name); + init_default_item_label(ctrl); // Update label based on the node touch name if available. LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid && !node->mTouchName.empty()) { - gMenuHolder->childSetValue(item_name, node->mTouchName); + ctrl->setValue(node->mTouchName); } else { - gMenuHolder->childSetValue(item_name, get_default_item_label(item_name)); + ctrl->setValue(get_default_item_label(ctrl->getName())); } return new_value; @@ -6591,20 +6591,18 @@ bool enable_object_sit(LLUICtrl* ctrl) bool sitting_on_sel = sitting_on_selection(); if (!sitting_on_sel) { - std::string item_name = ctrl->getName(); - // init default labels - init_default_item_label(item_name); + init_default_item_label(ctrl); // Update label LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode(); if (node && node->mValid && !node->mSitName.empty()) { - gMenuHolder->childSetValue(item_name, node->mSitName); + ctrl->setValue(node->mSitName); } else { - gMenuHolder->childSetValue(item_name, get_default_item_label(item_name)); + ctrl->setValue(get_default_item_label(ctrl->getName())); } } return !sitting_on_sel && is_object_sittable(); -- cgit v1.2.3 From 0c36fed11056511872afae14a39a88f5e46be0fc Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Sun, 30 Oct 2022 18:05:34 -0400 Subject: Correct macOS png loader to use a default gamma of 2.2 as apple has done since OS 10.6 --- indra/llimage/llpngwrapper.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/indra/llimage/llpngwrapper.cpp b/indra/llimage/llpngwrapper.cpp index f7dc6272cf..cad7c00042 100644 --- a/indra/llimage/llpngwrapper.cpp +++ b/indra/llimage/llpngwrapper.cpp @@ -257,12 +257,7 @@ void LLPngWrapper::normalizeImage() png_set_strip_16(mReadPngPtr); } -#if LL_DARWIN - const F64 SCREEN_GAMMA = 1.8; -#else const F64 SCREEN_GAMMA = 2.2; -#endif - if (png_get_gAMA(mReadPngPtr, mReadInfoPtr, &mGamma)) { png_set_gamma(mReadPngPtr, SCREEN_GAMMA, mGamma); -- cgit v1.2.3 From 520ebb392bd06701fb6f6472cccebfaa8f13a03c Mon Sep 17 00:00:00 2001 From: Beq Date: Sat, 5 Nov 2022 22:37:14 +0000 Subject: [BUG-232834][BUG-232871] Alpha mask is being applied with emissive mask This is the most local fix for this issue, addressing the specific unqualified use of HAS_ALPHA_MASK. If we find other issues with alpha mask being applied incorrectly then, it may be better to fix higher up in llvieweshadermgr.cpp by reverting the changes from SL-17532. For now, this way works for this specific bug without non-emissive side-effects. --- indra/newview/app_settings/shaders/class1/deferred/materialF.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl index b26194f278..1280bc20a8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl @@ -227,7 +227,7 @@ void main() vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy); diffcol.rgb *= vertex_color.rgb; -#ifdef HAS_ALPHA_MASK +#if HAS_ALPHA_MASK && (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE) #if DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND if (diffcol.a*vertex_color.a < minimum_alpha) #else -- cgit v1.2.3 From 73ca604ad5aa5dc93198ab8778b135b7f01d5c7b Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 14 Nov 2022 22:39:03 +0200 Subject: SL-18618 Update libpng --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index 1a353fe2e9..f363b76706 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -1418,9 +1418,9 @@ archive hash - c1c9e32e21f3c34d91ed045b2ca91f24 + 7a0059748d0b8733f2f9ce434cf604b8 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87781/805801/libpng-1.6.8.563850-darwin64-563850.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107514/937867/libpng-1.6.38.576621-darwin64-576621.tar.bz2 name darwin64 @@ -1442,9 +1442,9 @@ archive hash - 642e9cf95c8ccd0eb34f6d7a40df585a + 3112013186ad60b0fc270a398d4dd499 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87782/805831/libpng-1.6.8.563850-windows-563850.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107513/937823/libpng-1.6.38.576621-windows-576621.tar.bz2 name windows @@ -1454,16 +1454,16 @@ archive hash - ce46aa0f171d97626c4a3940347cecd7 + 7c6bfcdb0d6162587cdbc436f595dd02 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/87780/805832/libpng-1.6.8.563850-windows64-563850.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107512/937822/libpng-1.6.38.576621-windows64-576621.tar.bz2 name windows64 version - 1.6.8.563850 + 1.6.38.576621 libuuid -- cgit v1.2.3 From 5f44c2a5ffacc04e383635840f50ad3ddcf69dd4 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 17 Nov 2022 00:41:35 +0200 Subject: SL-15869 Do not account for login menu when checking if key combination is avaliable Ex: Allow mapping actions to Ctrl+Alt+D --- indra/newview/llkeyconflict.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp index d3ba18525b..60f8aca94c 100644 --- a/indra/newview/llkeyconflict.cpp +++ b/indra/newview/llkeyconflict.cpp @@ -171,8 +171,9 @@ bool LLKeyConflictHandler::isReservedByMenu(const KEY &key, const MASK &mask) { return false; } - return (gMenuBarView && gMenuBarView->hasAccelerator(key, mask)) - || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(key, mask)); + // At the moment controls are only applicable inworld, + // ignore gLoginMenuBarView + return gMenuBarView && gMenuBarView->hasAccelerator(key, mask); } // static @@ -182,8 +183,7 @@ bool LLKeyConflictHandler::isReservedByMenu(const LLKeyData &data) { return false; } - return (gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask)) - || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask)); + return gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask); } bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask) -- cgit v1.2.3 From a8ded3bcc4703803f738df14a665016aa20d03a2 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 18 Nov 2022 14:43:54 +0200 Subject: SL-17135 Pull in apr-suit package Same apr suit version, but with debug symbols --- autobuild.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/autobuild.xml b/autobuild.xml index f363b76706..ae63d08f93 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -52,9 +52,9 @@ archive hash - b6357ef3a0ec37877a5831820f25094e + 178b16ee9ff67986c8c14413ee68218e url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80557/759704/apr_suite-1.4.5.558565-darwin64-558565.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107593/938535/apr_suite-1.4.5.576669-darwin64-576669.tar.bz2 name darwin64 @@ -76,9 +76,9 @@ archive hash - cb48ac069440f6dcd564cfa9fd02a4c2 + d2997cad03dbd0d70a060276b5671480 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80556/759710/apr_suite-1.4.5.558565-windows-558565.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107594/938548/apr_suite-1.4.5.576669-windows-576669.tar.bz2 name windows @@ -88,16 +88,16 @@ archive hash - 646dc3828d9c39fb1e77c4eec44ed739 + ec24f5945faa8f13807b83eeaeb994f8 url - https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/80555/759709/apr_suite-1.4.5.558565-windows64-558565.tar.bz2 + https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/107592/938547/apr_suite-1.4.5.576669-windows64-576669.tar.bz2 name windows64 version - 1.4.5.558565 + 1.4.5.576669 boost -- cgit v1.2.3 From e231b6d8d3bf3d65d94054e6259e5d33d24e5425 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 22 Nov 2022 01:43:14 +0200 Subject: SL-18689 Crash at LLTabContainer::selectNextTab() FPE_NOOP at "idx = (idx + 1 ) % (S32)mTabList.size();" --- indra/llui/lltabcontainer.cpp | 5 +++++ indra/newview/llstartup.cpp | 2 -- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 0aa7a2d217..8c841540a5 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -1442,6 +1442,11 @@ void LLTabContainer::selectLastTab() void LLTabContainer::selectNextTab() { + if (mTabList.size() == 0) + { + return; + } + BOOL tab_has_focus = FALSE; if (mCurrentTabIdx >= 0 && mTabList[mCurrentTabIdx]->mButton->hasFocus()) { diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 054e9530d4..f2d73a4043 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -272,12 +272,10 @@ void show_first_run_dialog(); bool first_run_dialog_callback(const LLSD& notification, const LLSD& response); void set_startup_status(const F32 frac, const std::string& string, const std::string& msg); bool login_alert_status(const LLSD& notification, const LLSD& response); -void login_packet_failed(void**, S32 result); void use_circuit_callback(void**, S32 result); void register_viewer_callbacks(LLMessageSystem* msg); void asset_callback_nothing(const LLUUID&, LLAssetType::EType, void*, S32); bool callback_choose_gender(const LLSD& notification, const LLSD& response); -void init_start_screen(S32 location_id); void release_start_screen(); void reset_login(); LLSD transform_cert_args(LLPointer cert); -- cgit v1.2.3 From 87664fa35de33a8db00dd61ba91f5dc73afce14a Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 22 Nov 2022 23:08:47 +0200 Subject: SL-18219 Crash getting and sending render info on exit There might be other causes for sendRenderInfoToRegion and getRenderInfoFromRegion, crashing, but in some cases viewer was shutting down --- indra/newview/llappviewer.cpp | 3 ++- indra/newview/llavatarrenderinfoaccountant.cpp | 3 +-- indra/newview/llscenemonitor.cpp | 2 +- indra/newview/llscenemonitor.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 5d509fa4ff..f307bdf2e8 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -1730,7 +1730,8 @@ bool LLAppViewer::cleanup() { if (!isSecondInstance()) { - LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv")); + std::string dump_path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"); + LLSceneMonitor::instance().dumpToFile(dump_path); } LLSceneMonitor::deleteSingleton(); } diff --git a/indra/newview/llavatarrenderinfoaccountant.cpp b/indra/newview/llavatarrenderinfoaccountant.cpp index 275f17b02a..293c9d60a1 100644 --- a/indra/newview/llavatarrenderinfoaccountant.cpp +++ b/indra/newview/llavatarrenderinfoaccountant.cpp @@ -364,11 +364,10 @@ void LLAvatarRenderInfoAccountant::getRenderInfoFromRegion(LLViewerRegion * regi } } -// static // Called every frame - send render weight requests to every region void LLAvatarRenderInfoAccountant::idle() { - if (mRenderInfoScanTimer.hasExpired()) + if (mRenderInfoScanTimer.hasExpired() && !LLApp::isExiting()) { LL_DEBUGS("AvatarRenderInfo") << "Scanning regions for render info updates" << LL_ENDL; diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 2e44dc1459..7089df677e 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -515,7 +515,7 @@ void LLSceneMonitor::fetchQueryResult() } //dump results to a file _scene_xmonitor_results.csv -void LLSceneMonitor::dumpToFile(std::string file_name) +void LLSceneMonitor::dumpToFile(const std::string &file_name) { if (!hasResults()) return; diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h index 7cd531bd34..f2e1ef69b9 100644 --- a/indra/newview/llscenemonitor.h +++ b/indra/newview/llscenemonitor.h @@ -61,7 +61,7 @@ public: bool needsUpdate() const; const LLTrace::ExtendablePeriodicRecording* getRecording() const {return &mSceneLoadRecording;} - void dumpToFile(std::string file_name); + void dumpToFile(const std::string &file_name); bool hasResults() const { return mSceneLoadRecording.getResults().getDuration() != S32Seconds(0);} void reset(); -- cgit v1.2.3 From cfc2d2890e02898199337f46f364edc2fd3efcf8 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko <118780484+maxim-productengine@users.noreply.github.com> Date: Thu, 1 Dec 2022 02:04:04 +0200 Subject: SL-18243 Add wear and unwear buttons on line items in Outfits floater --- indra/newview/llinventorylistitem.h | 2 +- indra/newview/llwearableitemslist.cpp | 101 +++++++++++++++++++-- indra/newview/llwearableitemslist.h | 23 ++++- .../skins/default/textures/icons/add_icon.png | Bin 0 -> 3386 bytes .../skins/default/textures/icons/remove_icon.png | Bin 0 -> 3446 bytes indra/newview/skins/default/textures/textures.xml | 3 + .../skins/default/xui/en/outfit_accordion_tab.xml | 1 + .../skins/default/xui/en/panel_outfits_wearing.xml | 1 + .../xui/en/widgets/wearable_outfit_list_item.xml | 64 +++++++++++++ 9 files changed, 183 insertions(+), 12 deletions(-) create mode 100644 indra/newview/skins/default/textures/icons/add_icon.png create mode 100644 indra/newview/skins/default/textures/icons/remove_icon.png create mode 100644 indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h index d4dd212cc3..cf713a6930 100644 --- a/indra/newview/llinventorylistitem.h +++ b/indra/newview/llinventorylistitem.h @@ -197,6 +197,7 @@ protected: virtual BOOL handleToolTip( S32 x, S32 y, MASK mask); const LLUUID mInventoryItemUUID; + bool mHovered; private: @@ -221,7 +222,6 @@ private: LLUIImagePtr mSelectedImage; LLUIImagePtr mSeparatorImage; - bool mHovered; bool mSelected; bool mSeparatorVisible; diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp index bf4db81475..89b74ae962 100644 --- a/indra/newview/llwearableitemslist.cpp +++ b/indra/newview/llwearableitemslist.cpp @@ -92,17 +92,77 @@ LLPanelWearableListItem::LLPanelWearableListItem(LLViewerInventoryItem* item, co ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// +static LLWidgetNameRegistry::StaticRegistrar sRegisterPanelWearableOutfitItem(&typeid(LLPanelWearableOutfitItem::Params), "wearable_outfit_list_item"); + +LLPanelWearableOutfitItem::Params::Params() +: add_btn("add_btn"), + remove_btn("remove_btn") +{ +} + +BOOL LLPanelWearableOutfitItem::postBuild() +{ + LLPanelWearableListItem::postBuild(); + + LLViewerInventoryItem* inv_item = getItem(); + mShowWidgets &= (inv_item->getType() != LLAssetType::AT_BODYPART); + if(mShowWidgets) + { + addWidgetToRightSide("add_wearable"); + addWidgetToRightSide("remove_wearable"); + + childSetAction("add_wearable", boost::bind(&LLPanelWearableOutfitItem::onAddWearable, this)); + childSetAction("remove_wearable", boost::bind(&LLPanelWearableOutfitItem::onRemoveWearable, this)); + + setWidgetsVisible(false); + reshapeWidgets(); + } + return TRUE; +} + +BOOL LLPanelWearableOutfitItem::handleDoubleClick(S32 x, S32 y, MASK mask) +{ + if(!mShowWidgets) + { + return LLPanelWearableListItem::handleDoubleClick(x, y, mask); + } + + if(LLAppearanceMgr::instance().isLinkedInCOF(mInventoryItemUUID)) + { + onRemoveWearable(); + } + else + { + onAddWearable(); + } + return TRUE; +} + +void LLPanelWearableOutfitItem::onAddWearable() +{ + setWidgetsVisible(false); + reshapeWidgets(); + LLAppearanceMgr::instance().wearItemOnAvatar(mInventoryItemUUID, true, false); +} + +void LLPanelWearableOutfitItem::onRemoveWearable() +{ + setWidgetsVisible(false); + reshapeWidgets(); + LLAppearanceMgr::instance().removeItemFromAvatar(mInventoryItemUUID); +} // static LLPanelWearableOutfitItem* LLPanelWearableOutfitItem::create(LLViewerInventoryItem* item, - bool worn_indication_enabled) + bool worn_indication_enabled, + bool show_widgets) { LLPanelWearableOutfitItem* list_item = NULL; if (item) { - const LLPanelInventoryListItemBase::Params& params = LLUICtrlFactory::getDefaultParams(); + const LLPanelWearableOutfitItem::Params& params = LLUICtrlFactory::getDefaultParams(); - list_item = new LLPanelWearableOutfitItem(item, worn_indication_enabled, params); + list_item = new LLPanelWearableOutfitItem(item, worn_indication_enabled, params, show_widgets); list_item->initFromParams(params); list_item->postBuild(); } @@ -110,11 +170,23 @@ LLPanelWearableOutfitItem* LLPanelWearableOutfitItem::create(LLViewerInventoryIt } LLPanelWearableOutfitItem::LLPanelWearableOutfitItem(LLViewerInventoryItem* item, - bool worn_indication_enabled, - const LLPanelWearableOutfitItem::Params& params) -: LLPanelInventoryListItemBase(item, params) + bool worn_indication_enabled, + const LLPanelWearableOutfitItem::Params& params, + bool show_widgets) +: LLPanelWearableListItem(item, params) , mWornIndicationEnabled(worn_indication_enabled) +, mShowWidgets(show_widgets) { + if(mShowWidgets) + { + LLButton::Params button_params = params.add_btn; + applyXUILayout(button_params, this); + addChild(LLUICtrlFactory::create(button_params)); + + button_params = params.remove_btn; + applyXUILayout(button_params, this); + addChild(LLUICtrlFactory::create(button_params)); + } } // virtual @@ -127,11 +199,22 @@ void LLPanelWearableOutfitItem::updateItem(const std::string& name, // We don't use get_is_item_worn() here because this update is triggered by // an inventory observer upon link in COF beind added or removed so actual // worn status of a linked item may still remain unchanged. - if (mWornIndicationEnabled && LLAppearanceMgr::instance().isLinkedInCOF(mInventoryItemUUID)) + bool is_worn = LLAppearanceMgr::instance().isLinkedInCOF(mInventoryItemUUID); + if (mWornIndicationEnabled && is_worn) { search_label += LLTrans::getString("worn"); item_state = IS_WORN; } + if(mShowWidgets) + { + setShowWidget("add_wearable", !is_worn); + setShowWidget("remove_wearable", is_worn); + if(mHovered) + { + setWidgetsVisible(true); + reshapeWidgets(); + } + } LLPanelInventoryListItemBase::updateItem(search_label, item_state); } @@ -634,6 +717,7 @@ static const LLDefaultChildRegistry::Register r("wearable_i LLWearableItemsList::Params::Params() : standalone("standalone", true) , worn_indication_enabled("worn_indication_enabled", true) +, show_item_widgets("show_item_widgets", false) {} LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p) @@ -649,6 +733,7 @@ LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p) } mWornIndicationEnabled = p.worn_indication_enabled; setNoItemsCommentText(LLTrans::getString("LoadingData")); + mShowItemWidgets = p.show_item_widgets; } // virtual @@ -665,7 +750,7 @@ LLPanel* LLWearableItemsList::createNewItem(LLViewerInventoryItem* item) return NULL; } - return LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled); + return LLPanelWearableOutfitItem::create(item, mWornIndicationEnabled, mShowItemWidgets); } void LLWearableItemsList::updateList(const LLUUID& category_id) diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h index ba8488b237..f7774a7086 100644 --- a/indra/newview/llwearableitemslist.h +++ b/indra/newview/llwearableitemslist.h @@ -72,12 +72,23 @@ protected: * Extends LLPanelInventoryListItemBase with handling * double click to wear the item. */ -class LLPanelWearableOutfitItem : public LLPanelInventoryListItemBase +class LLPanelWearableOutfitItem : public LLPanelWearableListItem { LOG_CLASS(LLPanelWearableOutfitItem); public: + struct Params : public LLInitParam::Block + { + Optional add_btn, remove_btn; + + Params(); + }; + + BOOL postBuild(); + BOOL handleDoubleClick(S32 x, S32 y, MASK mask); + static LLPanelWearableOutfitItem* create(LLViewerInventoryItem* item, - bool worn_indication_enabled); + bool worn_indication_enabled, + bool show_widgets); /** * Updates item name and (worn) suffix. @@ -85,12 +96,16 @@ public: /*virtual*/ void updateItem(const std::string& name, EItemState item_state = IS_DEFAULT); + void onAddWearable(); + void onRemoveWearable(); + protected: LLPanelWearableOutfitItem(LLViewerInventoryItem* item, - bool worn_indication_enabled, const Params& params); + bool worn_indication_enabled, const Params& params, bool show_widgets = false); private: bool mWornIndicationEnabled; + bool mShowWidgets; }; class LLPanelDeletableWearableListItem : public LLPanelWearableListItem @@ -442,6 +457,7 @@ public: { Optional standalone; Optional worn_indication_enabled; + Optional show_item_widgets; Params(); }; @@ -482,6 +498,7 @@ protected: bool mIsStandalone; bool mWornIndicationEnabled; + bool mShowItemWidgets; ESortOrder mSortOrder; diff --git a/indra/newview/skins/default/textures/icons/add_icon.png b/indra/newview/skins/default/textures/icons/add_icon.png new file mode 100644 index 0000000000..cb68ee8e16 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/add_icon.png differ diff --git a/indra/newview/skins/default/textures/icons/remove_icon.png b/indra/newview/skins/default/textures/icons/remove_icon.png new file mode 100644 index 0000000000..6e62ee33f4 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/remove_icon.png differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index 4429a1677e..1f2c0867c4 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -743,6 +743,9 @@ with the same filename but different name + + + diff --git a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml index 2a24c74feb..d74dca8b95 100644 --- a/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml +++ b/indra/newview/skins/default/xui/en/outfit_accordion_tab.xml @@ -18,6 +18,7 @@ follows="all" keep_one_selected="true" multi_select="true" + show_item_widgets="true" name="wearable_items_list" translate="false" standalone="false" diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml index 42a7974316..b2dc975c6e 100644 --- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml +++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml @@ -36,6 +36,7 @@ left="3" multi_select="true" name="cof_items_list" + show_item_widgets="true" standalone="false" top="0" width="309" diff --git a/indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml b/indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml new file mode 100644 index 0000000000..cd84b91b1f --- /dev/null +++ b/indra/newview/skins/default/xui/en/widgets/wearable_outfit_list_item.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + -- cgit v1.2.3 From 112446804de888eef73f9f655d7c911da2d0a638 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Sat, 3 Dec 2022 03:04:01 +0200 Subject: SL-18486 Complete Avatars floater is blank. --- indra/newview/llfloateravatar.cpp | 14 +++++++++----- indra/newview/llfloateravatar.h | 3 +++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/indra/newview/llfloateravatar.cpp b/indra/newview/llfloateravatar.cpp index 31adf5b61e..f888d032ae 100644 --- a/indra/newview/llfloateravatar.cpp +++ b/indra/newview/llfloateravatar.cpp @@ -44,17 +44,21 @@ LLFloaterAvatar::LLFloaterAvatar(const LLSD& key) LLFloaterAvatar::~LLFloaterAvatar() { - LLMediaCtrl* avatar_picker = findChild("avatar_picker_contents"); - if (avatar_picker) + if (mAvatarPicker) { - avatar_picker->navigateStop(); - avatar_picker->clearCache(); //images are reloading each time already - avatar_picker->unloadMediaSource(); + mAvatarPicker->navigateStop(); + mAvatarPicker->clearCache(); //images are reloading each time already + mAvatarPicker->unloadMediaSource(); } } BOOL LLFloaterAvatar::postBuild() { + mAvatarPicker = findChild("avatar_picker_contents"); + if (mAvatarPicker) + { + mAvatarPicker->clearCache(); + } enableResizeCtrls(true, true, false); return TRUE; } diff --git a/indra/newview/llfloateravatar.h b/indra/newview/llfloateravatar.h index cadc5e4028..76e9372709 100644 --- a/indra/newview/llfloateravatar.h +++ b/indra/newview/llfloateravatar.h @@ -29,6 +29,7 @@ #define LL_FLOATER_AVATAR_H #include "llfloater.h" +class LLMediaCtrl; class LLFloaterAvatar: public LLFloater @@ -38,6 +39,8 @@ private: LLFloaterAvatar(const LLSD& key); /*virtual*/ ~LLFloaterAvatar(); /*virtual*/ BOOL postBuild(); + + LLMediaCtrl* mAvatarPicker; }; #endif -- cgit v1.2.3 From f7010e46af4205f2f14e07ee5d70c144e44aa7a5 Mon Sep 17 00:00:00 2001 From: akleshchev <117672381+akleshchev@users.noreply.github.com> Date: Tue, 6 Dec 2022 04:37:07 +0200 Subject: SL-18778 Crash at LLVoiceClient::removeObserver (#25) --- indra/newview/llspeakingindicatormanager.cpp | 20 ++++++++++++++------ indra/newview/llvoiceclient.cpp | 15 ++++++++++++--- indra/newview/llvoiceclient.h | 2 -- indra/newview/llvoicevivox.cpp | 5 ----- indra/newview/llvoicevivox.h | 2 -- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp index 5ca1d4b4a5..0111d8869c 100644 --- a/indra/newview/llspeakingindicatormanager.cpp +++ b/indra/newview/llspeakingindicatormanager.cpp @@ -51,6 +51,10 @@ class SpeakingIndicatorManager : public LLSingleton, L LLSINGLETON(SpeakingIndicatorManager); ~SpeakingIndicatorManager(); LOG_CLASS(SpeakingIndicatorManager); + +protected: + void cleanupSingleton(); + public: /** @@ -183,12 +187,16 @@ SpeakingIndicatorManager::SpeakingIndicatorManager() SpeakingIndicatorManager::~SpeakingIndicatorManager() { - // Don't use LLVoiceClient::getInstance() here without check - // singleton MAY have already been destroyed. - if(LLVoiceClient::instanceExists()) - { - LLVoiceClient::getInstance()->removeObserver(this); - } +} + +void SpeakingIndicatorManager::cleanupSingleton() +{ + // Don't use LLVoiceClient::getInstance() here without a check, + // singleton MAY have already been destroyed. + if (LLVoiceClient::instanceExists()) + { + LLVoiceClient::getInstance()->removeObserver(this); + } } void SpeakingIndicatorManager::sOnCurrentChannelChanged(const LLUUID& /*session_id*/) diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp index 2ef2d66f18..6bb987ede4 100644 --- a/indra/newview/llvoiceclient.cpp +++ b/indra/newview/llvoiceclient.cpp @@ -797,7 +797,10 @@ void LLVoiceClient::addObserver(LLVoiceClientStatusObserver* observer) void LLVoiceClient::removeObserver(LLVoiceClientStatusObserver* observer) { - if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer); + if (mVoiceModule) + { + mVoiceModule->removeObserver(observer); + } } void LLVoiceClient::addObserver(LLFriendObserver* observer) @@ -807,7 +810,10 @@ void LLVoiceClient::addObserver(LLFriendObserver* observer) void LLVoiceClient::removeObserver(LLFriendObserver* observer) { - if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer); + if (mVoiceModule) + { + mVoiceModule->removeObserver(observer); + } } void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) @@ -817,7 +823,10 @@ void LLVoiceClient::addObserver(LLVoiceClientParticipantObserver* observer) void LLVoiceClient::removeObserver(LLVoiceClientParticipantObserver* observer) { - if (mVoiceModule && mVoiceModule->singletoneInstanceExists()) mVoiceModule->removeObserver(observer); + if (mVoiceModule) + { + mVoiceModule->removeObserver(observer); + } } std::string LLVoiceClient::sipURIFromID(const LLUUID &id) diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h index 246883b611..aa67502908 100644 --- a/indra/newview/llvoiceclient.h +++ b/indra/newview/llvoiceclient.h @@ -122,8 +122,6 @@ public: virtual const LLVoiceVersionInfo& getVersion()=0; - virtual bool singletoneInstanceExists()=0; - ///////////////////// /// @name Tuning //@{ diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp index ac6369e4e2..5a06877c38 100644 --- a/indra/newview/llvoicevivox.cpp +++ b/indra/newview/llvoicevivox.cpp @@ -5217,11 +5217,6 @@ void LLVivoxVoiceClient::declineInvite(std::string &sessionHandle) } } -bool LLVivoxVoiceClient::singletoneInstanceExists() -{ - return LLVivoxVoiceClient::instanceExists(); -} - void LLVivoxVoiceClient::leaveNonSpatialChannel() { LL_DEBUGS("Voice") << "Request to leave spacial channel." << LL_ENDL; diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h index ebc3a62c35..0a785401c1 100644 --- a/indra/newview/llvoicevivox.h +++ b/indra/newview/llvoicevivox.h @@ -73,8 +73,6 @@ public: // Returns true if vivox has successfully logged in and is not in error state virtual bool isVoiceWorking() const; - - virtual bool singletoneInstanceExists(); ///////////////////// /// @name Tuning -- cgit v1.2.3 From ab8dc07630728b3c5dc0a031eef28f5391734242 Mon Sep 17 00:00:00 2001 From: Maxim Nikolenko Date: Mon, 12 Dec 2022 13:13:48 +0200 Subject: SL-18826 limit teleport command usage --- indra/newview/llurldispatcher.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp index a1670351f4..7c92e7ef98 100644 --- a/indra/newview/llurldispatcher.cpp +++ b/indra/newview/llurldispatcher.cpp @@ -263,7 +263,7 @@ public: // inside the app, otherwise a malicious web page could // cause a constant teleport loop. JC LLTeleportHandler() : - LLCommandHandler("teleport", UNTRUSTED_THROTTLE), + LLCommandHandler("teleport", UNTRUSTED_CLICK_ONLY), LLEventAPI("LLTeleportHandler", "Low-level teleport API") { LLEventAPI::add("teleport", -- cgit v1.2.3 From b4dd4271a1317c79aac4cf03a6612523e7a88ce4 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Mon, 12 Dec 2022 20:22:50 +0200 Subject: SL-16874 Added tool tips to buttons displayed by llDialog() --- doc/contributions.txt | 1 + indra/newview/lltoastnotifypanel.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/contributions.txt b/doc/contributions.txt index 04dc507783..f4cb450dd3 100755 --- a/doc/contributions.txt +++ b/doc/contributions.txt @@ -373,6 +373,7 @@ Charlie Sazaland Chaser Zaks BUG-225599 BUG-227485 + SL-16874 Cherry Cheevers ChickyBabes Zuzu Chorazin Allen diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp index 024f25bc98..bf3f4c1e88 100644 --- a/indra/newview/lltoastnotifypanel.cpp +++ b/indra/newview/lltoastnotifypanel.cpp @@ -89,6 +89,7 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog p.name = form_element["name"].asString(); p.label = form_element["text"].asString(); + p.tool_tip = form_element["text"].asString(); p.font = font; p.rect.height = BTN_HEIGHT; p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata)); -- cgit v1.2.3 From 07baa83ef273f41135b886363b34c423a566bffc Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 14 Dec 2022 20:49:56 +0200 Subject: SL-18384 Fix NSException for keyboard handling Affects accent keys for diacritical marks --- indra/llwindow/llopenglview-objc.mm | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/indra/llwindow/llopenglview-objc.mm b/indra/llwindow/llopenglview-objc.mm index 049226db65..7936245744 100644 --- a/indra/llwindow/llopenglview-objc.mm +++ b/indra/llwindow/llopenglview-objc.mm @@ -495,7 +495,12 @@ attributedStringInfo getSegments(NSAttributedString *str) // e.g. OS Window for upload something or Input Window... // mModifiers instance variable is for insertText: or insertText:replacementRange: (by Pell Smit) mModifiers = [theEvent modifierFlags]; - unichar ch = [[theEvent charactersIgnoringModifiers] characterAtIndex:0]; + NSString *str_no_modifiers = [theEvent charactersIgnoringModifiers]; + unichar ch = 0; + if (str_no_modifiers.length) + { + ch = [str_no_modifiers characterAtIndex:0]; + } bool acceptsText = mHasMarkedText ? false : callKeyDown(&eventData, keycode, mModifiers, ch); if (acceptsText && -- cgit v1.2.3 From 6f522084ed859507f13a6b04fe90eceb441f888e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 10 Nov 2022 19:40:57 +0200 Subject: SL-18426 At log in only a part friends reported to chat as online Server sends updates in bulk now, so notify per agent instead of per update --- indra/newview/llcallingcard.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 1ad2157df0..193d368b83 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -719,11 +719,12 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online) // we were tracking someone who went offline deleteTrackingData(); } - } - if(chat_notify) - { - // Look up the name of this agent for the notification - LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload)); + + if(chat_notify) + { + // Look up the name of this agent for the notification + LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload)); + } } mModifyMask |= LLFriendObserver::ONLINE; -- cgit v1.2.3 From 3fd86c2f23e288ec6754be0bf39bc452f6c0f3e1 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 5 Jan 2023 01:34:03 +0200 Subject: SL-18871 Debug setting's description is not scrollable --- indra/newview/llfloatersettingsdebug.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/indra/newview/llfloatersettingsdebug.cpp b/indra/newview/llfloatersettingsdebug.cpp index 25cf8b2bf7..3c7f341613 100644 --- a/indra/newview/llfloatersettingsdebug.cpp +++ b/indra/newview/llfloatersettingsdebug.cpp @@ -208,7 +208,16 @@ void LLFloaterSettingsDebug::updateControl(LLControlVariable* controlp) getChild("setting_name_txt")->setToolTip(controlp->getName()); mComment->setVisible(true); - mComment->setText(controlp->getComment()); + std::string old_text = mComment->getText(); + std::string new_text = controlp->getComment(); + // Don't setText if not nessesary, it will reset scroll + // This is a debug UI that reads from xml, there might + // be use cases where comment changes, but not the name + if (old_text != new_text) + { + mComment->setText(controlp->getComment()); + } + spinner1->setMaxValue(F32_MAX); spinner2->setMaxValue(F32_MAX); spinner3->setMaxValue(F32_MAX); -- cgit v1.2.3 From 73933fe778c5d29bfde2a3055b8ab21e5aa6b598 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 5 Jan 2023 18:21:53 +0200 Subject: SL-18894 The change of 'modify rights' is not recorded in IM history if the user is in DND mode Revert of commit for SL-15401. Messages are supposed to handle 'mute' on their own. --- indra/newview/llcallingcard.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 193d368b83..df79043b00 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -650,8 +650,7 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg) { if(mBuddyInfo.find(agent_id) != mBuddyInfo.end()) { - if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS) - && !gAgent.isDoNotDisturb()) + if (((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^ new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)) { LLSD args; args["NAME"] = LLSLURL("agent", agent_id, "displayname").getSLURLString(); -- cgit v1.2.3 From d6f5e5bc9424b9d45f6eeeca5d894d46dc91b279 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 7 Jan 2023 01:10:22 +0200 Subject: SL-18911 [MAC] My Land Holdings floater crashes when not empty --- indra/newview/llfloaterlandholdings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index 8633fe4e5e..2f13c940ca 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -89,7 +89,7 @@ BOOL LLFloaterLandHoldings::postBuild() LLUIString areastr = getString("area_string"); areastr.setArg("[AREA]", llformat("%d", gAgent.mGroups.at(i).mContribution)); element["columns"][1]["column"] = "area"; - element["columns"][1]["value"] = areastr; + element["columns"][1]["value"] = areastr.getString(); element["columns"][1]["font"] = "SANSSERIF"; grant_list->addElement(element); -- cgit v1.2.3 From 30678472ee9d25a738d71181c2b887f629cae790 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Sat, 7 Jan 2023 18:59:39 +0200 Subject: Revert "SL-18911 [MAC] My Land Holdings floater crashes when not empty" This reverts commit d6f5e5bc9424b9d45f6eeeca5d894d46dc91b279. --- indra/newview/llfloaterlandholdings.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp index 2f13c940ca..8633fe4e5e 100644 --- a/indra/newview/llfloaterlandholdings.cpp +++ b/indra/newview/llfloaterlandholdings.cpp @@ -89,7 +89,7 @@ BOOL LLFloaterLandHoldings::postBuild() LLUIString areastr = getString("area_string"); areastr.setArg("[AREA]", llformat("%d", gAgent.mGroups.at(i).mContribution)); element["columns"][1]["column"] = "area"; - element["columns"][1]["value"] = areastr.getString(); + element["columns"][1]["value"] = areastr; element["columns"][1]["font"] = "SANSSERIF"; grant_list->addElement(element); -- cgit v1.2.3 From 007939f0a76fd2f596d4d4252578af3d30234b33 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 11 Jan 2023 07:44:12 +0200 Subject: SL-18939 Cannot copy inventory folders with copiable links --- indra/newview/llinventorybridge.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 7793b71f56..7a3b913ed5 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -2140,6 +2140,7 @@ bool LLItemBridge::isItemCopyable(bool can_copy_as_link) const static LLCachedControl inventory_linking(gSavedSettings, "InventoryLinking", true); return (can_copy_as_link && inventory_linking) + || (mIsLink && inventory_linking) || item->getPermissions().allowCopyBy(gAgent.getID()); } @@ -2346,6 +2347,12 @@ BOOL LLFolderBridge::isUpToDate() const bool LLFolderBridge::isItemCopyable(bool can_copy_as_link) const { + if (can_copy_as_link && !LLFolderType::lookupIsProtectedType(getPreferredType())) + { + // Can copy and paste unprotected folders as links + return true; + } + // Folders are copyable if items in them are, recursively, copyable. // Get the content of the folder -- cgit v1.2.3 From b3201e75b1908dd5186d6561b6706f2cc07c92c3 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 11 Jan 2023 16:03:33 +0200 Subject: SL-18945 Links have no 'cut' option Links can be drag and dropped so they should be movable via 'cut' as well --- indra/newview/llinventorybridge.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 7a3b913ed5..db347f7096 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -831,6 +831,12 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id, { disabled_items.push_back(std::string("Find Original")); } + + items.push_back(std::string("Cut")); + if (!isItemMovable() || !isItemRemovable()) + { + disabled_items.push_back(std::string("Cut")); + } } else { -- cgit v1.2.3 From 71657b66f99301a602c7915b70b8b395902bf6ac Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Fri, 27 Jan 2023 22:04:11 +0200 Subject: Revert "SL-18581 Don't show the starter avatar toolbar button for NUX" This reverts commit 4d429b7ea31f51f653e0e2ad6b5799a515e28334. --- indra/newview/lltoolbarview.cpp | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp index 752fc6f3f3..01d799dcd5 100644 --- a/indra/newview/lltoolbarview.cpp +++ b/indra/newview/lltoolbarview.cpp @@ -44,7 +44,6 @@ #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 @@ -320,22 +319,6 @@ 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; } -- cgit v1.2.3 From 8d21d29bd7fa038db632ff90fb0e1207d0713ca2 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Thu, 2 Feb 2023 14:33:39 -0500 Subject: Increment viewer version to 6.6.10 following promotion of DRTVWR-570 --- indra/newview/VIEWER_VERSION.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt index f5199477c5..0673dfa857 100644 --- a/indra/newview/VIEWER_VERSION.txt +++ b/indra/newview/VIEWER_VERSION.txt @@ -1 +1 @@ -6.6.9 +6.6.10 -- cgit v1.2.3