Merge branch 'release/2025.08' of https://github.com/secondlife/viewer
# Conflicts: # indra/newview/llfloatermarketplace.cpp # indra/newview/llviewermessage.cpp # indra/newview/skins/default/xui/en/panel_preferences_move.xmlmaster
commit
51f7e7a7d7
|
|
@ -80,7 +80,7 @@ void LLQueuedThread::shutdown()
|
||||||
mRequestQueue.close();
|
mRequestQueue.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
S32 timeout = 100;
|
S32 timeout = 50;
|
||||||
for ( ; timeout>0; timeout--)
|
for ( ; timeout>0; timeout--)
|
||||||
{
|
{
|
||||||
if (isStopped())
|
if (isStopped())
|
||||||
|
|
@ -101,19 +101,34 @@ void LLQueuedThread::shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
QueuedRequest* req;
|
QueuedRequest* req;
|
||||||
S32 active_count = 0;
|
S32 queued_count = 0;
|
||||||
|
bool has_active = false;
|
||||||
|
lockData();
|
||||||
while ( (req = (QueuedRequest*)mRequestHash.pop_element()) )
|
while ( (req = (QueuedRequest*)mRequestHash.pop_element()) )
|
||||||
{
|
{
|
||||||
if (req->getStatus() == STATUS_QUEUED || req->getStatus() == STATUS_INPROGRESS)
|
if (req->getStatus() == STATUS_INPROGRESS)
|
||||||
{
|
{
|
||||||
++active_count;
|
has_active = true;
|
||||||
|
req->setFlags(FLAG_ABORT | FLAG_AUTO_COMPLETE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (req->getStatus() == STATUS_QUEUED)
|
||||||
|
{
|
||||||
|
++queued_count;
|
||||||
req->setStatus(STATUS_ABORTED); // avoid assert in deleteRequest
|
req->setStatus(STATUS_ABORTED); // avoid assert in deleteRequest
|
||||||
}
|
}
|
||||||
req->deleteRequest();
|
req->deleteRequest();
|
||||||
}
|
}
|
||||||
if (active_count)
|
unlockData();
|
||||||
|
if (queued_count)
|
||||||
{
|
{
|
||||||
LL_WARNS() << "~LLQueuedThread() called with active requests: " << active_count << LL_ENDL;
|
LL_WARNS() << "~LLQueuedThread() called with unpocessed requests: " << queued_count << LL_ENDL;
|
||||||
|
}
|
||||||
|
if (has_active)
|
||||||
|
{
|
||||||
|
LL_WARNS() << "~LLQueuedThread() called with active requests!" << LL_ENDL;
|
||||||
|
ms_sleep(100); // last chance for request to finish
|
||||||
|
printQueueStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
mRequestQueue.close();
|
mRequestQueue.close();
|
||||||
|
|
@ -600,7 +615,12 @@ LLQueuedThread::QueuedRequest::QueuedRequest(LLQueuedThread::handle_t handle, U3
|
||||||
|
|
||||||
LLQueuedThread::QueuedRequest::~QueuedRequest()
|
LLQueuedThread::QueuedRequest::~QueuedRequest()
|
||||||
{
|
{
|
||||||
llassert_always(mStatus == STATUS_DELETE);
|
if (mStatus != STATUS_DELETE)
|
||||||
|
{
|
||||||
|
// The only method to delete a request is deleteRequest(),
|
||||||
|
// it should have set the status to STATUS_DELETE
|
||||||
|
LL_ERRS() << "LLQueuedThread::QueuedRequest deleted with status " << mStatus << LL_ENDL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//virtual
|
//virtual
|
||||||
|
|
|
||||||
|
|
@ -1010,6 +1010,8 @@ void LLPluginProcessParent::poll(F64 timeout)
|
||||||
// </FS:Beq>
|
// </FS:Beq>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (sInstancesMutex)
|
||||||
|
{
|
||||||
// Remove instances in the done state from the sInstances map.
|
// Remove instances in the done state from the sInstances map.
|
||||||
LLCoros::LockType lock(*sInstancesMutex);
|
LLCoros::LockType lock(*sInstancesMutex);
|
||||||
mapInstances_t::iterator itClean = sInstances.begin();
|
mapInstances_t::iterator itClean = sInstances.begin();
|
||||||
|
|
@ -1021,6 +1023,7 @@ void LLPluginProcessParent::poll(F64 timeout)
|
||||||
++itClean;
|
++itClean;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LLPluginProcessParent::servicePoll()
|
void LLPluginProcessParent::servicePoll()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ S32 LLGLSLShader::sIndexedTextureChannels = 0;
|
||||||
U32 LLGLSLShader::sMaxGLTFMaterials = 0;
|
U32 LLGLSLShader::sMaxGLTFMaterials = 0;
|
||||||
U32 LLGLSLShader::sMaxGLTFNodes = 0;
|
U32 LLGLSLShader::sMaxGLTFNodes = 0;
|
||||||
bool LLGLSLShader::sProfileEnabled = false;
|
bool LLGLSLShader::sProfileEnabled = false;
|
||||||
|
bool LLGLSLShader::sCanProfile = true;
|
||||||
std::set<LLGLSLShader*> LLGLSLShader::sInstances;
|
std::set<LLGLSLShader*> LLGLSLShader::sInstances;
|
||||||
LLGLSLShader::defines_map_t LLGLSLShader::sGlobalDefines;
|
LLGLSLShader::defines_map_t LLGLSLShader::sGlobalDefines;
|
||||||
U64 LLGLSLShader::sTotalTimeElapsed = 0;
|
U64 LLGLSLShader::sTotalTimeElapsed = 0;
|
||||||
|
|
@ -267,7 +268,7 @@ void LLGLSLShader::placeProfileQuery(bool for_runtime)
|
||||||
|
|
||||||
bool LLGLSLShader::readProfileQuery(bool for_runtime, bool force_read)
|
bool LLGLSLShader::readProfileQuery(bool for_runtime, bool force_read)
|
||||||
{
|
{
|
||||||
if (sProfileEnabled || for_runtime)
|
if ((sProfileEnabled || for_runtime) && sCanProfile)
|
||||||
{
|
{
|
||||||
if (!mProfilePending)
|
if (!mProfilePending)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -160,6 +160,7 @@ public:
|
||||||
|
|
||||||
static std::set<LLGLSLShader*> sInstances;
|
static std::set<LLGLSLShader*> sInstances;
|
||||||
static bool sProfileEnabled;
|
static bool sProfileEnabled;
|
||||||
|
static bool sCanProfile;
|
||||||
|
|
||||||
LLGLSLShader();
|
LLGLSLShader();
|
||||||
~LLGLSLShader();
|
~LLGLSLShader();
|
||||||
|
|
|
||||||
|
|
@ -479,7 +479,34 @@ void LLAccordionCtrlTab::onUpdateScrollToChild(const LLUICtrl *cntrl)
|
||||||
// Translate to parent coordinatess to check if we are in visible rectangle
|
// Translate to parent coordinatess to check if we are in visible rectangle
|
||||||
rect.translate(getRect().mLeft, getRect().mBottom);
|
rect.translate(getRect().mLeft, getRect().mBottom);
|
||||||
|
|
||||||
if (!getRect().contains(rect))
|
bool needs_to_scroll = false;
|
||||||
|
const LLRect &acc_rect = getRect();
|
||||||
|
if (!acc_rect.contains(rect))
|
||||||
|
{
|
||||||
|
if (acc_rect.mTop < rect.mBottom || acc_rect.mBottom > rect.mTop)
|
||||||
|
{
|
||||||
|
// Content fully not in view
|
||||||
|
needs_to_scroll = true;
|
||||||
|
}
|
||||||
|
else if (acc_rect.getHeight() >= rect.getHeight())
|
||||||
|
{
|
||||||
|
// Content can be displayed fully, but only partially in view
|
||||||
|
needs_to_scroll = true;
|
||||||
|
}
|
||||||
|
else if (acc_rect.mTop <= rect.mTop || acc_rect.mBottom >= rect.mBottom)
|
||||||
|
{
|
||||||
|
// Intersects, but too big to be displayed fully
|
||||||
|
S32 covered_height = acc_rect.mTop > rect.mTop ? rect.mTop - acc_rect.mBottom : acc_rect.mTop - rect.mBottom;
|
||||||
|
constexpr F32 covered_ratio = 0.7f;
|
||||||
|
if (covered_height < covered_ratio * acc_rect.getHeight())
|
||||||
|
{
|
||||||
|
// Try to show bigger portion of the content
|
||||||
|
needs_to_scroll = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else too big and in the middle of the view as is
|
||||||
|
}
|
||||||
|
if (needs_to_scroll)
|
||||||
{
|
{
|
||||||
// for accordition's scroll, height is in pixels
|
// for accordition's scroll, height is in pixels
|
||||||
// Back to local coords and calculate position for scroller
|
// Back to local coords and calculate position for scroller
|
||||||
|
|
|
||||||
|
|
@ -1184,8 +1184,37 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
|
||||||
static LLUICachedControl<bool> useBWEmojis("FSUseBWEmojis", false); // <FS:Beq/> Add B&W emoji font support
|
static LLUICachedControl<bool> useBWEmojis("FSUseBWEmojis", false); // <FS:Beq/> Add B&W emoji font support
|
||||||
LLStyleSP emoji_style;
|
LLStyleSP emoji_style;
|
||||||
LLEmojiDictionary* ed = LLEmojiDictionary::instanceExists() ? LLEmojiDictionary::getInstance() : NULL;
|
LLEmojiDictionary* ed = LLEmojiDictionary::instanceExists() ? LLEmojiDictionary::getInstance() : NULL;
|
||||||
|
LLTextSegment* segmentp = nullptr;
|
||||||
|
segment_vec_t::iterator seg_iter;
|
||||||
|
if (segments && segments->size() > 0)
|
||||||
|
{
|
||||||
|
seg_iter = segments->begin();
|
||||||
|
segmentp = *seg_iter;
|
||||||
|
}
|
||||||
for (S32 text_kitty = 0, text_len = static_cast<S32>(wstr.size()); text_kitty < text_len; text_kitty++)
|
for (S32 text_kitty = 0, text_len = static_cast<S32>(wstr.size()); text_kitty < text_len; text_kitty++)
|
||||||
{
|
{
|
||||||
|
if (segmentp)
|
||||||
|
{
|
||||||
|
if (segmentp->getEnd() <= pos + text_kitty)
|
||||||
|
{
|
||||||
|
seg_iter++;
|
||||||
|
if (seg_iter != segments->end())
|
||||||
|
{
|
||||||
|
segmentp = *seg_iter;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
segmentp = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (segmentp && !segmentp->getPermitsEmoji())
|
||||||
|
{
|
||||||
|
// Some segments, like LLInlineViewSegment do not permit splitting
|
||||||
|
// and should not be interrupted by emoji segments
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
llwchar code = wstr[text_kitty];
|
llwchar code = wstr[text_kitty];
|
||||||
bool isEmoji = ed ? ed->isEmoji(code) : LLStringOps::isEmoji(code);
|
bool isEmoji = ed ? ed->isEmoji(code) : LLStringOps::isEmoji(code);
|
||||||
if (isEmoji)
|
if (isEmoji)
|
||||||
|
|
@ -3801,6 +3830,7 @@ S32 LLTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offs
|
||||||
void LLTextSegment::updateLayout(const LLTextBase& editor) {}
|
void LLTextSegment::updateLayout(const LLTextBase& editor) {}
|
||||||
F32 LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { return draw_rect.mLeft; }
|
F32 LLTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect) { return draw_rect.mLeft; }
|
||||||
bool LLTextSegment::canEdit() const { return false; }
|
bool LLTextSegment::canEdit() const { return false; }
|
||||||
|
bool LLTextSegment::getPermitsEmoji() const { return true; }
|
||||||
void LLTextSegment::unlinkFromDocument(LLTextBase*) {}
|
void LLTextSegment::unlinkFromDocument(LLTextBase*) {}
|
||||||
void LLTextSegment::linkToDocument(LLTextBase*) {}
|
void LLTextSegment::linkToDocument(LLTextBase*) {}
|
||||||
const LLUIColor& LLTextSegment::getColor() const { static const LLUIColor white = LLUIColorTable::instance().getColor("White", LLColor4::white); return white; }
|
const LLUIColor& LLTextSegment::getColor() const { static const LLUIColor white = LLUIColorTable::instance().getColor("White", LLColor4::white); return white; }
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ public:
|
||||||
virtual void updateLayout(const class LLTextBase& editor);
|
virtual void updateLayout(const class LLTextBase& editor);
|
||||||
virtual F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
|
virtual F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
|
||||||
virtual bool canEdit() const;
|
virtual bool canEdit() const;
|
||||||
|
virtual bool getPermitsEmoji() const;
|
||||||
virtual void unlinkFromDocument(class LLTextBase* editor);
|
virtual void unlinkFromDocument(class LLTextBase* editor);
|
||||||
virtual void linkToDocument(class LLTextBase* editor);
|
virtual void linkToDocument(class LLTextBase* editor);
|
||||||
|
|
||||||
|
|
@ -255,6 +256,7 @@ public:
|
||||||
/*virtual*/ void updateLayout(const class LLTextBase& editor);
|
/*virtual*/ void updateLayout(const class LLTextBase& editor);
|
||||||
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
|
/*virtual*/ F32 draw(S32 start, S32 end, S32 selection_start, S32 selection_end, const LLRectf& draw_rect);
|
||||||
/*virtual*/ bool canEdit() const { return false; }
|
/*virtual*/ bool canEdit() const { return false; }
|
||||||
|
/*virtual*/ bool getPermitsEmoji() const { return false; }
|
||||||
/*virtual*/ void unlinkFromDocument(class LLTextBase* editor);
|
/*virtual*/ void unlinkFromDocument(class LLTextBase* editor);
|
||||||
/*virtual*/ void linkToDocument(class LLTextBase* editor);
|
/*virtual*/ void linkToDocument(class LLTextBase* editor);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -186,7 +186,7 @@ std::map<S32, std::string> LLTeleportRequest::sTeleportStatusName = { { kPending
|
||||||
class LLTeleportRequestViaLandmark : public LLTeleportRequest
|
class LLTeleportRequestViaLandmark : public LLTeleportRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId);
|
LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId, bool log = true);
|
||||||
virtual ~LLTeleportRequestViaLandmark();
|
virtual ~LLTeleportRequestViaLandmark();
|
||||||
|
|
||||||
virtual void toOstream(std::ostream& os) const;
|
virtual void toOstream(std::ostream& os) const;
|
||||||
|
|
@ -198,6 +198,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
inline const LLUUID &getLandmarkId() const {return mLandmarkId;};
|
inline const LLUUID &getLandmarkId() const {return mLandmarkId;};
|
||||||
|
bool mLogOnDestruction = true;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LLUUID mLandmarkId;
|
LLUUID mLandmarkId;
|
||||||
|
|
@ -6157,17 +6158,26 @@ void LLTeleportRequest::toOstream(std::ostream& os) const
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// LLTeleportRequestViaLandmark
|
// LLTeleportRequestViaLandmark
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId)
|
LLTeleportRequestViaLandmark::LLTeleportRequestViaLandmark(const LLUUID &pLandmarkId, bool log)
|
||||||
: LLTeleportRequest(),
|
: LLTeleportRequest()
|
||||||
mLandmarkId(pLandmarkId)
|
, mLandmarkId(pLandmarkId)
|
||||||
|
, mLogOnDestruction(true)
|
||||||
{
|
{
|
||||||
|
if (log)
|
||||||
|
{
|
||||||
|
// Workaround to not log twice for LLTeleportRequestViaLure, besides this wouldn't have logged fully.
|
||||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created, " << *this << LL_ENDL;
|
LL_INFOS("Teleport") << "LLTeleportRequestViaLandmark created, " << *this << LL_ENDL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark()
|
LLTeleportRequestViaLandmark::~LLTeleportRequestViaLandmark()
|
||||||
{
|
{
|
||||||
|
if (mLogOnDestruction)
|
||||||
|
{
|
||||||
|
// Workaround to not crash on toOstream for derived classes and to not log twice.
|
||||||
LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark, " << *this << LL_ENDL;
|
LL_INFOS("Teleport") << "~LLTeleportRequestViaLandmark, " << *this << LL_ENDL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LLTeleportRequestViaLandmark::toOstream(std::ostream& os) const
|
void LLTeleportRequestViaLandmark::toOstream(std::ostream& os) const
|
||||||
{
|
{
|
||||||
|
|
@ -6197,15 +6207,19 @@ void LLTeleportRequestViaLandmark::restartTeleport()
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID& pLureId, bool pIsLureGodLike)
|
LLTeleportRequestViaLure::LLTeleportRequestViaLure(const LLUUID& pLureId, bool pIsLureGodLike)
|
||||||
: LLTeleportRequestViaLandmark(pLureId),
|
: LLTeleportRequestViaLandmark(pLureId, false),
|
||||||
mIsLureGodLike(pIsLureGodLike)
|
mIsLureGodLike(pIsLureGodLike)
|
||||||
{
|
{
|
||||||
LL_INFOS("Teleport") << "LLTeleportRequestViaLure created" << LL_ENDL;
|
LL_INFOS("Teleport") << "LLTeleportRequestViaLure created: " << *this << LL_ENDL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLTeleportRequestViaLure::~LLTeleportRequestViaLure()
|
LLTeleportRequestViaLure::~LLTeleportRequestViaLure()
|
||||||
{
|
{
|
||||||
LL_INFOS("Teleport") << "~LLTeleportRequestViaLure" << LL_ENDL;
|
if (mLogOnDestruction)
|
||||||
|
{
|
||||||
|
LL_INFOS("Teleport") << "~LLTeleportRequestViaLure: " << *this << LL_ENDL;
|
||||||
|
mLogOnDestruction = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LLTeleportRequestViaLure::toOstream(std::ostream& os) const
|
void LLTeleportRequestViaLure::toOstream(std::ostream& os) const
|
||||||
|
|
|
||||||
|
|
@ -245,8 +245,15 @@ namespace
|
||||||
// If marker doesn't exist, create a marker with 'other' code for next launch
|
// If marker doesn't exist, create a marker with 'other' code for next launch
|
||||||
// otherwise don't override existing file
|
// otherwise don't override existing file
|
||||||
// Any unmarked crashes will be considered as freezes
|
// Any unmarked crashes will be considered as freezes
|
||||||
|
if (app->logoutRequestSent())
|
||||||
|
{
|
||||||
|
app->createErrorMarker(LAST_EXEC_LOGOUT_CRASH);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
app->createErrorMarker(LAST_EXEC_OTHER_CRASH);
|
app->createErrorMarker(LAST_EXEC_OTHER_CRASH);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} // MDSCB_EXCEPTIONCODE
|
} // MDSCB_EXCEPTIONCODE
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -409,8 +409,53 @@ F32 logExceptionBenchmark()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool checkRDNA35()
|
||||||
|
{
|
||||||
|
// This checks if we're running on an RDNA3.5 GPU. You're only going to see these on AMD's APUs.
|
||||||
|
// As of driver version 25, we're seeing stalls in some of our queries.
|
||||||
|
// This appears to be a driver bug, and appears to be specific RDNA3.5 APUs.
|
||||||
|
// There's multiples of these guys, so we just use this function to check if that GPU is on the list of known RDNA3.5 APUs.
|
||||||
|
// - Geenz 11/12/2025
|
||||||
|
std::array<std::string, 7> rdna35GPUs = {
|
||||||
|
"8060S",
|
||||||
|
"8050S",
|
||||||
|
"8040S",
|
||||||
|
"860M",
|
||||||
|
"840M",
|
||||||
|
"890M",
|
||||||
|
"880M"
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& gpu_name : rdna35GPUs)
|
||||||
|
{
|
||||||
|
if (gGLManager.getRawGLString().find(gpu_name) != std::string::npos)
|
||||||
|
{
|
||||||
|
LL_WARNS("RenderInit") << "Detected AMD RDNA3.5 GPU (" << gpu_name << ")." << LL_ENDL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool LLFeatureManager::loadGPUClass()
|
bool LLFeatureManager::loadGPUClass()
|
||||||
{
|
{
|
||||||
|
// This is a hack for certain AMD GPUs in newer driver versions on certain APUs.
|
||||||
|
// These GPUs will show inconsistent freezes when attempting to run shader profiles against them.
|
||||||
|
// This is extremely problematic as it can lead to:
|
||||||
|
// - Login freezes
|
||||||
|
// - Inability to start the client
|
||||||
|
// - Completely random avatars triggering a freeze
|
||||||
|
// As a result, we filter out these GPUs for shader profiling.
|
||||||
|
// - Geenz 11/11/2025
|
||||||
|
|
||||||
|
if (gGLManager.getRawGLString().find("Radeon") != std::string::npos && checkRDNA35() && gGLManager.mDriverVersionVendorString.find("25.") != std::string::npos)
|
||||||
|
{
|
||||||
|
LL_WARNS("RenderInit") << "Detected AMD RDNA3.5 GPU on a known bad driver; disabling benchmark and occlusion culling to prevent freezes." << LL_ENDL;
|
||||||
|
gSavedSettings.setBOOL("SkipBenchmark", true);
|
||||||
|
gSavedSettings.setBOOL("UseOcclusion", false);
|
||||||
|
}
|
||||||
|
|
||||||
if (!gSavedSettings.getBOOL("SkipBenchmark"))
|
if (!gSavedSettings.getBOOL("SkipBenchmark"))
|
||||||
{
|
{
|
||||||
F32 class1_gbps = gSavedSettings.getF32("RenderClass1MemoryBandwidth");
|
F32 class1_gbps = gSavedSettings.getF32("RenderClass1MemoryBandwidth");
|
||||||
|
|
|
||||||
|
|
@ -123,6 +123,7 @@ public:
|
||||||
S32 getVersion() const { return mTableVersion; }
|
S32 getVersion() const { return mTableVersion; }
|
||||||
void setSafe(const bool safe) { mSafe = safe; }
|
void setSafe(const bool safe) { mSafe = safe; }
|
||||||
bool isSafe() const { return mSafe; }
|
bool isSafe() const { return mSafe; }
|
||||||
|
bool skipProfiling() const { return mSkipProfiling; }
|
||||||
|
|
||||||
LLFeatureList *findMask(const std::string& name);
|
LLFeatureList *findMask(const std::string& name);
|
||||||
bool maskFeatures(const std::string& name);
|
bool maskFeatures(const std::string& name);
|
||||||
|
|
@ -170,6 +171,7 @@ protected:
|
||||||
F32 mExpectedGLVersion; //expected GL version according to gpu table
|
F32 mExpectedGLVersion; //expected GL version according to gpu table
|
||||||
std::string mGPUString;
|
std::string mGPUString;
|
||||||
bool mGPUSupported;
|
bool mGPUSupported;
|
||||||
|
bool mSkipProfiling = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline
|
inline
|
||||||
|
|
|
||||||
|
|
@ -46,11 +46,9 @@ void LLFloaterMarketplace::onClose(bool app_quitting)
|
||||||
|
|
||||||
bool LLFloaterMarketplace::postBuild()
|
bool LLFloaterMarketplace::postBuild()
|
||||||
{
|
{
|
||||||
LLFloaterWebContent::postBuild();
|
if (!LLFloaterWebContent::postBuild())
|
||||||
// <FS:Ansariel> Already set in LLFloaterWebContent
|
return false;
|
||||||
//mWebBrowser = getChild<LLMediaCtrl>("marketplace_contents");
|
|
||||||
//mWebBrowser->addObserver(this);
|
|
||||||
// </FS:Ansariel>
|
|
||||||
mWebBrowser->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
|
mWebBrowser->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
|
||||||
std::string url = gSavedSettings.getString("MarketplaceURL");
|
std::string url = gSavedSettings.getString("MarketplaceURL");
|
||||||
mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
|
mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
|
||||||
|
|
|
||||||
|
|
@ -289,10 +289,12 @@ bool LLFloaterRegionInfo::postBuild()
|
||||||
static LLCachedControl<bool> feature_pbr_terrain_transforms_enabled(gSavedSettings, "RenderTerrainPBRTransformsEnabled", false);
|
static LLCachedControl<bool> feature_pbr_terrain_transforms_enabled(gSavedSettings, "RenderTerrainPBRTransformsEnabled", false);
|
||||||
if (!feature_pbr_terrain_transforms_enabled() || !feature_pbr_terrain_enabled())
|
if (!feature_pbr_terrain_transforms_enabled() || !feature_pbr_terrain_enabled())
|
||||||
{
|
{
|
||||||
|
LL_INFOS("Terrain") << "Building region terrain panel from panel_region_terrain.xml" << LL_ENDL;
|
||||||
panel->buildFromFile("panel_region_terrain.xml");
|
panel->buildFromFile("panel_region_terrain.xml");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
LL_INFOS("Terrain") << "Building region terrain panel from panel_region_terrain_texture_transform.xml" << LL_ENDL;
|
||||||
panel->buildFromFile("panel_region_terrain_texture_transform.xml");
|
panel->buildFromFile("panel_region_terrain_texture_transform.xml");
|
||||||
}
|
}
|
||||||
mTab->addTabPanel(panel);
|
mTab->addTabPanel(panel);
|
||||||
|
|
@ -1676,6 +1678,11 @@ bool LLPanelRegionTerrainInfo::validateMaterials()
|
||||||
const LLUUID& material_asset_id = material_ctrl->getImageAssetID();
|
const LLUUID& material_asset_id = material_ctrl->getImageAssetID();
|
||||||
llassert(material_asset_id.notNull());
|
llassert(material_asset_id.notNull());
|
||||||
if (material_asset_id.isNull()) { return false; }
|
if (material_asset_id.isNull()) { return false; }
|
||||||
|
if (material_asset_id == BLANK_MATERIAL_ASSET_ID)
|
||||||
|
{
|
||||||
|
// Default/Blank material is valid by default
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const LLFetchedGLTFMaterial* material = gGLTFMaterialList.getMaterial(material_asset_id);
|
const LLFetchedGLTFMaterial* material = gGLTFMaterialList.getMaterial(material_asset_id);
|
||||||
if (!material->isLoaded())
|
if (!material->isLoaded())
|
||||||
{
|
{
|
||||||
|
|
@ -2194,18 +2201,7 @@ void LLPanelRegionTerrainInfo::initMaterialCtrl(LLTextureCtrl*& ctrl, const std:
|
||||||
ctrl->setCommitCallback(
|
ctrl->setCommitCallback(
|
||||||
[this, index](LLUICtrl* ctrl, const LLSD& param)
|
[this, index](LLUICtrl* ctrl, const LLSD& param)
|
||||||
{
|
{
|
||||||
if (!mMaterialScaleUCtrl[index]
|
callbackMaterialCommit(index);
|
||||||
|| !mMaterialScaleVCtrl[index]
|
|
||||||
|| !mMaterialRotationCtrl[index]
|
|
||||||
|| !mMaterialOffsetUCtrl[index]
|
|
||||||
|| !mMaterialOffsetVCtrl[index]) return;
|
|
||||||
|
|
||||||
mMaterialScaleUCtrl[index]->setValue(1.f);
|
|
||||||
mMaterialScaleVCtrl[index]->setValue(1.f);
|
|
||||||
mMaterialRotationCtrl[index]->setValue(0.f);
|
|
||||||
mMaterialOffsetUCtrl[index]->setValue(0.f);
|
|
||||||
mMaterialOffsetVCtrl[index]->setValue(0.f);
|
|
||||||
onChangeAnything();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2333,6 +2329,25 @@ bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, con
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LLPanelRegionTerrainInfo::callbackMaterialCommit(S32 index)
|
||||||
|
{
|
||||||
|
// These can be null if 'transforms' panel was not inited
|
||||||
|
if (mMaterialScaleUCtrl[index]
|
||||||
|
&& mMaterialScaleVCtrl[index]
|
||||||
|
&& mMaterialRotationCtrl[index]
|
||||||
|
&& mMaterialOffsetUCtrl[index]
|
||||||
|
&& mMaterialOffsetVCtrl[index])
|
||||||
|
{
|
||||||
|
mMaterialScaleUCtrl[index]->setValue(1.f);
|
||||||
|
mMaterialScaleVCtrl[index]->setValue(1.f);
|
||||||
|
mMaterialRotationCtrl[index]->setValue(0.f);
|
||||||
|
mMaterialOffsetUCtrl[index]->setValue(0.f);
|
||||||
|
mMaterialOffsetVCtrl[index]->setValue(0.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeAnything();
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
// LLPanelEstateInfo
|
// LLPanelEstateInfo
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -302,6 +302,7 @@ public:
|
||||||
static void onClickBakeTerrain(void*);
|
static void onClickBakeTerrain(void*);
|
||||||
bool callbackBakeTerrain(const LLSD& notification, const LLSD& response);
|
bool callbackBakeTerrain(const LLSD& notification, const LLSD& response);
|
||||||
bool callbackTextureHeights(const LLSD& notification, const LLSD& response);
|
bool callbackTextureHeights(const LLSD& notification, const LLSD& response);
|
||||||
|
void callbackMaterialCommit(S32 index);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool sendUpdate() override;
|
bool sendUpdate() override;
|
||||||
|
|
|
||||||
|
|
@ -179,15 +179,14 @@ void LLFloaterSearch::initiateSearch(const LLSD& tokens)
|
||||||
|
|
||||||
// Naviation to the calculated URL - we know it's HTML so we can
|
// Naviation to the calculated URL - we know it's HTML so we can
|
||||||
// tell the media system not to bother with the MIME type check.
|
// tell the media system not to bother with the MIME type check.
|
||||||
LLMediaCtrl* search_browser = findChild<LLMediaCtrl>("search_contents");
|
mWebBrowser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
|
||||||
search_browser->navigateTo(url, HTTP_CONTENT_TEXT_HTML);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLFloaterSearch::postBuild()
|
bool LLFloaterSearch::postBuild()
|
||||||
{
|
{
|
||||||
LLFloaterWebContent::postBuild();
|
if (!LLFloaterWebContent::postBuild())
|
||||||
mWebBrowser = getChild<LLMediaCtrl>("search_contents");
|
return false;
|
||||||
mWebBrowser->addObserver(this);
|
|
||||||
mWebBrowser->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
|
mWebBrowser->setErrorPageURL(gSavedSettings.getString("GenericErrorPageURL"));
|
||||||
|
|
||||||
// If cookie is there, will set it now, Otherwise will have to wait for login completion
|
// If cookie is there, will set it now, Otherwise will have to wait for login completion
|
||||||
|
|
|
||||||
|
|
@ -2217,7 +2217,6 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
|
||||||
|
|
||||||
objectp->clearTEWaterExclusion(te);
|
objectp->clearTEWaterExclusion(te);
|
||||||
// Blank out most override data on the object and send to server
|
// Blank out most override data on the object and send to server
|
||||||
objectp->setRenderMaterialID(te, asset_id);
|
|
||||||
if (should_preserve_transforms && preserved_override)
|
if (should_preserve_transforms && preserved_override)
|
||||||
{
|
{
|
||||||
// Apply material with preserved transforms
|
// Apply material with preserved transforms
|
||||||
|
|
|
||||||
|
|
@ -1551,7 +1551,7 @@ void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hit_obj->setRenderMaterialID(te, asset_id, false, true);
|
hit_obj->setRenderMaterialID(te, asset_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -267,8 +267,11 @@ void display_stats()
|
||||||
if (gRecentFPSTime.getElapsedTimeF32() >= FPS_LOG_FREQUENCY)
|
if (gRecentFPSTime.getElapsedTimeF32() >= FPS_LOG_FREQUENCY)
|
||||||
{
|
{
|
||||||
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS");
|
LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("DS - FPS");
|
||||||
|
LLTrace::Recording& recording = LLTrace::get_frame_recording().getLastRecording();
|
||||||
|
F64 normalized_session_jitter = recording.getLastValue(LLStatViewer::NOTRMALIZED_FRAMETIME_JITTER_SESSION);
|
||||||
|
F64 normalized_period_jitter = recording.getLastValue(LLStatViewer::NORMALIZED_FRAMTIME_JITTER_PERIOD);
|
||||||
F32 fps = gRecentFrameCount / FPS_LOG_FREQUENCY;
|
F32 fps = gRecentFrameCount / FPS_LOG_FREQUENCY;
|
||||||
LL_INFOS() << llformat("FPS: %.02f", fps) << LL_ENDL;
|
LL_INFOS() << llformat("FPS: %.02f SESSION JITTER: %.4f PERIOD JITTER: %.4f", fps, normalized_session_jitter, normalized_period_jitter) << LL_ENDL;
|
||||||
gRecentFrameCount = 0;
|
gRecentFrameCount = 0;
|
||||||
gRecentFPSTime.reset();
|
gRecentFPSTime.reset();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1372,8 +1372,8 @@ void LLViewerMedia::getOpenIDCookieCoro(std::string url)
|
||||||
std::string browser_name;
|
std::string browser_name;
|
||||||
};
|
};
|
||||||
struct MediaCookieInstance media_cookie_instances[] = {
|
struct MediaCookieInstance media_cookie_instances[] = {
|
||||||
{"search", "search_contents" },
|
{"search", "webbrowser" },
|
||||||
{"marketplace", "marketplace_contents" },
|
{"marketplace", "webbrowser" },
|
||||||
{"destinations", "destination_guide_contents" },
|
{"destinations", "destination_guide_contents" },
|
||||||
};
|
};
|
||||||
for (MediaCookieInstance mci : media_cookie_instances)
|
for (MediaCookieInstance mci : media_cookie_instances)
|
||||||
|
|
|
||||||
|
|
@ -4029,7 +4029,10 @@ void process_crossed_region(LLMessageSystem* msg, void**)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LL_INFOS("Messaging") << "process_crossed_region()" << LL_ENDL;
|
LL_INFOS("Messaging") << "process_crossed_region()" << LL_ENDL;
|
||||||
|
if (isAgentAvatarValid())
|
||||||
|
{
|
||||||
gAgentAvatarp->resetRegionCrossingTimer();
|
gAgentAvatarp->resetRegionCrossingTimer();
|
||||||
|
}
|
||||||
// <FS:Ansariel> FIRE-12004: Attachments getting lost on TP; this is apparently the place to
|
// <FS:Ansariel> FIRE-12004: Attachments getting lost on TP; this is apparently the place to
|
||||||
// hook in for region crossings - we get an info from the simulator that we
|
// hook in for region crossings - we get an info from the simulator that we
|
||||||
// crossed a region and then the viewer starts the handover process. We only
|
// crossed a region and then the viewer starts the handover process. We only
|
||||||
|
|
|
||||||
|
|
@ -234,6 +234,9 @@ extern LLTrace::EventStatHandle<F64Seconds > AVATAR_EDIT_TIME,
|
||||||
|
|
||||||
extern LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE;
|
extern LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT_RATE;
|
||||||
|
|
||||||
|
extern LLTrace::SampleStatHandle<F64> NOTRMALIZED_FRAMETIME_JITTER_SESSION;
|
||||||
|
extern LLTrace::SampleStatHandle<F64> NORMALIZED_FRAMTIME_JITTER_PERIOD;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class LLViewerStats : public LLSingleton<LLViewerStats>
|
class LLViewerStats : public LLSingleton<LLViewerStats>
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@
|
||||||
layout="topleft"
|
layout="topleft"
|
||||||
left="0"
|
left="0"
|
||||||
trusted_content="true"
|
trusted_content="true"
|
||||||
name="search_contents"
|
name="webbrowser"
|
||||||
top="0"/>
|
top="0"/>
|
||||||
</layout_panel>
|
</layout_panel>
|
||||||
<layout_panel name="status_bar"
|
<layout_panel name="status_bar"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue