diff --git a/indra/llkdu/llimagej2ckdu.cpp b/indra/llkdu/llimagej2ckdu.cpp index c5904a6e1a..1444e36179 100644 --- a/indra/llkdu/llimagej2ckdu.cpp +++ b/indra/llkdu/llimagej2ckdu.cpp @@ -290,108 +290,123 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // instrument image decodes LLImageDataLock lock(&base); - S32 data_size = base.getDataSize(); - S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); - - // - // Initialization - // - mCodeStreamp.reset(); - - // It's not clear to nat under what circumstances we would reuse a - // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of - // two U32s and a pointer, so it's not as if it would be a huge overhead - // to allocate a new one every time. - // Also -- why is base.getData() tested specifically here? If that returns - // NULL, shouldn't we bail out of the whole method? - if (!mInputp && base.getData()) + try { - // The compressed data has been loaded - // Setup the source for the codestream - mInputp.reset(new LLKDUMemSource(base.getData(), data_size)); - } - if (mInputp) - { - // This is LLKDUMemSource::reset(), not boost::scoped_ptr::reset(). - mInputp->reset(); - } + S32 data_size = base.getDataSize(); + S32 max_bytes = (base.getMaxBytes() ? base.getMaxBytes() : data_size); - mCodeStreamp->create(mInputp.get()); + // + // Initialization + // + mCodeStreamp.reset(); - // Set the maximum number of bytes to use from the codestream - // *TODO: This seems to be wrong. The base class should have no idea of - // how j2c compression works so no good way of computing what's the byte - // range to be used. + // It's not clear to nat under what circumstances we would reuse a + // pre-existing LLKDUMemSource instance. As of 2016-08-05, it consists of + // two U32s and a pointer, so it's not as if it would be a huge overhead + // to allocate a new one every time. + // Also -- why is base.getData() tested specifically here? If that returns + // NULL, shouldn't we bail out of the whole method? + if (!mInputp && base.getData()) + { + // The compressed data has been loaded + // Setup the source for the codestream + mInputp.reset(new LLKDUMemSource(base.getData(), data_size)); + } + + if (mInputp) + { + // This is LLKDUMemSource::reset(), not boost::scoped_ptr::reset(). + mInputp->reset(); + } + + mCodeStreamp->create(mInputp.get()); + + // Set the maximum number of bytes to use from the codestream + // *TODO: This seems to be wrong. The base class should have no idea of + // how j2c compression works so no good way of computing what's the byte + // range to be used. #if (KDU_MAJOR_VERSION*10000 + KDU_MINOR_VERSION*100 + KDU_PATCH_VERSION) >= 80200 - mCodeStreamp->set_max_bytes(max_bytes, false); + mCodeStreamp->set_max_bytes(max_bytes, false); #else - mCodeStreamp->set_max_bytes(max_bytes,true); + mCodeStreamp->set_max_bytes(max_bytes, true); #endif - // If you want to flip or rotate the image for some reason, change - // the resolution, or identify a restricted region of interest, this is - // the place to do it. You may use "kdu_codestream::change_appearance" - // and "kdu_codestream::apply_input_restrictions" for this purpose. - // If you wish to truncate the code-stream prior to decompression, you - // may use "kdu_codestream::set_max_bytes". - // If you wish to retain all compressed data so that the material - // can be decompressed multiple times, possibly with different appearance - // parameters, you should call "kdu_codestream::set_persistent" here. - // There are a variety of other features which must be enabled at - // this point if you want to take advantage of them. See the - // descriptions appearing with the "kdu_codestream" interface functions - // in "kdu_compressed.h" for an itemized account of these capabilities. + // If you want to flip or rotate the image for some reason, change + // the resolution, or identify a restricted region of interest, this is + // the place to do it. You may use "kdu_codestream::change_appearance" + // and "kdu_codestream::apply_input_restrictions" for this purpose. + // If you wish to truncate the code-stream prior to decompression, you + // may use "kdu_codestream::set_max_bytes". + // If you wish to retain all compressed data so that the material + // can be decompressed multiple times, possibly with different appearance + // parameters, you should call "kdu_codestream::set_persistent" here. + // There are a variety of other features which must be enabled at + // this point if you want to take advantage of them. See the + // descriptions appearing with the "kdu_codestream" interface functions + // in "kdu_compressed.h" for an itemized account of these capabilities. - switch (mode) - { - case MODE_FAST: - mCodeStreamp->set_fast(); - break; - case MODE_RESILIENT: - mCodeStreamp->set_resilient(); - break; - case MODE_FUSSY: - mCodeStreamp->set_fussy(); - break; - default: - llassert(0); - mCodeStreamp->set_fast(); - } - - kdu_dims dims; - mCodeStreamp->get_dims(0,dims); - - S32 components = mCodeStreamp->get_num_components(); - - // Check that components have consistent dimensions (for PPM file) - for (int idx = 1; idx < components; ++idx) - { - kdu_dims other_dims; - mCodeStreamp->get_dims(idx, other_dims); - if (other_dims != dims) + switch (mode) { - // This method is only called from methods that catch KDUError. - // We want to fail the image load, not crash the viewer. - LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions " - << stringize(other_dims) - << " do not match component 0 dimensions " - << stringize(dims) << "!"))); + case MODE_FAST: + mCodeStreamp->set_fast(); + break; + case MODE_RESILIENT: + mCodeStreamp->set_resilient(); + break; + case MODE_FUSSY: + mCodeStreamp->set_fussy(); + break; + default: + llassert(0); + mCodeStreamp->set_fast(); + } + + kdu_dims dims; + mCodeStreamp->get_dims(0, dims); + + S32 components = mCodeStreamp->get_num_components(); + + // Check that components have consistent dimensions (for PPM file) + for (int idx = 1; idx < components; ++idx) + { + kdu_dims other_dims; + mCodeStreamp->get_dims(idx, other_dims); + if (other_dims != dims) + { + // This method is only called from methods that catch KDUError. + // We want to fail the image load, not crash the viewer. + LLTHROW(KDUError(STRINGIZE("Component " << idx << " dimensions " + << stringize(other_dims) + << " do not match component 0 dimensions " + << stringize(dims) << "!"))); + } + } + + // Get the number of resolution levels in that image + mLevels = mCodeStreamp->get_min_dwt_levels(); + + // Set the base dimensions + base.setSize(dims.size.x, dims.size.y, components); + base.setLevels(mLevels); + + if (!keep_codestream) + { + mCodeStreamp.reset(); + mInputp.reset(); } } - - // Get the number of resolution levels in that image - mLevels = mCodeStreamp->get_min_dwt_levels(); - - // Set the base dimensions - base.setSize(dims.size.x, dims.size.y, components); - base.setLevels(mLevels); - - if (!keep_codestream) + catch (std::bad_alloc&) { - mCodeStreamp.reset(); - mInputp.reset(); + // we are in a thread, can't show an 'out of memory' here, + // main thread will keep going + throw; + } + catch (...) + { + LLTHROW(KDUError(STRINGIZE("Unknown J2C error : " + + boost::current_exception_diagnostic_information() << "!"))); } } diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 263cbf7840..d9e14d6d70 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -4183,18 +4183,15 @@ void LLWindowWin32::fillCompositionLogfont(LOGFONT *logfont) break; } - // FIRE-34906 (BugSplat) crash when mPreEditor is NULL. (affects at least version 6.6.17->7.1.11) - // logfont->lfHeight = mPreeditor->getPreeditFontSize(); - if(mPreeditor) + if (mPreeditor) { logfont->lfHeight = mPreeditor->getPreeditFontSize(); } else { - // In the absence of other options, use the default font height for monospace. - logfont->lfHeight = LLFontGL::getFontMonospace()->getLineHeight(); + // todo: extract from some font * LLUI::getScaleFactor() intead + logfont->lfHeight = 10; } - // logfont->lfWeight = FW_NORMAL; } diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index cf1dd623e1..442fe4ce75 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 73 +version 74 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 1098134850..b1c2b3cf55 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 53 +version 54 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 8ba3741d79..1d8ebdf6fb 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 72 +version 73 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended diff --git a/indra/newview/gltfscenemanager.cpp b/indra/newview/gltfscenemanager.cpp index b4ab1692c3..38d1cf66a3 100644 --- a/indra/newview/gltfscenemanager.cpp +++ b/indra/newview/gltfscenemanager.cpp @@ -69,9 +69,16 @@ void GLTFSceneManager::load() { return; } - if (filenames.size() > 0) + try { - GLTFSceneManager::instance().load(filenames[0]); + if (filenames.size() > 0) + { + GLTFSceneManager::instance().load(filenames[0]); + } + } + catch (std::bad_alloc&) + { + LLNotificationsUtil::add("CannotOpenFileTooBig"); } }, LLFilePicker::FFLOAD_GLTF, diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp index 583fc934d5..5542a16b2e 100644 --- a/indra/newview/llcallingcard.cpp +++ b/indra/newview/llcallingcard.cpp @@ -516,7 +516,7 @@ void LLAvatarTracker::idleNotifyObservers() void LLAvatarTracker::notifyObservers() { - if (mIsNotifyObservers) + if (mIsNotifyObservers || (LLStartUp::getStartupState() <= STATE_INVENTORY_CALLBACKS)) { // Don't allow multiple calls. // new masks and ids will be processed later from idle. diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 0c70af9475..e85358f6cc 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -260,7 +260,15 @@ void LLDrawable::cleanupReferences() std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); mFaces.clear(); - gPipeline.unlinkDrawable(this); + if (gPipeline.mInitialized) + { + gPipeline.unlinkDrawable(this); + } + else if (getSpatialGroup()) + { + // Not supposed to happen? + getSpatialGroup()->getSpatialPartition()->remove(this, getSpatialGroup()); + } removeFromOctree(); diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp index e3f368bf64..1d70e56d13 100644 --- a/indra/newview/lleventpoll.cpp +++ b/indra/newview/lleventpoll.cpp @@ -116,18 +116,27 @@ namespace Details void LLEventPollImpl::handleMessage(const LLSD& content) { LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; - std::string msg_name = content["message"]; + std::string msg_name = content["message"].asString(); LLSD message; - message["sender"] = mSenderIp; - // Guard against messages with no "body" + try + { + message["sender"] = mSenderIp; + // Guard against messages with no "body" - // message["body"] = content["body"]; + // message["body"] = content["body"]; + + if( content.has( "body" ) ) + message["body"] = content["body"]; + else + LL_WARNS() << "Malformed content? " << ll_pretty_print_sd( content ) << LL_ENDL; + // + } + catch (std::bad_alloc&) + { + LLError::LLUserWarningMsg::showOutOfMemory(); + LL_ERRS("LLCoros") << "Bad memory allocation on message: " << msg_name << LL_ENDL; + } - if( content.has( "body" ) ) - message["body"] = content["body"]; - else - LL_WARNS() << "Malformed content? " << ll_pretty_print_sd( content ) << LL_ENDL; - // LLMessageSystem::dispatch(msg_name, message); } diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index e8af21ac23..5f522b035c 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -689,11 +689,15 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) // do not create a new material, reuse existing pointer // so that mTextureEntires remains untouched LLGLTFMaterial* render_mat = entry->getGLTFRenderMaterial(); - if (render_mat) + if (render_mat && render_mat != mat) { *render_mat = *mat; render_mat->applyOverride(*override_mat); // can update mGLTFMaterialWithLocalTextures } + else + { + LL_WARNS() << "A TE had an override, but no render material" << LL_ENDL; + } } } } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index da8f06e875..9df85051e8 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2866,9 +2866,16 @@ void LLMaterialEditor::importMaterial() { return; } - if (filenames.size() > 0) + try { - LLMaterialEditor::loadMaterialFromFile(filenames[0], -1); + if (filenames.size() > 0) + { + LLMaterialEditor::loadMaterialFromFile(filenames[0], -1); + } + } + catch (std::bad_alloc&) + { + LLNotificationsUtil::add("CannotOpenFileTooBig"); } }, LLFilePicker::FFLOAD_MATERIAL, diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 79a2eaa471..ed1e92670e 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -7759,7 +7759,7 @@ void LLSelectMgr::updatePointAt() LLVector3 select_offset; const LLPickInfo& pick = gViewerWindow->getLastPick(); LLViewerObject *click_object = pick.getObject(); - bool was_hud = pick.mPickHUD && !click_object->isHUDAttachment(); + bool was_hud = pick.mPickHUD && click_object && !click_object->isHUDAttachment(); if (click_object && click_object->isSelected() && !was_hud) { // clicked on another object in our selection group, use that as target diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp index a8e9d7c1b4..1c08f60e91 100644 --- a/indra/newview/lltoast.cpp +++ b/indra/newview/lltoast.cpp @@ -458,6 +458,14 @@ void LLToast::setVisible(bool show) void LLToast::updateHoveredState() { + if (!mWrapperPanel) + { + // Shouldn't be happening. + // mWrapperPanel should have been inited in the constructor + // This needs to be figured out and fixed + llassert(false); + return; + } S32 x, y; LLUI::getInstance()->getMousePositionScreen(&x, &y); diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 5051698e22..18be18a3d6 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -569,10 +569,9 @@ public: U32 renderTransparent(bool first_pass); void renderCollisionVolumes(); void renderBones(const std::string &selected_joint = std::string()); + virtual void renderJoints(); void renderOnlySelectedBones(const std::vector &selected_joints); void renderBoxAroundJointAttachments(LLJoint * joint); - - void renderJoints(); static void deleteCachedImages(bool clearAll=true); static void destroyGL(); static void restoreGL(); diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp index 97f50c39cd..bd0405e37f 100644 --- a/indra/newview/llvoavatarself.cpp +++ b/indra/newview/llvoavatarself.cpp @@ -1032,6 +1032,7 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time) LLJoint *LLVOAvatarSelf::getJoint( const JointKey &name ) // { + std::lock_guard lock(mJointMapMutex); LLJoint *jointp = NULL; jointp = LLVOAvatar::getJoint(name); if (!jointp && mScreenp) @@ -1055,6 +1056,14 @@ LLJoint *LLVOAvatarSelf::getJoint( const JointKey &name ) return jointp; } + +//virtual +void LLVOAvatarSelf::renderJoints() +{ + std::lock_guard lock(mJointMapMutex); + LLVOAvatar::renderJoints(); +} + // virtual // [Legacy Bake] //bool LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight) diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h index 17dde9e621..de8a435be9 100644 --- a/indra/newview/llvoavatarself.h +++ b/indra/newview/llvoavatarself.h @@ -96,6 +96,8 @@ public: /*virtual*/ LLJoint* getJoint( const JointKey &name ); // + /*virtual*/ void renderJoints(); + // [Legacy Bake] ///*virtual*/ bool setVisualParamWeight(const LLVisualParam *which_param, F32 weight); ///*virtual*/ bool setVisualParamWeight(const char* param_name, F32 weight); @@ -122,6 +124,8 @@ private: //bool setParamWeight(const LLViewerVisualParam *param, F32 weight); bool setParamWeight(const LLViewerVisualParam *param, F32 weight, bool upload_bake = false); + std::mutex mJointMapMutex; // getJoint gets used from mesh thread + /******************************************************************************** ** ** ** STATE diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml index 5706b2e684..44f8cf3ba5 100644 --- a/indra/newview/skins/default/xui/de/notifications.xml +++ b/indra/newview/skins/default/xui/de/notifications.xml @@ -953,6 +953,11 @@ Die Datei ist möglicherweise zu groß. Versuchen Sie, die Auflösung oder Quali Schnappschuss nicht hochgeladen werden. Die Datei ist möglicherweise zu groß. Versuchen Sie, die Auflösung zu verringern oder versuchen Sie es erneut. + + + Datei kann nicht geöffnet werden. + +Dem Viewer ist beim Öffnen der Datei der Speicher ausgegangen. Die Datei ist vermutlich zu groß. „[LANDMARK_NAME]“ wurde zum Ordner „[FOLDER_NAME]“ hinzugefügt. diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 86cf61f4dc..01a253b83d 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -2503,6 +2503,16 @@ Unable to upload snapshot. File might be too big, try reducing resolution or try again later. fail + + +Unable to open file. + +Viewer ran out of memory while opening file. File might be too big. + fail +