mirror of
https://github.com/lubosz/overte.git
synced 2025-08-07 18:21:16 +02:00
Reduce present traffic on main thread event queue.
In an effort to diagnose the root cause of several deadlocks, it seems possible that the main thread event queue can grow to a size where it can take many seconds to drain. This PR attempts to address this in two ways: * Change the connection between the DisplayPlugin::presented signal and the Application::onPresent slot to be a DirectConnection. This should prevent the main thread from filling up with signal events. * Within Applicaiton::onPresent use an atomic counter to prevent the main thread from filling up with repeated Idle events.
This commit is contained in:
parent
4dcce6ef45
commit
a2a6cd0c7a
3 changed files with 61 additions and 8 deletions
|
@ -207,6 +207,17 @@
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
#include <VersionHelpers.h>
|
#include <VersionHelpers.h>
|
||||||
|
|
||||||
|
#ifdef DEBUG_EVENT_QUEUE
|
||||||
|
// This is a HACK that uses private headers included with the qt source distrubution.
|
||||||
|
// To use this feature you need to add these directores to your include path:
|
||||||
|
// E:/Qt/5.9.1/Src/qtbase/include/QtCore/5.9.1/QtCore
|
||||||
|
// E:/Qt/5.9.1/Src/qtbase/include/QtCore/5.9.1
|
||||||
|
#define QT_BOOTSTRAPPED
|
||||||
|
#include <private/qthread_p.h>
|
||||||
|
#include <private/qobject_p.h>
|
||||||
|
#undef QT_BOOTSTRAPPED
|
||||||
|
#endif
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
_declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
|
||||||
}
|
}
|
||||||
|
@ -264,9 +275,7 @@ private:
|
||||||
switch ((int)event->type()) {
|
switch ((int)event->type()) {
|
||||||
case ApplicationEvent::Render:
|
case ApplicationEvent::Render:
|
||||||
render();
|
render();
|
||||||
// Ensure we never back up the render events. Each render should be triggered only in response
|
qApp->_pendingRenderEventCount--;
|
||||||
// to the NEXT render event after the last render occured
|
|
||||||
QCoreApplication::removePostedEvents(this, ApplicationEvent::Render);
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -2712,9 +2721,15 @@ bool Application::importFromZIP(const QString& filePath) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// thread-safe
|
||||||
void Application::onPresent(quint32 frameCount) {
|
void Application::onPresent(quint32 frameCount) {
|
||||||
postEvent(this, new QEvent((QEvent::Type)ApplicationEvent::Idle), Qt::HighEventPriority);
|
if (_pendingIdleEventCount.load() == 0) {
|
||||||
if (_renderEventHandler && !isAboutToQuit()) {
|
_pendingIdleEventCount++;
|
||||||
|
postEvent(this, new QEvent((QEvent::Type)ApplicationEvent::Idle), Qt::HighEventPriority);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_renderEventHandler && !isAboutToQuit() && _pendingRenderEventCount.load() == 0) {
|
||||||
|
_pendingRenderEventCount++;
|
||||||
postEvent(_renderEventHandler, new QEvent((QEvent::Type)ApplicationEvent::Render));
|
postEvent(_renderEventHandler, new QEvent((QEvent::Type)ApplicationEvent::Render));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2781,7 +2796,26 @@ bool Application::handleFileOpenEvent(QFileOpenEvent* fileEvent) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_EVENT_QUEUE
|
||||||
|
static int getEventQueueSize(QThread* thread) {
|
||||||
|
auto threadData = QThreadData::get2(thread);
|
||||||
|
QMutexLocker locker(&threadData->postEventList.mutex);
|
||||||
|
return threadData->postEventList.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dumpEventQueue(QThread* thread) {
|
||||||
|
auto threadData = QThreadData::get2(thread);
|
||||||
|
QMutexLocker locker(&threadData->postEventList.mutex);
|
||||||
|
qDebug() << "AJT: event list, size =" << threadData->postEventList.size();
|
||||||
|
for (auto& postEvent : threadData->postEventList) {
|
||||||
|
QEvent::Type type = (postEvent.event ? postEvent.event->type() : QEvent::None);
|
||||||
|
qDebug() << "AJT: " << type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // DEBUG_EVENT_QUEUE
|
||||||
|
|
||||||
bool Application::event(QEvent* event) {
|
bool Application::event(QEvent* event) {
|
||||||
|
|
||||||
if (!Menu::getInstance()) {
|
if (!Menu::getInstance()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2801,8 +2835,18 @@ bool Application::event(QEvent* event) {
|
||||||
// see (windowMinimizedChanged)
|
// see (windowMinimizedChanged)
|
||||||
case ApplicationEvent::Idle:
|
case ApplicationEvent::Idle:
|
||||||
idle();
|
idle();
|
||||||
// Don't process extra idle events that arrived in the event queue while we were doing this idle
|
|
||||||
QCoreApplication::removePostedEvents(this, ApplicationEvent::Idle);
|
#ifdef DEBUG_EVENT_QUEUE
|
||||||
|
{
|
||||||
|
int count = getEventQueueSize(QThread::currentThread());
|
||||||
|
if (count > 400) {
|
||||||
|
dumpEventQueue(QThread::currentThread());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // DEBUG_EVENT_QUEUE
|
||||||
|
|
||||||
|
_pendingIdleEventCount--;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case QEvent::MouseMove:
|
case QEvent::MouseMove:
|
||||||
|
@ -7203,7 +7247,7 @@ void Application::updateDisplayMode() {
|
||||||
_offscreenContext->makeCurrent();
|
_offscreenContext->makeCurrent();
|
||||||
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
||||||
_displayPlugin = newDisplayPlugin;
|
_displayPlugin = newDisplayPlugin;
|
||||||
connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent);
|
connect(_displayPlugin.get(), &DisplayPlugin::presented, this, &Application::onPresent, Qt::DirectConnection);
|
||||||
auto desktop = offscreenUi->getDesktop();
|
auto desktop = offscreenUi->getDesktop();
|
||||||
if (desktop) {
|
if (desktop) {
|
||||||
desktop->setProperty("repositionLocked", wasRepositionLocked);
|
desktop->setProperty("repositionLocked", wasRepositionLocked);
|
||||||
|
|
|
@ -717,5 +717,8 @@ private:
|
||||||
LaserPointerManager _laserPointerManager;
|
LaserPointerManager _laserPointerManager;
|
||||||
|
|
||||||
friend class RenderEventHandler;
|
friend class RenderEventHandler;
|
||||||
|
|
||||||
|
std::atomic<int> _pendingIdleEventCount { 0 };
|
||||||
|
std::atomic<int> _pendingRenderEventCount { 0 };
|
||||||
};
|
};
|
||||||
#endif // hifi_Application_h
|
#endif // hifi_Application_h
|
||||||
|
|
|
@ -72,6 +72,12 @@ void Application::paintGL() {
|
||||||
{
|
{
|
||||||
QMutexLocker viewLocker(&_renderArgsMutex);
|
QMutexLocker viewLocker(&_renderArgsMutex);
|
||||||
renderArgs = _appRenderArgs._renderArgs;
|
renderArgs = _appRenderArgs._renderArgs;
|
||||||
|
|
||||||
|
// don't render if there is no context.
|
||||||
|
if (!_appRenderArgs._renderArgs._context) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
HMDSensorPose = _appRenderArgs._headPose;
|
HMDSensorPose = _appRenderArgs._headPose;
|
||||||
eyeToWorld = _appRenderArgs._eyeToWorld;
|
eyeToWorld = _appRenderArgs._eyeToWorld;
|
||||||
sensorToWorld = _appRenderArgs._sensorToWorld;
|
sensorToWorld = _appRenderArgs._sensorToWorld;
|
||||||
|
|
Loading…
Reference in a new issue