Merge pull request #6597 from jherico/scorpius

Fix occasional crashes switching from the Oculus plugin
This commit is contained in:
Philip Rosedale 2015-12-09 10:33:48 -08:00
commit a580442b92
3 changed files with 33 additions and 10 deletions

View file

@ -54,6 +54,7 @@ public:
} }
virtual void run() override { virtual void run() override {
OpenGLDisplayPlugin* currentPlugin{ nullptr };
Q_ASSERT(_context); Q_ASSERT(_context);
while (!_shutdown) { while (!_shutdown) {
if (_pendingMainThreadOperation) { if (_pendingMainThreadOperation) {
@ -81,12 +82,13 @@ public:
// Check if we have a new plugin to activate // Check if we have a new plugin to activate
if (_newPlugin != nullptr) { if (_newPlugin != nullptr) {
// Deactivate the old plugin // Deactivate the old plugin
if (_activePlugin != nullptr) { if (currentPlugin != nullptr) {
_activePlugin->uncustomizeContext(); currentPlugin->uncustomizeContext();
currentPlugin->enableDeactivate();
} }
_newPlugin->customizeContext(); _newPlugin->customizeContext();
_activePlugin = _newPlugin; currentPlugin = _newPlugin;
_newPlugin = nullptr; _newPlugin = nullptr;
} }
_context->doneCurrent(); _context->doneCurrent();
@ -94,20 +96,21 @@ public:
} }
// If there's no active plugin, just sleep // If there's no active plugin, just sleep
if (_activePlugin == nullptr) { if (currentPlugin == nullptr) {
QThread::usleep(100); QThread::usleep(100);
continue; continue;
} }
// take the latest texture and present it // take the latest texture and present it
_context->makeCurrent(); _context->makeCurrent();
_activePlugin->present(); currentPlugin->present();
_context->doneCurrent(); _context->doneCurrent();
} }
_context->makeCurrent(); _context->makeCurrent();
if (_activePlugin) { if (currentPlugin) {
_activePlugin->uncustomizeContext(); currentPlugin->uncustomizeContext();
currentPlugin->enableDeactivate();
} }
_context->doneCurrent(); _context->doneCurrent();
_context->moveToThread(qApp->thread()); _context->moveToThread(qApp->thread());
@ -147,7 +150,6 @@ private:
bool _finishedMainThreadOperation { false }; bool _finishedMainThreadOperation { false };
QThread* _mainThread { nullptr }; QThread* _mainThread { nullptr };
OpenGLDisplayPlugin* _newPlugin { nullptr }; OpenGLDisplayPlugin* _newPlugin { nullptr };
OpenGLDisplayPlugin* _activePlugin { nullptr };
QGLContext* _context { nullptr }; QGLContext* _context { nullptr };
}; };
@ -208,11 +210,16 @@ void OpenGLDisplayPlugin::stop() {
} }
void OpenGLDisplayPlugin::deactivate() { void OpenGLDisplayPlugin::deactivate() {
{
Lock lock(_mutex);
_deactivateWait.wait(lock, [&]{ return _uncustomized; });
}
_timer.stop(); _timer.stop();
DisplayPlugin::deactivate(); DisplayPlugin::deactivate();
} }
void OpenGLDisplayPlugin::customizeContext() { void OpenGLDisplayPlugin::customizeContext() {
_uncustomized = false;
auto presentThread = DependencyManager::get<PresentThread>(); auto presentThread = DependencyManager::get<PresentThread>();
Q_ASSERT(thread() == presentThread->thread()); Q_ASSERT(thread() == presentThread->thread());
@ -233,6 +240,7 @@ void OpenGLDisplayPlugin::uncustomizeContext() {
_plane.reset(); _plane.reset();
} }
// Pressing Alt (and Meta) key alone activates the menubar because its style inherits the // Pressing Alt (and Meta) key alone activates the menubar because its style inherits the
// SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to // SHMenuBarAltKeyNavigation from QWindowsStyle. This makes it impossible for a scripts to
// receive keyPress events for the Alt (and Meta) key in a reliable manner. // receive keyPress events for the Alt (and Meta) key in a reliable manner.
@ -380,3 +388,9 @@ QImage OpenGLDisplayPlugin::getScreenshot() const {
}); });
return result; return result;
} }
void OpenGLDisplayPlugin::enableDeactivate() {
Lock lock(_mutex);
_uncustomized = true;
_deactivateWait.notify_one();
}

View file

@ -9,6 +9,8 @@
#include "DisplayPlugin.h" #include "DisplayPlugin.h"
#include <condition_variable>
#include <QtCore/QTimer> #include <QtCore/QTimer>
#include <GLMHelpers.h> #include <GLMHelpers.h>
@ -18,8 +20,9 @@
class OpenGLDisplayPlugin : public DisplayPlugin { class OpenGLDisplayPlugin : public DisplayPlugin {
protected: protected:
using Mutex = std::recursive_mutex; using Mutex = std::mutex;
using Lock = std::unique_lock<Mutex>; using Lock = std::unique_lock<Mutex>;
using Condition = std::condition_variable;
public: public:
OpenGLDisplayPlugin(); OpenGLDisplayPlugin();
virtual void activate() override; virtual void activate() override;
@ -82,6 +85,12 @@ protected:
GLTextureEscrow _sceneTextureEscrow; GLTextureEscrow _sceneTextureEscrow;
bool _vsyncSupported { false }; bool _vsyncSupported { false };
private:
void enableDeactivate();
Condition _deactivateWait;
bool _uncustomized{ false };
}; };

View file

@ -230,7 +230,7 @@ void OculusDisplayPlugin::internalPresent() {
viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1]; viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1];
ovrLayerHeader* layers = &_sceneLayer.Header; ovrLayerHeader* layers = &_sceneLayer.Header;
ovrResult result = ovr_SubmitFrame(_hmd, 0, &viewScaleDesc, &layers, 1); ovrResult result = ovr_SubmitFrame(_hmd, frameIndex, &viewScaleDesc, &layers, 1);
if (!OVR_SUCCESS(result)) { if (!OVR_SUCCESS(result)) {
qDebug() << result; qDebug() << result;
} }