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.hmaster
commit
3f1373de4c
|
|
@ -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() << "!")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue