mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 05:09:23 +02:00
Merge pull request #7439 from jherico/deadlock_qml
Fix potential deadlock in QML
This commit is contained in:
commit
dbfea6ec82
2 changed files with 29 additions and 9 deletions
|
@ -23,6 +23,7 @@
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
#include <Finally.h>
|
||||||
|
|
||||||
#include "OffscreenGLCanvas.h"
|
#include "OffscreenGLCanvas.h"
|
||||||
#include "GLEscrow.h"
|
#include "GLEscrow.h"
|
||||||
|
@ -84,6 +85,7 @@ protected:
|
||||||
Queue _queue;
|
Queue _queue;
|
||||||
QMutex _mutex;
|
QMutex _mutex;
|
||||||
QWaitCondition _waitCondition;
|
QWaitCondition _waitCondition;
|
||||||
|
std::atomic<bool> _rendering { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Event-driven methods
|
// Event-driven methods
|
||||||
|
@ -271,15 +273,25 @@ void OffscreenQmlRenderThread::resize() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlRenderThread::render() {
|
void OffscreenQmlRenderThread::render() {
|
||||||
if (_surface->_paused) {
|
// Ensure we always release the main thread
|
||||||
|
Finally releaseMainThread([this] {
|
||||||
_waitCondition.wakeOne();
|
_waitCondition.wakeOne();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (_surface->_paused) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutexLocker locker(&_mutex);
|
_rendering = true;
|
||||||
_renderControl->sync();
|
Finally unmarkRenderingFlag([this] {
|
||||||
_waitCondition.wakeOne();
|
_rendering = false;
|
||||||
locker.unlock();
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
QMutexLocker locker(&_mutex);
|
||||||
|
_renderControl->sync();
|
||||||
|
releaseMainThread.trigger();
|
||||||
|
}
|
||||||
|
|
||||||
using namespace oglplus;
|
using namespace oglplus;
|
||||||
|
|
||||||
|
@ -292,6 +304,7 @@ void OffscreenQmlRenderThread::render() {
|
||||||
_fbo->AttachTexture(Framebuffer::Target::Draw, FramebufferAttachment::Color, *texture, 0);
|
_fbo->AttachTexture(Framebuffer::Target::Draw, FramebufferAttachment::Color, *texture, 0);
|
||||||
_fbo->Complete(Framebuffer::Target::Draw);
|
_fbo->Complete(Framebuffer::Target::Draw);
|
||||||
{
|
{
|
||||||
|
PROFILE_RANGE("qml_render->rendercontrol")
|
||||||
_renderControl->render();
|
_renderControl->render();
|
||||||
// FIXME The web browsers seem to be leaving GL in an error state.
|
// FIXME The web browsers seem to be leaving GL in an error state.
|
||||||
// Need a debug context with sync logging to figure out why.
|
// Need a debug context with sync logging to figure out why.
|
||||||
|
@ -380,8 +393,6 @@ void OffscreenQmlSurface::resize(const QSize& newSize_) {
|
||||||
std::max(static_cast<int>(scale * newSize.height()), 10));
|
std::max(static_cast<int>(scale * newSize.height()), 10));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
QSize currentSize = _renderer->_quickWindow->geometry().size();
|
QSize currentSize = _renderer->_quickWindow->geometry().size();
|
||||||
if (newSize == currentSize) {
|
if (newSize == currentSize) {
|
||||||
return;
|
return;
|
||||||
|
@ -492,7 +503,12 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::function<void(QQmlContext*, QOb
|
||||||
}
|
}
|
||||||
|
|
||||||
void OffscreenQmlSurface::updateQuick() {
|
void OffscreenQmlSurface::updateQuick() {
|
||||||
if (!_renderer || !_renderer->allowNewFrame(_maxFps)) {
|
// If we're
|
||||||
|
// a) not set up
|
||||||
|
// b) already rendering a frame
|
||||||
|
// c) rendering too fast
|
||||||
|
// then skip this
|
||||||
|
if (!_renderer || _renderer->_rendering || !_renderer->allowNewFrame(_maxFps)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,11 +518,11 @@ void OffscreenQmlSurface::updateQuick() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_render) {
|
if (_render) {
|
||||||
|
PROFILE_RANGE(__FUNCTION__);
|
||||||
// Lock the GUI size while syncing
|
// Lock the GUI size while syncing
|
||||||
QMutexLocker locker(&(_renderer->_mutex));
|
QMutexLocker locker(&(_renderer->_mutex));
|
||||||
_renderer->_queue.add(RENDER);
|
_renderer->_queue.add(RENDER);
|
||||||
_renderer->_waitCondition.wait(&(_renderer->_mutex));
|
_renderer->_waitCondition.wait(&(_renderer->_mutex));
|
||||||
|
|
||||||
_render = false;
|
_render = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,10 @@ public:
|
||||||
template <typename F>
|
template <typename F>
|
||||||
Finally(F f) : _f(f) {}
|
Finally(F f) : _f(f) {}
|
||||||
~Finally() { _f(); }
|
~Finally() { _f(); }
|
||||||
|
void trigger() {
|
||||||
|
_f();
|
||||||
|
_f = [] {};
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::function<void()> _f;
|
std::function<void()> _f;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue