Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions indra/llcommon/llwatchdog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ bool LLWatchdogTimeout::isAlive() const
return (mTimer.getStarted() && !mTimer.hasExpired());
}

bool LLWatchdogTimeout::hasExpired() const
{
return mTimer.hasExpired();
}

void LLWatchdogTimeout::reset()
{
mTimer.setTimerExpirySec(mTimeout);
Expand Down
2 changes: 2 additions & 0 deletions indra/llcommon/llwatchdog.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class LLWatchdogEntry
// This may mean that resources used by
// isAlive and other method may need synchronization.
virtual bool isAlive() const = 0;
virtual bool hasExpired() const = 0;
virtual void reset() = 0;
virtual void start();
virtual void stop();
Expand All @@ -66,6 +67,7 @@ class LLWatchdogTimeout : public LLWatchdogEntry
virtual ~LLWatchdogTimeout();

bool isAlive() const override;
bool hasExpired() const override;
void reset() override;
void start() override { start(""); }
void stop() override;
Expand Down
57 changes: 39 additions & 18 deletions indra/llrender/llshadermgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1142,34 +1142,55 @@ bool LLShaderMgr::loadCachedProgramBinary(LLGLSLShader* shader)
{
std::string in_path = gDirUtilp->add(mShaderCacheDir, shader->mShaderHash.asString() + ".shaderbin");
auto& shader_info = binary_iter->second;
if (shader_info.mBinaryLength > 0)
{
std::vector<U8> in_data;
in_data.resize(shader_info.mBinaryLength);

LLUniqueFile filep = LLFile::fopen(in_path, "rb");
if (filep)
try
{
constexpr GLsizei MAX_SHADER_BINARY_SIZE = 1024 * 1024; // 1 MB, normally around 10KB
if (shader_info.mBinaryLength > 0 && shader_info.mBinaryLength <= MAX_SHADER_BINARY_SIZE)
{
size_t result = fread(in_data.data(), sizeof(U8), in_data.size(), filep);
filep.close();
std::vector<U8> in_data;
in_data.resize(shader_info.mBinaryLength);

if (result == in_data.size())
LLUniqueFile filep = LLFile::fopen(in_path, "rb");
if (filep)
{
GLenum error = glGetError(); // Clear current error
glProgramBinary(shader->mProgramObject, shader_info.mBinaryFormat, in_data.data(), shader_info.mBinaryLength);
size_t result = fread(in_data.data(), sizeof(U8), in_data.size(), filep);
filep.close();

error = glGetError();
GLint success = GL_TRUE;
glGetProgramiv(shader->mProgramObject, GL_LINK_STATUS, &success);
if (error == GL_NO_ERROR && success == GL_TRUE)
if (result == in_data.size())
{
binary_iter->second.mLastUsedTime = (F32)LLTimer::getTotalSeconds();
LL_INFOS() << "Loaded cached binary for shader: " << shader->mName << LL_ENDL;
return true;
GLenum error = glGetError(); // Clear current error
glProgramBinary(shader->mProgramObject, shader_info.mBinaryFormat, in_data.data(), shader_info.mBinaryLength);

error = glGetError();
GLint success = GL_TRUE;
glGetProgramiv(shader->mProgramObject, GL_LINK_STATUS, &success);
if (error == GL_NO_ERROR && success == GL_TRUE)
{
binary_iter->second.mLastUsedTime = (F32)LLTimer::getTotalSeconds();
LL_INFOS() << "Loaded cached binary for shader: " << shader->mName << LL_ENDL;
return true;
}
}
else
{
LL_WARNS("ShaderMgr") << "Incomplete read of shader binary. Expected: "
<< in_data.size() << ", read: " << result << LL_ENDL;
}
}
}
}
catch (const std::bad_alloc&)
{
LL_WARNS("ShaderMgr") << "Failed to allocate memory for shader binary ("
<< shader_info.mBinaryLength << " bytes) for: "
<< shader->mName << LL_ENDL;
}
catch (const std::exception& err)
{
LL_WARNS("ShaderMgr") << "Caught exception " << err.what() << " while loading shader binary for: " << shader->mName << LL_ENDL;
}

//an error occured, normally we would print log but in this case it means the shader needs recompiling.
LL_INFOS() << "Failed to load cached binary for shader: " << shader->mName << " falling back to compilation" << LL_ENDL;
LLFile::remove(in_path);
Expand Down
26 changes: 26 additions & 0 deletions indra/newview/llappviewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6321,6 +6321,32 @@ F32 LLAppViewer::getMainloopTimeoutSec() const
}
}

std::string LLAppViewer::getMainloopWatchdogState() const
{
if (!mMainloopTimeout)
{
return std::string();
}
std::string state = mMainloopTimeout->getState();

if (mMainloopTimeout->hasExpired())
{
return "Expired at " + state;
}

// Check if the watchdog is currently active (timer started)
if (!mMainloopTimeout->isAlive())
{
// Timer is not running, meaning watchdog is paused/stopped
if (state.empty())
{
return "Paused";
}
return "Paused at " + state;
}
return state;
}

void LLAppViewer::handleLoginComplete()
{
gLoggedInTime.start();
Expand Down
1 change: 1 addition & 0 deletions indra/newview/llappviewer.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ class LLAppViewer : public LLApp
void pingMainloopTimeout(std::string_view state);

F32 getMainloopTimeoutSec() const;
std::string getMainloopWatchdogState() const;

// Handle the 'login completed' event.
// *NOTE:Mani Fix this for login abstraction!!
Expand Down
8 changes: 8 additions & 0 deletions indra/newview/llappviewerwin32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,14 @@ namespace
}

LLAppViewer* app = LLAppViewer::instance();

// Include mainloop watchdog state if available
std::string watchdog_state = app->getMainloopWatchdogState();
if (!watchdog_state.empty())
{
sBugSplatSender->setAttribute(WCSTR(L"WatchdogState"), WCSTR(watchdog_state));
}

if (!app->isSecondInstance() && !app->errorMarkerExists())
{
// If marker doesn't exist, create a marker with 'other' or 'logout' code for next launch
Expand Down
Loading