Prevent deadlock crashes when building shaders at startup

This commit is contained in:
Bradley Austin Davis 2018-02-08 10:23:25 -08:00 committed by Brad Davis
parent 4bb329696a
commit f6fbac25b0

View file

@ -307,8 +307,12 @@ static QTimer locationUpdateTimer;
static QTimer identityPacketTimer;
static QTimer pingTimer;
static const QString DISABLE_WATCHDOG_FLAG("HIFI_DISABLE_WATCHDOG");
static bool DISABLE_WATCHDOG = QProcessEnvironment::systemEnvironment().contains(DISABLE_WATCHDOG_FLAG);
#if defined(Q_OS_ANDROID)
static bool DISABLE_WATCHDOG = true;
#else
static const QString DISABLE_WATCHDOG_FLAG{ "HIFI_DISABLE_WATCHDOG" };
static bool DISABLE_WATCHDOG = nsightActive() || QProcessEnvironment::systemEnvironment().contains(DISABLE_WATCHDOG_FLAG);
#endif
static const int MAX_CONCURRENT_RESOURCE_DOWNLOADS = 16;
@ -398,20 +402,26 @@ public:
*crashTrigger = 0xDEAD10CC;
}
static void withPause(const std::function<void()>& lambda) {
pause();
lambda();
resume();
}
static void pause() {
_paused = true;
}
static void resume() {
_paused = false;
// Update the heartbeat BEFORE resuming the checks
updateHeartbeat();
_paused = false;
}
void run() override {
while (!_quit) {
QThread::sleep(HEARTBEAT_UPDATE_INTERVAL_SECS);
// Don't do heartbeat detection under nsight
if (nsightActive() || _paused) {
if (_paused) {
continue;
}
uint64_t lastHeartbeat = _heartbeat; // sample atomic _heartbeat, because we could context switch away and have it updated on us
@ -1103,9 +1113,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
// Make sure we don't time out during slow operations at startup
updateHeartbeat();
// 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();
// sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
// The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
static const QString TESTER = "HIFI_TESTER";
@ -2220,25 +2227,21 @@ void Application::initializeGL() {
initDisplay();
qCDebug(interfaceapp, "Initialized Display.");
#ifdef Q_OS_OSX
// FIXME: on mac os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread.
DeadlockWatchdogThread::pause();
#endif
// FIXME: on low end systems os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread.
DeadlockWatchdogThread::withPause([&] {
// Set up the render engine
render::CullFunctor cullFunctor = LODManager::shouldRender;
static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
bool isDeferred = !QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD);
_renderEngine->addJob<UpdateSceneTask>("UpdateScene");
_renderEngine->addJob<SecondaryCameraRenderTask>("SecondaryCameraJob", cullFunctor);
_renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, isDeferred);
_renderEngine->load();
_renderEngine->registerScene(_main3DScene);
// Set up the render engine
render::CullFunctor cullFunctor = LODManager::shouldRender;
static const QString RENDER_FORWARD = "HIFI_RENDER_FORWARD";
bool isDeferred = !QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD);
_renderEngine->addJob<UpdateSceneTask>("UpdateScene");
_renderEngine->addJob<SecondaryCameraRenderTask>("SecondaryCameraJob", cullFunctor);
_renderEngine->addJob<RenderViewTask>("RenderMainView", cullFunctor, isDeferred);
#ifdef Q_OS_OSX
DeadlockWatchdogThread::resume();
#endif
_renderEngine->load();
_renderEngine->registerScene(_main3DScene);
// 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();
});
_offscreenContext = new OffscreenGLCanvas();
_offscreenContext->setObjectName("MainThreadContext");