Merge pull request #12370 from jherico/fix/deadlock_shaders

Prevent deadlock crashes when building shaders at startup
This commit is contained in:
Brad Hefta-Gaub 2018-02-08 14:44:46 -08:00 committed by GitHub
commit a6c8172990
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -318,7 +318,7 @@ static QTimer pingTimer;
static bool DISABLE_WATCHDOG = true; static bool DISABLE_WATCHDOG = true;
#else #else
static const QString DISABLE_WATCHDOG_FLAG{ "HIFI_DISABLE_WATCHDOG" }; static const QString DISABLE_WATCHDOG_FLAG{ "HIFI_DISABLE_WATCHDOG" };
static bool DISABLE_WATCHDOG = QProcessEnvironment::systemEnvironment().contains(DISABLE_WATCHDOG_FLAG); static bool DISABLE_WATCHDOG = nsightActive() || QProcessEnvironment::systemEnvironment().contains(DISABLE_WATCHDOG_FLAG);
#endif #endif
#if defined(USE_GLES) #if defined(USE_GLES)
@ -415,20 +415,26 @@ public:
*crashTrigger = 0xDEAD10CC; *crashTrigger = 0xDEAD10CC;
} }
static void withPause(const std::function<void()>& lambda) {
pause();
lambda();
resume();
}
static void pause() { static void pause() {
_paused = true; _paused = true;
} }
static void resume() { static void resume() {
_paused = false; // Update the heartbeat BEFORE resuming the checks
updateHeartbeat(); updateHeartbeat();
_paused = false;
} }
void run() override { void run() override {
while (!_quit) { while (!_quit) {
QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS); QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
// Don't do heartbeat detection under nsight // Don't do heartbeat detection under nsight
if (nsightActive() || _paused) { if (_paused) {
continue; continue;
} }
uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us
@ -2283,29 +2289,22 @@ void Application::initializeGL() {
initDisplay(); initDisplay();
qCDebug(interfaceapp, "Initialized Display."); qCDebug(interfaceapp, "Initialized Display.");
#ifdef Q_OS_OSX // FIXME: on low end systems os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread.
// FIXME: on mac os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread. DeadlockWatchdogThread::withPause([&] {
DeadlockWatchdogThread::pause(); // Set up the render engine
#endif render::CullFunctor cullFunctor = LODManager::shouldRender;
static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
// Set up the render engine _renderEngine->addJob<UpdateSceneTask>("UpdateScene");
render::CullFunctor cullFunctor = LODManager::shouldRender;
static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
_renderEngine->addJob<UpdateSceneTask>("UpdateScene");
#ifndef Q_OS_ANDROID #ifndef Q_OS_ANDROID
_renderEngine->addJob<SecondaryCameraRenderTask>("SecondaryCameraJob", cullFunctor, !DISABLE_DEFERRED); _renderEngine->addJob<SecondaryCameraRenderTask>("SecondaryCameraJob", cullFunctor, !DISABLE_DEFERRED);
#endif #endif
_renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, !DISABLE_DEFERRED, render::ItemKey::TAG_BITS_0, render::ItemKey::TAG_BITS_0); _renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, !DISABLE_DEFERRED, render::ItemKey::TAG_BITS_0, render::ItemKey::TAG_BITS_0);
_renderEngine->load();
_renderEngine->registerScene(_main3DScene);
_renderEngine->load(); // Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success.
_renderEngine->registerScene(_main3DScene); DependencyManager::get<GeometryCache>()->initializeShapePipelines();
});
// Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success.
DependencyManager::get<GeometryCache>()->initializeShapePipelines();
#ifdef Q_OS_OSX
DeadlockWatchdogThread::resume();
#endif
_offscreenContext = new OffscreenGLCanvas(); _offscreenContext = new OffscreenGLCanvas();
_offscreenContext->setObjectName("MainThreadContext"); _offscreenContext->setObjectName("MainThreadContext");