Merge branch 'release/2025.03' of https://github.com/secondlife/viewer

# Conflicts:
#	indra/llkdu/llimagej2ckdu.cpp
#	indra/llwindow/llwindowwin32.cpp
#	indra/newview/lleventpoll.cpp
#	indra/newview/llvoavatar.h
#	indra/newview/llvoavatarself.h
master
Ansariel 2025-04-10 18:28:30 +02:00
commit 3f1373de4c
18 changed files with 198 additions and 116 deletions

View File

@ -290,108 +290,123 @@ void LLImageJ2CKDU::setupCodeStream(LLImageJ2C &base, bool keep_codestream, ECod
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // <FS:Beq> 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() << "!")));
}
}

View File

@ -4183,18 +4183,15 @@ void LLWindowWin32::fillCompositionLogfont(LOGFONT *logfont)
break;
}
// <FS:Beq> 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;
}
// </FS:Beq>
logfont->lfWeight = FW_NORMAL;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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.

View File

@ -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();

View File

@ -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;
// <FS:ND> Guard against messages with no "body"
try
{
message["sender"] = mSenderIp;
// <FS:ND> 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;
// <FS:ND>
}
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;
// <FS:ND>
LLMessageSystem::dispatch(msg_name, message);
}

View File

@ -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;
}
}
}
}

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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<std::string> &selected_joints);
void renderBoxAroundJointAttachments(LLJoint * joint);
void renderJoints();
static void deleteCachedImages(bool clearAll=true);
static void destroyGL();
static void restoreGL();

View File

@ -1032,6 +1032,7 @@ void LLVOAvatarSelf::idleUpdate(LLAgent &agent, const F64 &time)
LLJoint *LLVOAvatarSelf::getJoint( const JointKey &name )
// </FS:ND>
{
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
// <FS:Ansariel> [Legacy Bake]
//bool LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight)

View File

@ -96,6 +96,8 @@ public:
/*virtual*/ LLJoint* getJoint( const JointKey &name );
// </FS:ND>
/*virtual*/ void renderJoints();
// <FS:Ansariel> [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

View File

@ -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.
</notification>
<notification name="CannotOpenFileTooBig">
Datei kann nicht geöffnet werden.
Dem Viewer ist beim Öffnen der Datei der Speicher ausgegangen. Die Datei ist vermutlich zu groß.
</notification>
<notification name="LandmarkCreated">
„[LANDMARK_NAME]“ wurde zum Ordner „[FOLDER_NAME]“ hinzugefügt.

View File

@ -2503,6 +2503,16 @@ Unable to upload snapshot.
File might be too big, try reducing resolution or try again later.
<tag>fail</tag>
</notification>
<notification
icon="alertmodal.tga"
name="CannotOpenFileTooBig"
type="alertmodal">
Unable to open file.
Viewer ran out of memory while opening file. File might be too big.
<tag>fail</tag>
</notification>
<notification
icon="notifytip.tga"