From 419522f7256865aeceb1b30f1a333e87fdd72fc9 Mon Sep 17 00:00:00 2001 From: Michael Meeks Date: Wed, 2 Sep 2015 11:18:42 +0100 Subject: 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. Conflicts: vcl/source/opengl/OpenGLHelper.cxx Change-Id: I45f0873672f950fb3baba0ca859d854a0bb25064 Reviewed-on: https://gerrit.libreoffice.org/18265 Reviewed-by: Michael Meeks Reviewed-by: Miklos Vajna Tested-by: Miklos Vajna --- vcl/source/opengl/OpenGLHelper.cxx | 71 +++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx index deaf91c08d33..526e124669bc 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 @@ -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", "", 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,13 +490,17 @@ 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; aHalfSecond.Seconds = 0; - aHalfSecond.Nanosec = 1000*1000*1000/2; + aHalfSecond.Nanosec = 1000*1000*1000/4; + + bool bAbortFired = false; do { sal_uInt64 nLastEnters = OpenGLZone::gnEnterCount; @@ -496,28 +509,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 -- cgit v1.2.3