mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 02:17:11 +02:00
Fix oculus crash on switching display plugin to something else
This commit is contained in:
parent
0b12812ea4
commit
1f83d04423
10 changed files with 133 additions and 68 deletions
|
@ -64,6 +64,7 @@
|
|||
|
||||
#include <EntityScriptingInterface.h>
|
||||
#include <ErrorDialog.h>
|
||||
#include <Finally.h>
|
||||
#include <FramebufferCache.h>
|
||||
#include <gpu/Batch.h>
|
||||
#include <gpu/Context.h>
|
||||
|
@ -1009,6 +1010,16 @@ void Application::paintGL() {
|
|||
if (nullptr == _displayPlugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Some plugins process message events, potentially leading to
|
||||
// re-entering a paint event. don't allow further processing if this
|
||||
// happens
|
||||
if (_inPaint) {
|
||||
return;
|
||||
}
|
||||
_inPaint = true;
|
||||
Finally clearFlagLambda([this] { _inPaint = false; });
|
||||
|
||||
auto displayPlugin = getActiveDisplayPlugin();
|
||||
displayPlugin->preRender();
|
||||
_offscreenContext->makeCurrent();
|
||||
|
@ -1219,7 +1230,6 @@ void Application::paintGL() {
|
|||
_frameCount++;
|
||||
Stats::getInstance()->setRenderDetails(renderArgs._details);
|
||||
|
||||
|
||||
// Reset the gpu::Context Stages
|
||||
// Back to the default framebuffer;
|
||||
gpu::Batch batch;
|
||||
|
@ -4703,7 +4713,23 @@ void Application::updateDisplayMode() {
|
|||
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
DisplayPluginPointer oldDisplayPlugin = _displayPlugin;
|
||||
if (oldDisplayPlugin != newDisplayPlugin) {
|
||||
if (newDisplayPlugin == oldDisplayPlugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Some plugins *cough* Oculus *cough* process message events from inside their
|
||||
// display function, and we don't want to change the display plugin underneath
|
||||
// the paintGL call, so we need to guard against that
|
||||
if (_inPaint) {
|
||||
qDebug() << "Deferring plugin switch until out of painting";
|
||||
// Have the old plugin stop requesting renders
|
||||
oldDisplayPlugin->stop();
|
||||
QCoreApplication::postEvent(this, new LambdaEvent([this] {
|
||||
updateDisplayMode();
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_currentDisplayPluginActions.isEmpty()) {
|
||||
auto menu = Menu::getInstance();
|
||||
foreach(auto itemInfo, _currentDisplayPluginActions) {
|
||||
|
@ -4749,7 +4775,6 @@ void Application::updateDisplayMode() {
|
|||
}
|
||||
emit activeDisplayPluginChanged();
|
||||
resetSensors();
|
||||
}
|
||||
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
|
||||
}
|
||||
|
||||
|
@ -5052,3 +5077,15 @@ void Application::crashApplication() {
|
|||
|
||||
qCDebug(interfaceapp) << "Intentionally crashed Interface";
|
||||
}
|
||||
|
||||
void Application::setActiveDisplayPlugin(const QString& pluginName) {
|
||||
auto menu = Menu::getInstance();
|
||||
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
|
||||
QString name = displayPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
if (pluginName == name) {
|
||||
action->setChecked(true);
|
||||
}
|
||||
}
|
||||
updateDisplayMode();
|
||||
}
|
||||
|
|
|
@ -673,6 +673,7 @@ private:
|
|||
int _simsPerSecondReport = 0;
|
||||
quint64 _lastSimsPerSecondUpdate = 0;
|
||||
bool _isForeground = true; // starts out assumed to be in foreground
|
||||
bool _inPaint = false;
|
||||
|
||||
friend class PluginContainerProxy;
|
||||
};
|
||||
|
|
|
@ -147,15 +147,3 @@ void PluginContainerProxy::showDisplayPluginsTools() {
|
|||
QGLWidget* PluginContainerProxy::getPrimarySurface() {
|
||||
return qApp->_glWidget;
|
||||
}
|
||||
|
||||
void Application::setActiveDisplayPlugin(const QString& pluginName) {
|
||||
auto menu = Menu::getInstance();
|
||||
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
|
||||
QString name = displayPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
if (pluginName == name) {
|
||||
action->setChecked(true);
|
||||
}
|
||||
}
|
||||
updateDisplayMode();
|
||||
}
|
||||
|
|
|
@ -57,6 +57,11 @@ public:
|
|||
|
||||
// Rendering support
|
||||
|
||||
// Stop requesting renders, but don't do full deactivation
|
||||
// needed to work around the issues caused by Oculus
|
||||
// processing messages in the middle of submitFrame
|
||||
virtual void stop() = 0;
|
||||
|
||||
/**
|
||||
* Called by the application before the frame rendering. Can be used for
|
||||
* render timing related calls (for instance, the Oculus begin frame timing
|
||||
|
@ -120,6 +125,7 @@ public:
|
|||
virtual void resetSensors() {}
|
||||
virtual float devicePixelRatio() { return 1.0; }
|
||||
|
||||
|
||||
static const QString& MENU_PATH();
|
||||
signals:
|
||||
void recommendedFramebufferSizeChanged(const QSize & size);
|
||||
|
|
|
@ -30,3 +30,4 @@ void NullDisplayPlugin::finishFrame() {}
|
|||
|
||||
void NullDisplayPlugin::activate() {}
|
||||
void NullDisplayPlugin::deactivate() {}
|
||||
void NullDisplayPlugin::stop() {}
|
||||
|
|
|
@ -17,6 +17,7 @@ public:
|
|||
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
void stop() override;
|
||||
|
||||
virtual glm::uvec2 getRecommendedRenderSize() const override;
|
||||
virtual bool hasFocus() const override;
|
||||
|
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
OpenGLDisplayPlugin::OpenGLDisplayPlugin() {
|
||||
connect(&_timer, &QTimer::timeout, this, [&] {
|
||||
if (_active) {
|
||||
emit requestRender();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -56,10 +58,17 @@ void OpenGLDisplayPlugin::customizeContext() {
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::activate() {
|
||||
_active = true;
|
||||
_timer.start(1);
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::stop() {
|
||||
_active = false;
|
||||
_timer.stop();
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::deactivate() {
|
||||
_active = false;
|
||||
_timer.stop();
|
||||
|
||||
makeCurrent();
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
|
||||
virtual void activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
virtual void stop() override;
|
||||
virtual bool eventFilter(QObject* receiver, QEvent* event) override;
|
||||
|
||||
virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) override;
|
||||
|
@ -44,6 +44,7 @@ protected:
|
|||
mutable QTimer _timer;
|
||||
ProgramPtr _program;
|
||||
ShapeWrapperPtr _plane;
|
||||
bool _active{ false };
|
||||
bool _vsyncSupported{ false };
|
||||
};
|
||||
|
||||
|
|
|
@ -350,11 +350,6 @@ void OculusDisplayPlugin::deactivate() {
|
|||
}
|
||||
|
||||
void OculusDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) {
|
||||
static bool inDisplay = false;
|
||||
if (inDisplay) {
|
||||
return;
|
||||
}
|
||||
inDisplay = true;
|
||||
#if (OVR_MAJOR_VERSION >= 6)
|
||||
using namespace oglplus;
|
||||
// Need to make sure only the display plugin is responsible for
|
||||
|
@ -420,7 +415,6 @@ void OculusDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSi
|
|||
|
||||
++_frameIndex;
|
||||
#endif
|
||||
inDisplay = false;
|
||||
}
|
||||
|
||||
// Pass input events on to the application
|
||||
|
|
27
libraries/shared/src/Finally.h
Normal file
27
libraries/shared/src/Finally.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/09/01
|
||||
// Copyright 2013-2105 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
// Simulates a java finally block by executing a lambda when an instance leaves
|
||||
// scope
|
||||
|
||||
#include <functional>
|
||||
|
||||
#pragma once
|
||||
#ifndef hifi_Finally_h
|
||||
#define hifi_Finally_h
|
||||
|
||||
class Finally {
|
||||
public:
|
||||
template <typename F>
|
||||
Finally(F f) : _f(f) {}
|
||||
~Finally() { _f(); }
|
||||
private:
|
||||
std::function<void()> _f;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue