summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorToma┼ż Vajngerl <tomaz.vajngerl@collabora.com>2016-09-19 18:03:47 +0200
committerTor Lillqvist <tml@collabora.com>2016-09-20 15:26:11 +0000
commit21c806828154449fb002f75a8235482eb8a77272 (patch)
treec954906fec660764e31b32f16cddd2d305876bf4
parent9e2f22dfab467b41d552fdaeabf9445c5ad34a47 (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. Contains also the following commits: tdf#102295: The relaxed values were actually too pessimistic. tdf#102295: AMD actually has two vendor id's. tdf#102295: remove mutex - use atomic for watchdog timings (cherry picked from commit e5c3c69423c0f32bf4bee147936e58ba4d3be181) Change-Id: Ifd9ff7ecfa4b004d5411d6d364dd01a389a3fcec Reviewed-on: https://gerrit.libreoffice.org/29042 Reviewed-by: Eike Rathke <erack@redhat.com> Reviewed-by: Tor Lillqvist <tml@collabora.com> Tested-by: Tor Lillqvist <tml@collabora.com>
-rw-r--r--vcl/inc/opengl/watchdog.hxx38
-rw-r--r--vcl/inc/opengl/zone.hxx1
-rw-r--r--vcl/source/opengl/OpenGLHelper.cxx43
3 files changed, 68 insertions, 14 deletions
diff --git a/vcl/inc/opengl/watchdog.hxx b/vcl/inc/opengl/watchdog.hxx
index 0213efb7d668..c266de62f7dc 100644
--- a/vcl/inc/opengl/watchdog.hxx
+++ b/vcl/inc/opengl/watchdog.hxx
@@ -14,6 +14,44 @@
#include <sal/types.h>
#include <rtl/ref.hxx>
#include <salhelper/thread.hxx>
+#include <atomic>
+
+struct WatchdogTimingsValues
+{
+ /// delays to take various actions in 1/4 of a second increments.
+ int mnDisableEntries;
+ int mnAbortAfter;
+};
+
+enum class WatchdogTimingMode
+{
+ NORMAL,
+ SHADER_COMPILE
+};
+
+class WatchdogTimings
+{
+private:
+ std::vector<WatchdogTimingsValues> maTimingValues;
+ std::atomic<bool> mbRelaxed;
+
+public:
+ WatchdogTimings();
+
+ void setRelax(bool bRelaxed)
+ {
+ mbRelaxed = bRelaxed;
+ }
+
+ WatchdogTimingsValues getWatchdogTimingsValues(WatchdogTimingMode eMode)
+ {
+ size_t index = 0;
+ index = (eMode == WatchdogTimingMode::SHADER_COMPILE) ? 1 : 0;
+ index = mbRelaxed ? index + 2 : index;
+
+ return maTimingValues[index];
+ }
+};
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 5dff6894494d..12f6151048f7 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() == "0x1002" || aInfo.GetAdapterVendorID() == "0x1022")) /* AMD */
+ {
+ SAL_INFO("vcl.opengl", "Relaxing watchdog timings.");
+ OpenGLZone::relaxWatchdogTimings();
+ }
#else
bBlacklisted = false;
#endif
@@ -806,9 +813,17 @@ void OpenGLZone::leave() { gnLeaveCount++; }
namespace {
static volatile bool gbWatchdogFiring = false;
static oslCondition gpWatchdogExit = nullptr;
+ static WatchdogTimings gWatchdogTimings;
static rtl::Reference<OpenGLWatchdogThread> gxWatchdog;
}
+WatchdogTimings::WatchdogTimings()
+ : maTimingValues({{6, 20} /* 1.5s, 5s */, {20, 120} /* 5s, 30s */,
+ {60, 240} /* 15s, 60s */, {60, 240} /* 15s, 60s */})
+ , mbRelaxed(false)
+{
+}
+
OpenGLWatchdogThread::OpenGLWatchdogThread()
: salhelper::Thread("OpenGL Watchdog")
{
@@ -816,25 +831,20 @@ 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;
// The shader compiler can take a long time, first time.
- if (gbInShaderCompile)
- nType = 1;
+ WatchdogTimingMode eMode = gbInShaderCompile ? WatchdogTimingMode::SHADER_COMPILE : WatchdogTimingMode::NORMAL;
+ WatchdogTimingsValues aTimingValues = gWatchdogTimings.getWatchdogTimingsValues(eMode);
if (nLastEnters == OpenGLZone::gnEnterCount)
nUnchanged++;
@@ -843,12 +853,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]);
+ (eMode == WatchdogTimingMode::SHADER_COMPILE ? "in shader" : "normal gl") <<
+ "breakpoints mid: " << aTimingValues.mnDisableEntries <<
+ " max " << aTimingValues.mnAbortAfter);
// Not making progress
- if (nUnchanged >= nDisableEntries[nType])
+ if (nUnchanged >= aTimingValues.mnDisableEntries)
{
static bool bFired = false;
if (!bFired)
@@ -869,7 +879,7 @@ void OpenGLWatchdogThread::execute()
}
// Not making even more progress
- if (nUnchanged >= nAbortAfter[nType])
+ if (nUnchanged >= aTimingValues.mnAbortAfter)
{
if (!bAbortFired)
{
@@ -943,6 +953,11 @@ void OpenGLZone::hardDisable()
}
}
+void OpenGLZone::relaxWatchdogTimings()
+{
+ gWatchdogTimings.setRelax(true);
+}
+
OpenGLVCLContextZone::OpenGLVCLContextZone()
{
OpenGLContext::makeVCLCurrent();