summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2015-09-02 11:18:42 +0100
committerMichael Meeks <michael.meeks@collabora.com>2015-09-02 12:12:01 +0100
commitdaa869222edc3aded82f0fc3e73f126b6cfd08ad (patch)
treee1dc897c9d7066c9ee4a453635bdc3eb1ea40109
parentb25388f9c71804df92582f01dac8e5d9d1d5439e (diff)
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
-rw-r--r--vcl/source/opengl/OpenGLHelper.cxx70
1 files changed, 54 insertions, 16 deletions
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index 9a28438afe83..6288849dda28 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -28,6 +28,7 @@
#include "svdata.hxx"
+#include "salinst.hxx"
#include "opengl/zone.hxx"
#include "opengl/watchdog.hxx"
#include <osl/conditn.h>
@@ -38,6 +39,10 @@
#include "opengl/win/WinDeviceInfo.hxx"
#endif
+static bool volatile gbInShaderCompile = false;
+sal_uInt64 volatile OpenGLZone::gnEnterCount = 0;
+sal_uInt64 volatile OpenGLZone::gnLeaveCount = 0;
+
namespace {
OUString getShaderFolder()
@@ -140,6 +145,8 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString
{
OpenGLZone aZone;
+ gbInShaderCompile = true;
+
VCL_GL_INFO("vcl.opengl", "Load shader: vertex " << rVertexShaderName << " fragment " << rFragmentShaderName);
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
@@ -190,6 +197,11 @@ GLint OpenGLHelper::LoadShaders(const OUString& rVertexShaderName,const OUString
return LogCompilerError(ProgramID, "program", "<both>", false);
CHECK_GL_ERROR();
+
+ // Ensure we bump our counts before we leave the shader zone.
+ { OpenGLZone aMakeProgress; }
+ gbInShaderCompile = false;
+
return ProgramID;
}
@@ -462,9 +474,6 @@ bool OpenGLHelper::supportsVCLOpenGL()
return true;
}
-sal_uInt64 volatile OpenGLZone::gnEnterCount = 0;
-sal_uInt64 volatile OpenGLZone::gnLeaveCount = 0;
-
void OpenGLZone::enter() { gnEnterCount++; }
void OpenGLZone::leave() { gnLeaveCount++; }
@@ -481,10 +490,13 @@ OpenGLWatchdogThread::OpenGLWatchdogThread()
void OpenGLWatchdogThread::execute()
{
- static const int nDisableEntries = 4; // 2 seconds - disable GL
- static const int nAbortAfter = 10; // 5 seconds - not coming back; abort
+ // delays to take various actions in 1/4 of a second increments.
+ 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
- TimeValue aHalfSecond(0, 1000*1000*1000*0.5);
+ TimeValue aHalfSecond(0, 1000*1000*1000*0.25);
+ bool bAbortFired = false;
do {
sal_uInt64 nLastEnters = OpenGLZone::gnEnterCount;
@@ -493,28 +505,54 @@ void OpenGLWatchdogThread::execute()
if (OpenGLZone::isInZone())
{
+ int nType = 0;
+ // The shader compiler can take a long time, first time.
+ if (gbInShaderCompile)
+ nType = 1;
+
if (nLastEnters == OpenGLZone::gnEnterCount)
nUnchanged++;
else
nUnchanged = 0;
SAL_INFO("vcl.opengl", "GL watchdog - unchanged " <<
nUnchanged << " enter count " <<
- OpenGLZone::gnEnterCount);
+ OpenGLZone::gnEnterCount << " type " <<
+ (nType ? "in shader" : "normal gl") <<
+ "breakpoints mid: " << nDisableEntries[nType] <<
+ " max " << nAbortAfter[nType]);
// Not making progress
- if (nUnchanged == nDisableEntries)
+ if (nUnchanged >= nDisableEntries[nType])
{
- gbWatchdogFiring = true;
- SAL_WARN("vcl.opengl", "Watchdog triggered: hard disable GL");
- OpenGLZone::hardDisable();
- gbWatchdogFiring = false;
+ static bool bFired = false;
+ if (!bFired)
+ {
+ 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");
- gbWatchdogFiring = true;
- std::abort();
+ if (!bAbortFired)
+ {
+ SAL_WARN("vcl.opengl", "Watchdog gave up: aborting");
+ gbWatchdogFiring = true;
+ nUnchanged = 0;
+ std::abort();
+ }
+ bAbortFired = true;
}
}
else