How to pause rendering?
-
I'm trying to prevent rendering while the application state is
ApplicationSuspendedbut am stuck atm with my attempt.QScopedPointer<QQuickWindow> window ... QSemaphore renderSemaphore(1); bool releaseOnRender {}; QObject::connect(window.data(), &QQuickWindow::beforeRendering, qApp, [&] { releaseOnRender = renderSemaphore.tryAcquire(1, -1); }, Qt::DirectConnection); QObject::connect(window.data(), &QQuickWindow::afterRendering, qApp, [&] { if (releaseOnRender) { renderSemaphore.release(1); } }, Qt::DirectConnection); Qt::ApplicationState prevApplicationState = Qt::ApplicationState::ApplicationActive; QObject::connect(qApp, &QGuiApplication::applicationStateChanged, qApp, [&] (Qt::ApplicationState state) { qDebug() << "Changed state to" << state; if (state != prevApplicationState) { if (state == Qt::ApplicationState::ApplicationSuspended) { renderSemaphore.acquire(1); qDebug() << "Freezing render"; } else { renderSemaphore.release(1); qDebug() << "Releasing render"; } prevApplicationState = state; } }, Qt::DirectConnection);after initially being blocked in
renderSemaphore.tryAcquire(1, -1);,QGuiApplication::applicationStateChangedisn't responding either (though it should be a different thread (shouldn't it?)Am happy about any advice / idea on how to block, pause or stop rendering while being
ApplicationSuspended -
I'm trying to prevent rendering while the application state is
ApplicationSuspendedbut am stuck atm with my attempt.QScopedPointer<QQuickWindow> window ... QSemaphore renderSemaphore(1); bool releaseOnRender {}; QObject::connect(window.data(), &QQuickWindow::beforeRendering, qApp, [&] { releaseOnRender = renderSemaphore.tryAcquire(1, -1); }, Qt::DirectConnection); QObject::connect(window.data(), &QQuickWindow::afterRendering, qApp, [&] { if (releaseOnRender) { renderSemaphore.release(1); } }, Qt::DirectConnection); Qt::ApplicationState prevApplicationState = Qt::ApplicationState::ApplicationActive; QObject::connect(qApp, &QGuiApplication::applicationStateChanged, qApp, [&] (Qt::ApplicationState state) { qDebug() << "Changed state to" << state; if (state != prevApplicationState) { if (state == Qt::ApplicationState::ApplicationSuspended) { renderSemaphore.acquire(1); qDebug() << "Freezing render"; } else { renderSemaphore.release(1); qDebug() << "Releasing render"; } prevApplicationState = state; } }, Qt::DirectConnection);after initially being blocked in
renderSemaphore.tryAcquire(1, -1);,QGuiApplication::applicationStateChangedisn't responding either (though it should be a different thread (shouldn't it?)Am happy about any advice / idea on how to block, pause or stop rendering while being
ApplicationSuspendedI can't tell you why it's not working exactly, but I'd suggest something along these lines:
QAtomicInteger<bool> pauseFlag(false); QSemaphore pauseSemaphore; QObject::connect(window.data(), &QQuickWindow::beforeRendering, window.data(), [] () { if (pauseFlag.loadAcquire()) pauseSemaphore.acquire(); }); QObject::connect(qApp, &QGuiApplication::applicationStateChanged, qApp, [] (Qt::ApplicationState state) { switch (state) { case Qt::ApplicationState::ApplicationSuspended: pauseFlag.storeRelease(true); break; case Qt::ApplicationState::ApplicationActive: if (pauseFlag.testAndSetRelease(true, false)) pauseSemaphore.release(); break; } });PS. The
pauseFlag.storeRelease(true);can probably safely be replaced by a relaxed store. -
Something came to mind. You should check that the thread the signal is emitted from isn't the main thread, which'd explain why your code (and mine) deadlocks.