Kaydet (Commit) daa86922 authored tarafından Michael Meeks's avatar Michael Meeks

tdf#93850 - Defer watchdog during shader compiles.

Shader compilation can take a while the first time; best not to
disable GL at that point. Have more of a hair trigger at other times.
Also explicitly exit if we appear to have hung in std::abort handling.

Change-Id: I45f0873672f950fb3baba0ca859d854a0bb25064
üst b25388f9
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "svdata.hxx" #include "svdata.hxx"
#include "salinst.hxx"
#include "opengl/zone.hxx" #include "opengl/zone.hxx"
#include "opengl/watchdog.hxx" #include "opengl/watchdog.hxx"
#include <osl/conditn.h> #include <osl/conditn.h>
...@@ -38,6 +39,10 @@ ...@@ -38,6 +39,10 @@
#include "opengl/win/WinDeviceInfo.hxx" #include "opengl/win/WinDeviceInfo.hxx"
#endif #endif
static bool volatile gbInShaderCompile = false;
sal_uInt64 volatile OpenGLZone::gnEnterCount = 0;
sal_uInt64 volatile OpenGLZone::gnLeaveCount = 0;
namespace { namespace {
OUString getShaderFolder() OUString getShaderFolder()
...@@ -140,6 +145,8 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString ...@@ -140,6 +145,8 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString
{ {
OpenGLZone aZone; OpenGLZone aZone;
gbInShaderCompile = true;
VCL_GL_INFO("vcl.opengl", "Load shader: vertex " << rVertexShaderName << " fragment " << rFragmentShaderName); VCL_GL_INFO("vcl.opengl", "Load shader: vertex " << rVertexShaderName << " fragment " << rFragmentShaderName);
// Create the shaders // Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER); GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
...@@ -190,6 +197,11 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString ...@@ -190,6 +197,11 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString
return LogCompilerError(ProgramID, "program", "<both>", false); return LogCompilerError(ProgramID, "program", "<both>", false);
CHECK_GL_ERROR(); CHECK_GL_ERROR();
// Ensure we bump our counts before we leave the shader zone.
{ OpenGLZone aMakeProgress; }
gbInShaderCompile = false;
return ProgramID; return ProgramID;
} }
...@@ -462,9 +474,6 @@ bool OpenGLHelper::supportsVCLOpenGL() ...@@ -462,9 +474,6 @@ bool OpenGLHelper::supportsVCLOpenGL()
return true; return true;
} }
sal_uInt64 volatile OpenGLZone::gnEnterCount = 0;
sal_uInt64 volatile OpenGLZone::gnLeaveCount = 0;
void OpenGLZone::enter() { gnEnterCount++; } void OpenGLZone::enter() { gnEnterCount++; }
void OpenGLZone::leave() { gnLeaveCount++; } void OpenGLZone::leave() { gnLeaveCount++; }
...@@ -481,10 +490,13 @@ OpenGLWatchdogThread::OpenGLWatchdogThread() ...@@ -481,10 +490,13 @@ OpenGLWatchdogThread::OpenGLWatchdogThread()
void OpenGLWatchdogThread::execute() void OpenGLWatchdogThread::execute()
{ {
static const int nDisableEntries = 4; // 2 seconds - disable GL // delays to take various actions in 1/4 of a second increments.
static const int nAbortAfter = 10; // 5 seconds - not coming back; abort static const int nDisableEntries[2] = { 6 /* 1.5s */, 20 /* 5s */ };
static const int nAbortAfter[2] = { 20 /* 10s */, 120 /* 30s */ };
int nUnchanged = 0; // how many unchanged nEnters int nUnchanged = 0; // how many unchanged nEnters
TimeValue aHalfSecond(0, 1000*1000*1000*0.5); TimeValue aHalfSecond(0, 1000*1000*1000*0.25);
bool bAbortFired = false;
do { do {
sal_uInt64 nLastEnters = OpenGLZone::gnEnterCount; sal_uInt64 nLastEnters = OpenGLZone::gnEnterCount;
...@@ -493,28 +505,54 @@ void OpenGLWatchdogThread::execute() ...@@ -493,28 +505,54 @@ void OpenGLWatchdogThread::execute()
if (OpenGLZone::isInZone()) if (OpenGLZone::isInZone())
{ {
int nType = 0;
// The shader compiler can take a long time, first time.
if (gbInShaderCompile)
nType = 1;
if (nLastEnters == OpenGLZone::gnEnterCount) if (nLastEnters == OpenGLZone::gnEnterCount)
nUnchanged++; nUnchanged++;
else else
nUnchanged = 0; nUnchanged = 0;
SAL_INFO("vcl.opengl", "GL watchdog - unchanged " << SAL_INFO("vcl.opengl", "GL watchdog - unchanged " <<
nUnchanged << " enter count " << nUnchanged << " enter count " <<
OpenGLZone::gnEnterCount); OpenGLZone::gnEnterCount << " type " <<
(nType ? "in shader" : "normal gl") <<
"breakpoints mid: " << nDisableEntries[nType] <<
" max " << nAbortAfter[nType]);
// Not making progress // Not making progress
if (nUnchanged == nDisableEntries) if (nUnchanged >= nDisableEntries[nType])
{ {
gbWatchdogFiring = true; static bool bFired = false;
SAL_WARN("vcl.opengl", "Watchdog triggered: hard disable GL"); if (!bFired)
OpenGLZone::hardDisable(); {
gbWatchdogFiring = false; gbWatchdogFiring = true;
SAL_WARN("vcl.opengl", "Watchdog triggered: hard disable GL");
OpenGLZone::hardDisable();
gbWatchdogFiring = false;
}
bFired = true;
// we can hang using VCL in the abort handling -> be impatient
if (bAbortFired)
{
SAL_WARN("vcl.opengl", "Watchdog gave up: hard exiting");
_exit(1);
}
} }
if (nUnchanged == nAbortAfter) // Not making even more progress
if (nUnchanged >= nAbortAfter[nType])
{ {
SAL_WARN("vcl.opengl", "Watchdog gave up: aborting"); if (!bAbortFired)
gbWatchdogFiring = true; {
std::abort(); SAL_WARN("vcl.opengl", "Watchdog gave up: aborting");
gbWatchdogFiring = true;
nUnchanged = 0;
std::abort();
}
bAbortFired = true;
} }
} }
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment