summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.com>2016-09-19 18:03:47 +0200
committerJan Holesovsky <kendy@collabora.com>2016-09-19 23:30:12 +0200
commite5c3c69423c0f32bf4bee147936e58ba4d3be181 (patch)
tree35f7eb0226226831cee12c8ba18c93993cd1dc9f
parent11370a0ce5a8ca503927cff38d79b38e513123fe (diff)
tdf#102295: relax timeout timings for the GL watchdog
Some OS/GPU combinations need more relaxed watchdog timeout timings as the shader compilation takes too long to complete. Change-Id: Ifd9ff7ecfa4b004d5411d6d364dd01a389a3fcec
-rw-r--r--vcl/inc/opengl/watchdog.hxx36
-rw-r--r--vcl/inc/opengl/zone.hxx1
-rw-r--r--vcl/source/opengl/OpenGLHelper.cxx55
3 files changed, 79 insertions, 13 deletions
diff --git a/vcl/inc/opengl/watchdog.hxx b/vcl/inc/opengl/watchdog.hxx
index 0213efb7d668..ced3cf23fbd6 100644
--- a/vcl/inc/opengl/watchdog.hxx
+++ b/vcl/inc/opengl/watchdog.hxx
@@ -14,6 +14,42 @@
#include <sal/types.h>
#include <rtl/ref.hxx>
#include <salhelper/thread.hxx>
+#include <osl/mutex.hxx>
+
+struct WatchdogTimings
+{
+ osl::Mutex maMutex;
+
+ int mnMode;
+
+ /// delays to take various actions in 1/4 of a second increments.
+ std::vector<int> maDisableEntries;
+ std::vector<int> maAbortAfter;
+
+ WatchdogTimings();
+
+ void relax();
+
+ int getMode()
+ {
+ return mnMode;
+ }
+
+ void setMode(int nMode)
+ {
+ mnMode = nMode;
+ }
+
+ int getDisableEntries()
+ {
+ return maDisableEntries[mnMode];
+ }
+
+ int getAbortAfter()
+ {
+ return maAbortAfter[mnMode];
+ }
+};
class OpenGLWatchdogThread : private salhelper::Thread
{
diff --git a/vcl/inc/opengl/zone.hxx b/vcl/inc/opengl/zone.hxx
index 11f6ed00ec3c..65a7249b16b2 100644
--- a/vcl/inc/opengl/zone.hxx
+++ b/vcl/inc/opengl/zone.hxx
@@ -38,6 +38,7 @@ public:
~OpenGLZone() { gnLeaveCount++; }
static bool isInZone() { return gnEnterCount != gnLeaveCount; }
static void hardDisable();
+ static void relaxWatchdogTimings();
};
/// Create this to not only enter the zone, but set VCL context.
diff --git a/vcl/source/opengl/OpenGLHelper.cxx b/vcl/source/opengl/OpenGLHelper.cxx
index f713cf87e693..fa1c532132a9 100644
--- a/vcl/source/opengl/OpenGLHelper.cxx
+++ b/vcl/source/opengl/OpenGLHelper.cxx
@@ -780,6 +780,13 @@ bool OpenGLHelper::isDeviceBlacklisted()
#elif defined( _WIN32 )
WinOpenGLDeviceInfo aInfo;
bBlacklisted = aInfo.isDeviceBlocked();
+
+ if (aInfo.GetWindowsVersion() == 0x00060001 && /* Windows 7 */
+ aInfo.GetAdapterVendorID() == "0x1022") /* AMD */
+ {
+ SAL_INFO("vcl.opengl", "Relaxing watchdog timings.");
+ OpenGLZone::relaxWatchdogTimings();
+ }
#else
bBlacklisted = false;
#endif
@@ -806,9 +813,27 @@ void OpenGLZone::leave() { gnLeaveCount++; }
namespace {
static volatile bool gbWatchdogFiring = false;
static oslCondition gpWatchdogExit = nullptr;
+ static WatchdogTimings gWatchdogTimings;
static rtl::Reference<OpenGLWatchdogThread> gxWatchdog;
}
+WatchdogTimings::WatchdogTimings()
+ : mnMode(0)
+ , maDisableEntries({ 6 /* 1.5s */, 20 /* 5s */ })
+ , maAbortAfter({ 20 /* 5s */, 120 /* 30s */ })
+{}
+
+void WatchdogTimings::relax()
+{
+ osl::MutexGuard g(maMutex);
+
+ maDisableEntries[0] = 180; /* 45s */
+ maDisableEntries[1] = 180; /* 45s */
+
+ maAbortAfter[0] = 240; /* 60s */
+ maAbortAfter[1] = 240; /* 60s */
+}
+
OpenGLWatchdogThread::OpenGLWatchdogThread()
: salhelper::Thread("OpenGL Watchdog")
{
@@ -816,25 +841,24 @@ OpenGLWatchdogThread::OpenGLWatchdogThread()
void OpenGLWatchdogThread::execute()
{
- // 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.25);
+ TimeValue aQuarterSecond(0, 1000*1000*1000*0.25);
bool bAbortFired = false;
do {
sal_uInt64 nLastEnters = OpenGLZone::gnEnterCount;
- osl_waitCondition(gpWatchdogExit, &aHalfSecond);
+ osl_waitCondition(gpWatchdogExit, &aQuarterSecond);
if (OpenGLZone::isInZone())
{
- int nType = 0;
+ osl::MutexGuard g(gWatchdogTimings.maMutex);
+
// The shader compiler can take a long time, first time.
if (gbInShaderCompile)
- nType = 1;
+ gWatchdogTimings.setMode(1);
+ else
+ gWatchdogTimings.setMode(0);
if (nLastEnters == OpenGLZone::gnEnterCount)
nUnchanged++;
@@ -843,12 +867,12 @@ void OpenGLWatchdogThread::execute()
SAL_INFO("vcl.opengl", "GL watchdog - unchanged " <<
nUnchanged << " enter count " <<
OpenGLZone::gnEnterCount << " type " <<
- (nType ? "in shader" : "normal gl") <<
- "breakpoints mid: " << nDisableEntries[nType] <<
- " max " << nAbortAfter[nType]);
+ (gWatchdogTimings.getMode() ? "in shader" : "normal gl") <<
+ "breakpoints mid: " << gWatchdogTimings.getDisableEntries() <<
+ " max " << gWatchdogTimings.getAbortAfter());
// Not making progress
- if (nUnchanged >= nDisableEntries[nType])
+ if (nUnchanged >= gWatchdogTimings.getDisableEntries())
{
static bool bFired = false;
if (!bFired)
@@ -869,7 +893,7 @@ void OpenGLWatchdogThread::execute()
}
// Not making even more progress
- if (nUnchanged >= nAbortAfter[nType])
+ if (nUnchanged >= gWatchdogTimings.getAbortAfter())
{
if (!bAbortFired)
{
@@ -943,6 +967,11 @@ void OpenGLZone::hardDisable()
}
}
+void OpenGLZone::relaxWatchdogTimings()
+{
+ gWatchdogTimings.relax();
+}
+
OpenGLVCLContextZone::OpenGLVCLContextZone()
{
OpenGLContext::makeVCLCurrent();