mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-06 14:23:23 +02:00
SharedObject::onRender deadlock fix
Call gl::globalRelease() for paused surfaces, this fixes a very common deadlock on mac. But for PC, by inspection, a race condition could occur over the _syncRequested boolean, between the main and qml rendering thread. To fix this, we split render and renderSync into separate messages.
This commit is contained in:
parent
86f562de1b
commit
c33ad93a55
4 changed files with 24 additions and 8 deletions
|
@ -31,6 +31,10 @@ bool RenderEventHandler::event(QEvent* e) {
|
|||
onRender();
|
||||
return true;
|
||||
|
||||
case OffscreenEvent::RenderSync:
|
||||
onRenderSync();
|
||||
return true;
|
||||
|
||||
case OffscreenEvent::Initialize:
|
||||
onInitalize();
|
||||
return true;
|
||||
|
@ -106,6 +110,14 @@ void RenderEventHandler::resize() {
|
|||
}
|
||||
|
||||
void RenderEventHandler::onRender() {
|
||||
qmlRender(false);
|
||||
}
|
||||
|
||||
void RenderEventHandler::onRenderSync() {
|
||||
qmlRender(true);
|
||||
}
|
||||
|
||||
void RenderEventHandler::qmlRender(bool sceneGraphSync) {
|
||||
if (_shared->isQuit()) {
|
||||
return;
|
||||
}
|
||||
|
@ -117,7 +129,8 @@ void RenderEventHandler::onRender() {
|
|||
PROFILE_RANGE(render_qml_gl, __FUNCTION__);
|
||||
|
||||
gl::globalLock();
|
||||
if (!_shared->preRender()) {
|
||||
if (!_shared->preRender(sceneGraphSync)) {
|
||||
gl::globalRelease();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ public:
|
|||
enum Type {
|
||||
Initialize = QEvent::User + 1,
|
||||
Render,
|
||||
RenderSync,
|
||||
Quit
|
||||
};
|
||||
|
||||
|
@ -45,6 +46,8 @@ private:
|
|||
void onInitalize();
|
||||
void resize();
|
||||
void onRender();
|
||||
void onRenderSync();
|
||||
void qmlRender(bool sceneGraphSync);
|
||||
void onQuit();
|
||||
|
||||
SharedObject* const _shared;
|
||||
|
@ -59,4 +62,4 @@ private:
|
|||
|
||||
}}} // namespace hifi::qml::impl
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -344,17 +344,17 @@ void SharedObject::setSize(const QSize& size) {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool SharedObject::preRender() {
|
||||
bool SharedObject::preRender(bool sceneGraphSync) {
|
||||
#ifndef DISABLE_QML
|
||||
QMutexLocker lock(&_mutex);
|
||||
if (_paused) {
|
||||
if (_syncRequested) {
|
||||
if (sceneGraphSync) {
|
||||
wake();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_syncRequested) {
|
||||
if (sceneGraphSync) {
|
||||
bool syncResult = true;
|
||||
if (!nsightActive()) {
|
||||
PROFILE_RANGE(render_qml_gl, "sync")
|
||||
|
@ -364,7 +364,6 @@ bool SharedObject::preRender() {
|
|||
if (!syncResult) {
|
||||
return false;
|
||||
}
|
||||
_syncRequested = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -475,9 +474,10 @@ void SharedObject::onRender() {
|
|||
lock.unlock();
|
||||
_renderControl->polishItems();
|
||||
lock.relock();
|
||||
QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::Render));
|
||||
QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::RenderSync));
|
||||
// sync and render request, main and render threads must be synchronized
|
||||
wait();
|
||||
_syncRequested = false;
|
||||
} else {
|
||||
QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::Render));
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public:
|
|||
private:
|
||||
bool event(QEvent* e) override;
|
||||
|
||||
bool preRender();
|
||||
bool preRender(bool sceneGraphSync);
|
||||
void shutdownRendering(OffscreenGLCanvas& canvas, const QSize& size);
|
||||
// Called by the render event handler, from the render thread
|
||||
void initializeRenderControl(QOpenGLContext* context);
|
||||
|
|
Loading…
Reference in a new issue