mirror of
https://github.com/overte-org/overte.git
synced 2025-04-07 17:52:26 +02:00
Reduce crashes on switching display plugins
This commit is contained in:
parent
9d15c190f7
commit
7045680bc7
35 changed files with 305 additions and 316 deletions
|
@ -698,6 +698,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
ResourceCache::setRequestLimit(3);
|
||||
|
||||
_glWidget = new GLCanvas();
|
||||
getApplicationCompositor().setRenderingWidget(_glWidget);
|
||||
_window->setCentralWidget(_glWidget);
|
||||
|
||||
_window->restoreGeometry();
|
||||
|
@ -4684,10 +4685,12 @@ qreal Application::getDevicePixelRatio() {
|
|||
}
|
||||
|
||||
DisplayPlugin* Application::getActiveDisplayPlugin() {
|
||||
if (nullptr == _displayPlugin) {
|
||||
std::unique_lock<std::recursive_mutex> lock(_displayPluginLock);
|
||||
if (nullptr == _displayPlugin && QThread::currentThread() == thread()) {
|
||||
updateDisplayMode();
|
||||
Q_ASSERT(_displayPlugin);
|
||||
}
|
||||
|
||||
return _displayPlugin.get();
|
||||
}
|
||||
|
||||
|
@ -4733,6 +4736,19 @@ static void addDisplayPluginToMenu(DisplayPluginPointer displayPlugin, bool acti
|
|||
}
|
||||
|
||||
void Application::updateDisplayMode() {
|
||||
// Unsafe to call this method from anything but the main thread
|
||||
if (QThread::currentThread() != thread()) {
|
||||
qFatal("Attempted to switch display plugins from a non-main thread");
|
||||
}
|
||||
|
||||
// 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
|
||||
// The current oculus runtime doesn't do this anymore
|
||||
if (_inPaint) {
|
||||
qFatal("Attempted to switch display plugins while in painting");
|
||||
}
|
||||
|
||||
auto menu = Menu::getInstance();
|
||||
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
|
||||
|
||||
|
@ -4789,70 +4805,25 @@ void Application::updateDisplayMode() {
|
|||
}
|
||||
}
|
||||
|
||||
if (newDisplayPlugin == _displayPlugin) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (_displayPlugin) {
|
||||
_displayPlugin->deactivate();
|
||||
}
|
||||
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
DisplayPluginPointer oldDisplayPlugin = _displayPlugin;
|
||||
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();
|
||||
QTimer* timer = new QTimer();
|
||||
timer->singleShot(500, [this, timer] {
|
||||
timer->deleteLater();
|
||||
updateDisplayMode();
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (!_pluginContainer->currentDisplayActions().isEmpty()) {
|
||||
auto menu = Menu::getInstance();
|
||||
foreach(auto itemInfo, _pluginContainer->currentDisplayActions()) {
|
||||
menu->removeMenuItem(itemInfo.first, itemInfo.second);
|
||||
}
|
||||
_pluginContainer->currentDisplayActions().clear();
|
||||
}
|
||||
|
||||
if (newDisplayPlugin) {
|
||||
_offscreenContext->makeCurrent();
|
||||
newDisplayPlugin->activate();
|
||||
_offscreenContext->makeCurrent();
|
||||
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
|
||||
_offscreenContext->makeCurrent();
|
||||
}
|
||||
|
||||
oldDisplayPlugin = _displayPlugin;
|
||||
// FIXME probably excessive and useless context switching
|
||||
_offscreenContext->makeCurrent();
|
||||
newDisplayPlugin->activate();
|
||||
_offscreenContext->makeCurrent();
|
||||
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
|
||||
_offscreenContext->makeCurrent();
|
||||
getApplicationCompositor().setDisplayPlugin(newDisplayPlugin);
|
||||
_displayPlugin = newDisplayPlugin;
|
||||
getApplicationCompositor().setDisplayPlugin(_displayPlugin);
|
||||
|
||||
// If the displayPlugin is a screen based HMD, then it will want the HMDTools displayed
|
||||
// Direct Mode HMDs (like windows Oculus) will be isHmd() but will have a screen of -1
|
||||
bool newPluginWantsHMDTools = newDisplayPlugin ?
|
||||
(newDisplayPlugin->isHmd() && (newDisplayPlugin->getHmdScreen() >= 0)) : false;
|
||||
bool oldPluginWantedHMDTools = oldDisplayPlugin ?
|
||||
(oldDisplayPlugin->isHmd() && (oldDisplayPlugin->getHmdScreen() >= 0)) : false;
|
||||
|
||||
// Only show the hmd tools after the correct plugin has
|
||||
// been activated so that it's UI is setup correctly
|
||||
if (newPluginWantsHMDTools) {
|
||||
_pluginContainer->showDisplayPluginsTools();
|
||||
}
|
||||
|
||||
if (oldDisplayPlugin) {
|
||||
oldDisplayPlugin->deactivate();
|
||||
_offscreenContext->makeCurrent();
|
||||
|
||||
// if the old plugin was HMD and the new plugin is not HMD, then hide our hmdtools
|
||||
if (oldPluginWantedHMDTools && !newPluginWantsHMDTools) {
|
||||
DependencyManager::get<DialogsManager>()->hmdTools(false);
|
||||
}
|
||||
}
|
||||
emit activeDisplayPluginChanged();
|
||||
|
||||
// reset the avatar, to set head and hand palms back to a resonable default pose.
|
||||
|
|
|
@ -385,6 +385,7 @@ private:
|
|||
|
||||
OffscreenGLCanvas* _offscreenContext { nullptr };
|
||||
DisplayPluginPointer _displayPlugin;
|
||||
std::recursive_mutex _displayPluginLock;
|
||||
InputPluginList _activeInputPlugins;
|
||||
|
||||
bool _activatingDisplayPlugin { false };
|
||||
|
|
|
@ -38,8 +38,8 @@ void PluginContainerProxy::requestReset() {
|
|||
qApp->resetSensors(true);
|
||||
}
|
||||
|
||||
void PluginContainerProxy::showDisplayPluginsTools() {
|
||||
DependencyManager::get<DialogsManager>()->hmdTools(true);
|
||||
void PluginContainerProxy::showDisplayPluginsTools(bool show) {
|
||||
DependencyManager::get<DialogsManager>()->hmdTools(show);
|
||||
}
|
||||
|
||||
GLWidget* PluginContainerProxy::getPrimaryWidget() {
|
||||
|
|
|
@ -14,7 +14,7 @@ class PluginContainerProxy : public QObject, PluginContainer {
|
|||
Q_OBJECT
|
||||
PluginContainerProxy();
|
||||
virtual ~PluginContainerProxy();
|
||||
virtual void showDisplayPluginsTools() override;
|
||||
virtual void showDisplayPluginsTools(bool show = true) override;
|
||||
virtual void requestReset() override;
|
||||
virtual bool makeRenderingContextCurrent() override;
|
||||
virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override;
|
||||
|
|
|
@ -143,7 +143,9 @@ void DialogsManager::hmdTools(bool showTools) {
|
|||
}
|
||||
|
||||
void DialogsManager::hmdToolsClosed() {
|
||||
_hmdToolsDialog->hide();
|
||||
if (_hmdToolsDialog) {
|
||||
_hmdToolsDialog->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogsManager::showScriptEditor() {
|
||||
|
|
|
@ -19,8 +19,8 @@ const QString Basic2DWindowOpenGLDisplayPlugin::NAME("Desktop");
|
|||
|
||||
static const QString FULLSCREEN = "Fullscreen";
|
||||
|
||||
void Basic2DWindowOpenGLDisplayPlugin::activate() {
|
||||
WindowOpenGLDisplayPlugin::activate();
|
||||
void Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
|
||||
Parent::internalActivate();
|
||||
|
||||
_framerateActions.clear();
|
||||
_container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), FULLSCREEN,
|
||||
|
@ -37,14 +37,14 @@ void Basic2DWindowOpenGLDisplayPlugin::activate() {
|
|||
|
||||
void Basic2DWindowOpenGLDisplayPlugin::submitSceneTexture(uint32_t frameIndex, const gpu::TexturePointer& sceneTexture) {
|
||||
_wantVsync = true; // always
|
||||
WindowOpenGLDisplayPlugin::submitSceneTexture(frameIndex, sceneTexture);
|
||||
Parent::submitSceneTexture(frameIndex, sceneTexture);
|
||||
}
|
||||
|
||||
void Basic2DWindowOpenGLDisplayPlugin::internalPresent() {
|
||||
if (_wantVsync != isVsyncEnabled()) {
|
||||
enableVsync(_wantVsync);
|
||||
}
|
||||
WindowOpenGLDisplayPlugin::internalPresent();
|
||||
Parent::internalPresent();
|
||||
}
|
||||
|
||||
static const uint32_t MIN_THROTTLE_CHECK_FRAMES = 60;
|
||||
|
|
|
@ -7,22 +7,22 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include "WindowOpenGLDisplayPlugin.h"
|
||||
#include "OpenGLDisplayPlugin.h"
|
||||
|
||||
const float TARGET_FRAMERATE_Basic2DWindowOpenGL = 60.0f;
|
||||
|
||||
class QScreen;
|
||||
class QAction;
|
||||
|
||||
class Basic2DWindowOpenGLDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
||||
class Basic2DWindowOpenGLDisplayPlugin : public OpenGLDisplayPlugin {
|
||||
Q_OBJECT
|
||||
|
||||
using Parent = OpenGLDisplayPlugin;
|
||||
public:
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
|
||||
virtual float getTargetFrameRate() override { return _framerateTarget ? (float) _framerateTarget : TARGET_FRAMERATE_Basic2DWindowOpenGL; }
|
||||
|
||||
virtual void activate() override;
|
||||
virtual void internalActivate() override;
|
||||
|
||||
virtual void submitSceneTexture(uint32_t frameIndex, const gpu::TexturePointer& sceneTexture) override;
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include <NumericalConstants.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <plugins/PluginManager.h>
|
||||
#include <plugins/PluginContainer.h>
|
||||
#include <CursorManager.h>
|
||||
#include <gl/GLWidget.h>
|
||||
|
||||
|
@ -188,16 +187,15 @@ void CompositorHelper::handleLeaveEvent() {
|
|||
if (shouldCaptureMouse()) {
|
||||
|
||||
//QWidget* mainWidget = (QWidget*)qApp->getWindow();
|
||||
static auto renderingWidget = PluginContainer::getInstance().getPrimaryWidget();
|
||||
static QWidget* mainWidget = nullptr;
|
||||
if (mainWidget == nullptr) {
|
||||
mainWidget = renderingWidget->parentWidget();
|
||||
if (mainWidget == nullptr && _renderingWidget != nullptr) {
|
||||
mainWidget = _renderingWidget->parentWidget();
|
||||
}
|
||||
QRect mainWidgetFrame;
|
||||
{
|
||||
mainWidgetFrame = renderingWidget->geometry();
|
||||
mainWidgetFrame = _renderingWidget->geometry();
|
||||
auto topLeft = mainWidgetFrame.topLeft();
|
||||
auto topLeftScreen = renderingWidget->mapToGlobal(topLeft);
|
||||
auto topLeftScreen = _renderingWidget->mapToGlobal(topLeft);
|
||||
mainWidgetFrame.moveTopLeft(topLeftScreen);
|
||||
}
|
||||
QRect uncoveredRect = mainWidgetFrame;
|
||||
|
@ -293,16 +291,17 @@ void CompositorHelper::sendFakeMouseEvent() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (_renderingWidget) {
|
||||
// in HMD mode we need to fake our mouse moves...
|
||||
QPoint globalPos(_reticlePositionInHMD.x, _reticlePositionInHMD.y);
|
||||
auto button = Qt::NoButton;
|
||||
auto buttons = QApplication::mouseButtons();
|
||||
auto modifiers = QApplication::keyboardModifiers();
|
||||
static auto renderingWidget = PluginContainer::getInstance().getPrimaryWidget();
|
||||
QMouseEvent event(QEvent::MouseMove, globalPos, button, buttons, modifiers);
|
||||
_fakeMouseEvent = true;
|
||||
qApp->sendEvent(renderingWidget, &event);
|
||||
_fakeMouseEvent = false;
|
||||
QPoint globalPos(_reticlePositionInHMD.x, _reticlePositionInHMD.y);
|
||||
auto button = Qt::NoButton;
|
||||
auto buttons = QApplication::mouseButtons();
|
||||
auto modifiers = QApplication::keyboardModifiers();
|
||||
QMouseEvent event(QEvent::MouseMove, globalPos, button, buttons, modifiers);
|
||||
_fakeMouseEvent = true;
|
||||
qApp->sendEvent(_renderingWidget, &event);
|
||||
_fakeMouseEvent = false;
|
||||
}
|
||||
}
|
||||
|
||||
void CompositorHelper::setReticlePosition(const glm::vec2& position, bool sendFakeEvent) {
|
||||
|
@ -496,9 +495,8 @@ glm::mat4 CompositorHelper::getReticleTransform(const glm::mat4& eyePose, const
|
|||
result = glm::scale(pointerTransform, reticleScale);
|
||||
} else {
|
||||
static const float CURSOR_PIXEL_SIZE = 32.0f;
|
||||
static auto renderingWidget = PluginContainer::getInstance().getPrimaryWidget();
|
||||
const auto canvasSize = vec2(toGlm(renderingWidget->size()));;
|
||||
vec2 mousePosition = toGlm(renderingWidget->mapFromGlobal(QCursor::pos()));
|
||||
const auto canvasSize = vec2(toGlm(_renderingWidget->size()));;
|
||||
vec2 mousePosition = toGlm(_renderingWidget->mapFromGlobal(QCursor::pos()));
|
||||
mousePosition /= canvasSize;
|
||||
mousePosition *= 2.0;
|
||||
mousePosition -= 1.0;
|
||||
|
|
|
@ -48,6 +48,7 @@ public:
|
|||
static const vec2 MOUSE_EXTENTS_PIXELS;
|
||||
|
||||
CompositorHelper();
|
||||
void setRenderingWidget(QWidget* widget) { _renderingWidget = widget; }
|
||||
|
||||
bool calculateRayUICollisionPoint(const glm::vec3& position, const glm::vec3& direction, glm::vec3& result) const;
|
||||
|
||||
|
@ -126,6 +127,7 @@ private:
|
|||
DisplayPluginPointer _currentDisplayPlugin;
|
||||
glm::mat4 _currentCamera;
|
||||
uint32_t _currentFrame { 0 };
|
||||
QWidget* _renderingWidget{ nullptr };
|
||||
|
||||
//// Support for hovering and tooltips
|
||||
//static EntityItemID _noItemId;
|
||||
|
|
|
@ -30,8 +30,6 @@ void NullDisplayPlugin::submitOverlayTexture(const gpu::TexturePointer& overlayT
|
|||
_container->releaseOverlayTexture(overlayTexture);
|
||||
}
|
||||
|
||||
void NullDisplayPlugin::stop() {}
|
||||
|
||||
QImage NullDisplayPlugin::getScreenshot() const {
|
||||
return QImage();
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@ public:
|
|||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual grouping getGrouping() const override { return DEVELOPER; }
|
||||
|
||||
void stop() override;
|
||||
|
||||
virtual glm::uvec2 getRecommendedRenderSize() const override;
|
||||
virtual bool hasFocus() const override;
|
||||
virtual void submitSceneTexture(uint32_t frameIndex, const gpu::TexturePointer& sceneTexture) override;
|
||||
|
|
|
@ -54,6 +54,9 @@ public:
|
|||
|
||||
void shutdown() {
|
||||
if (isRunning()) {
|
||||
// First ensure that we turn off any current display plugin
|
||||
setNewDisplayPlugin(nullptr);
|
||||
|
||||
Lock lock(_mutex);
|
||||
_shutdown = true;
|
||||
_condition.wait(lock, [&] { return !_shutdown; });
|
||||
|
@ -64,7 +67,10 @@ public:
|
|||
|
||||
void setNewDisplayPlugin(OpenGLDisplayPlugin* plugin) {
|
||||
Lock lock(_mutex);
|
||||
_newPlugin = plugin;
|
||||
if (isRunning()) {
|
||||
_newPluginQueue.push(plugin);
|
||||
_condition.wait(lock, [=]()->bool { return _newPluginQueue.empty(); });
|
||||
}
|
||||
}
|
||||
|
||||
void setContext(QGLContext * context) {
|
||||
|
@ -98,37 +104,42 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// Check before lock
|
||||
if (_newPlugin != nullptr) {
|
||||
// Check for a new display plugin
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
_context->makeCurrent();
|
||||
// Check if we have a new plugin to activate
|
||||
if (_newPlugin != nullptr) {
|
||||
// Deactivate the old plugin
|
||||
if (currentPlugin != nullptr) {
|
||||
try {
|
||||
currentPlugin->uncustomizeContext();
|
||||
} catch (const oglplus::Error& error) {
|
||||
qWarning() << "OpenGL error in uncustomizeContext: " << error.what();
|
||||
while (!_newPluginQueue.empty()) {
|
||||
auto newPlugin = _newPluginQueue.front();
|
||||
if (newPlugin != currentPlugin) {
|
||||
// Deactivate the old plugin
|
||||
if (currentPlugin != nullptr) {
|
||||
try {
|
||||
currentPlugin->uncustomizeContext();
|
||||
} catch (const oglplus::Error& error) {
|
||||
qWarning() << "OpenGL error in uncustomizeContext: " << error.what();
|
||||
}
|
||||
}
|
||||
currentPlugin->enableDeactivate();
|
||||
}
|
||||
|
||||
try {
|
||||
_newPlugin->customizeContext();
|
||||
} catch (const oglplus::Error& error) {
|
||||
qWarning() << "OpenGL error in customizeContext: " << error.what();
|
||||
if (newPlugin) {
|
||||
try {
|
||||
newPlugin->customizeContext();
|
||||
} catch (const oglplus::Error& error) {
|
||||
qWarning() << "OpenGL error in customizeContext: " << error.what();
|
||||
}
|
||||
}
|
||||
currentPlugin = newPlugin;
|
||||
_newPluginQueue.pop();
|
||||
_condition.notify_one();
|
||||
}
|
||||
currentPlugin = _newPlugin;
|
||||
_newPlugin = nullptr;
|
||||
}
|
||||
_context->doneCurrent();
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
// If there's no active plugin, just sleep
|
||||
if (currentPlugin == nullptr) {
|
||||
QThread::usleep(100);
|
||||
// Minimum sleep ends up being about 2 ms anyway
|
||||
QThread::msleep(1);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -146,15 +157,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
_context->makeCurrent();
|
||||
if (currentPlugin) {
|
||||
currentPlugin->uncustomizeContext();
|
||||
currentPlugin->enableDeactivate();
|
||||
}
|
||||
_context->doneCurrent();
|
||||
_context->moveToThread(qApp->thread());
|
||||
|
||||
Lock lock(_mutex);
|
||||
_context->moveToThread(qApp->thread());
|
||||
_shutdown = false;
|
||||
_condition.notify_one();
|
||||
}
|
||||
|
@ -192,7 +196,7 @@ private:
|
|||
bool _pendingMainThreadOperation { false };
|
||||
bool _finishedMainThreadOperation { false };
|
||||
QThread* _mainThread { nullptr };
|
||||
OpenGLDisplayPlugin* _newPlugin { nullptr };
|
||||
std::queue<OpenGLDisplayPlugin*> _newPluginQueue;
|
||||
QGLContext* _context { nullptr };
|
||||
};
|
||||
|
||||
|
@ -231,6 +235,12 @@ void OpenGLDisplayPlugin::activate() {
|
|||
}
|
||||
|
||||
_vsyncSupported = _container->getPrimaryWidget()->isVsyncSupported();
|
||||
|
||||
// Child classes may override this in order to do things like initialize
|
||||
// libraries, etc
|
||||
internalActivate();
|
||||
|
||||
|
||||
#if THREADED_PRESENT
|
||||
// Start the present thread if necessary
|
||||
auto presentThread = DependencyManager::get<PresentThread>();
|
||||
|
@ -243,6 +253,9 @@ void OpenGLDisplayPlugin::activate() {
|
|||
// Start execution
|
||||
presentThread->start();
|
||||
}
|
||||
|
||||
// This should not return until the new context has been customized
|
||||
// and the old context (if any) has been uncustomized
|
||||
presentThread->setNewDisplayPlugin(this);
|
||||
#else
|
||||
static auto widget = _container->getPrimaryWidget();
|
||||
|
@ -253,28 +266,25 @@ void OpenGLDisplayPlugin::activate() {
|
|||
DisplayPlugin::activate();
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::stop() {
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::deactivate() {
|
||||
|
||||
#if THREADED_PRESENT
|
||||
{
|
||||
Lock lock(_mutex);
|
||||
_deactivateWait.wait(lock, [&]{ return _uncustomized; });
|
||||
}
|
||||
auto presentThread = DependencyManager::get<PresentThread>();
|
||||
// Does not return until the GL transition has completeed
|
||||
presentThread->setNewDisplayPlugin(nullptr);
|
||||
#else
|
||||
static auto widget = _container->getPrimaryWidget();
|
||||
widget->makeCurrent();
|
||||
uncustomizeContext();
|
||||
_container->makeRenderingContextCurrent();
|
||||
#endif
|
||||
internalDeactivate();
|
||||
DisplayPlugin::deactivate();
|
||||
}
|
||||
|
||||
|
||||
void OpenGLDisplayPlugin::customizeContext() {
|
||||
#if THREADED_PRESENT
|
||||
_uncustomized = false;
|
||||
auto presentThread = DependencyManager::get<PresentThread>();
|
||||
Q_ASSERT(thread() == presentThread->thread());
|
||||
#endif
|
||||
|
@ -393,13 +403,12 @@ void OpenGLDisplayPlugin::submitOverlayTexture(const gpu::TexturePointer& overla
|
|||
}
|
||||
|
||||
void OpenGLDisplayPlugin::updateTextures() {
|
||||
auto oldSceneTexture = _currentSceneTexture;
|
||||
_currentSceneTexture = _sceneTextureEscrow.fetchAndRelease(_currentSceneTexture);
|
||||
if (oldSceneTexture != _currentSceneTexture) {
|
||||
// FIXME intrduce a GPU wait instead of a CPU/GPU sync point?
|
||||
if (_sceneTextureEscrow.fetchSignaledAndRelease(_currentSceneTexture)) {
|
||||
updateFrameData();
|
||||
}
|
||||
|
||||
_currentOverlayTexture = _overlayTextureEscrow.fetchAndRelease(_currentOverlayTexture);
|
||||
_overlayTextureEscrow.fetchSignaledAndRelease(_currentOverlayTexture);
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::updateFrameData() {
|
||||
|
@ -407,7 +416,6 @@ void OpenGLDisplayPlugin::updateFrameData() {
|
|||
_currentRenderFrameIndex = _sceneTextureToFrameIndexMap[_currentSceneTexture];
|
||||
}
|
||||
|
||||
|
||||
void OpenGLDisplayPlugin::updateFramerate() {
|
||||
uint64_t now = usecTimestampNow();
|
||||
static uint64_t lastSwapEnd { now };
|
||||
|
@ -593,14 +601,6 @@ QImage OpenGLDisplayPlugin::getScreenshot() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
#if THREADED_PRESENT
|
||||
void OpenGLDisplayPlugin::enableDeactivate() {
|
||||
Lock lock(_mutex);
|
||||
_uncustomized = true;
|
||||
_deactivateWait.notify_one();
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t OpenGLDisplayPlugin::getSceneTextureId() const {
|
||||
if (!_currentSceneTexture) {
|
||||
return 0;
|
||||
|
@ -625,3 +625,26 @@ void OpenGLDisplayPlugin::eyeViewport(Eye eye) const {
|
|||
}
|
||||
Context::Viewport(vpPos.x, vpPos.y, vpSize.x, vpSize.y);
|
||||
}
|
||||
|
||||
glm::uvec2 OpenGLDisplayPlugin::getSurfacePixels() const {
|
||||
uvec2 result;
|
||||
auto window = _container->getPrimaryWidget();
|
||||
if (window) {
|
||||
result = toGlm(window->geometry().size() * window->devicePixelRatio());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
glm::uvec2 OpenGLDisplayPlugin::getSurfaceSize() const {
|
||||
uvec2 result;
|
||||
auto window = _container->getPrimaryWidget();
|
||||
if (window) {
|
||||
result = toGlm(window->geometry().size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool OpenGLDisplayPlugin::hasFocus() const {
|
||||
auto window = _container->getPrimaryWidget();
|
||||
return window ? window->hasFocus() : false;
|
||||
}
|
||||
|
|
|
@ -29,9 +29,12 @@ protected:
|
|||
using TextureEscrow = GLEscrow<gpu::TexturePointer>;
|
||||
public:
|
||||
OpenGLDisplayPlugin();
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
void stop() override;
|
||||
|
||||
// These must be final to ensure proper ordering of operations
|
||||
// between the main thread and the presentation thread
|
||||
void activate() override final;
|
||||
void deactivate() override final;
|
||||
|
||||
bool eventFilter(QObject* receiver, QEvent* event) override;
|
||||
bool isDisplayVisible() const override { return true; }
|
||||
|
||||
|
@ -56,13 +59,15 @@ protected:
|
|||
#endif
|
||||
uint32_t getSceneTextureId() const;
|
||||
uint32_t getOverlayTextureId() const;
|
||||
|
||||
|
||||
glm::uvec2 getSurfaceSize() const;
|
||||
glm::uvec2 getSurfacePixels() const;
|
||||
|
||||
void compositeLayers();
|
||||
virtual void compositeOverlay();
|
||||
virtual void compositePointer();
|
||||
|
||||
virtual glm::uvec2 getSurfaceSize() const = 0;
|
||||
virtual glm::uvec2 getSurfacePixels() const = 0;
|
||||
virtual bool hasFocus() const override;
|
||||
|
||||
// FIXME make thread safe?
|
||||
virtual bool isVsyncEnabled();
|
||||
|
@ -71,6 +76,9 @@ protected:
|
|||
// These functions must only be called on the presentation thread
|
||||
virtual void customizeContext();
|
||||
virtual void uncustomizeContext();
|
||||
|
||||
virtual void internalActivate() {}
|
||||
virtual void internalDeactivate() {}
|
||||
virtual void cleanupForSceneTexture(const gpu::TexturePointer& sceneTexture);
|
||||
// Plugin specific functionality to send the composed scene to the output window or device
|
||||
virtual void internalPresent();
|
||||
|
@ -113,14 +121,6 @@ protected:
|
|||
|
||||
std::map<uint16_t, CursorData> _cursorsData;
|
||||
BasicFramebufferWrapperPtr _compositeFramebuffer;
|
||||
|
||||
private:
|
||||
#if THREADED_PRESENT
|
||||
void enableDeactivate();
|
||||
Condition _deactivateWait;
|
||||
bool _uncustomized{ false };
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/05/29
|
||||
// Copyright 2015 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
|
||||
//
|
||||
#include "WindowOpenGLDisplayPlugin.h"
|
||||
|
||||
#include <gl/GLWidget.h>
|
||||
|
||||
#include "plugins/PluginContainer.h"
|
||||
|
||||
glm::uvec2 WindowOpenGLDisplayPlugin::getSurfacePixels() const {
|
||||
uvec2 result;
|
||||
if (_window) {
|
||||
result = toGlm(_window->geometry().size() * _window->devicePixelRatio());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
glm::uvec2 WindowOpenGLDisplayPlugin::getSurfaceSize() const {
|
||||
uvec2 result;
|
||||
if (_window) {
|
||||
result = toGlm(_window->geometry().size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool WindowOpenGLDisplayPlugin::hasFocus() const {
|
||||
return _window ? _window->hasFocus() : false;
|
||||
}
|
||||
|
||||
void WindowOpenGLDisplayPlugin::activate() {
|
||||
_window = _container->getPrimaryWidget();
|
||||
OpenGLDisplayPlugin::activate();
|
||||
}
|
||||
|
||||
void WindowOpenGLDisplayPlugin::deactivate() {
|
||||
OpenGLDisplayPlugin::deactivate();
|
||||
_window = nullptr;
|
||||
}
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/05/29
|
||||
// Copyright 2015 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
|
||||
//
|
||||
#pragma once
|
||||
|
||||
#include "OpenGLDisplayPlugin.h"
|
||||
|
||||
class QWidget;
|
||||
|
||||
class WindowOpenGLDisplayPlugin : public OpenGLDisplayPlugin {
|
||||
public:
|
||||
virtual bool hasFocus() const override;
|
||||
virtual void activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
protected:
|
||||
virtual glm::uvec2 getSurfaceSize() const override final;
|
||||
virtual glm::uvec2 getSurfacePixels() const override final;
|
||||
|
||||
QWidget* _window { nullptr };
|
||||
};
|
|
@ -18,6 +18,7 @@
|
|||
#include <plugins/PluginContainer.h>
|
||||
#include <gpu/GLBackend.h>
|
||||
#include <CursorManager.h>
|
||||
#include <gl/GLWidget.h>
|
||||
|
||||
#include "../Logging.h"
|
||||
#include "../CompositorHelper.h"
|
||||
|
@ -30,7 +31,7 @@ glm::uvec2 HmdDisplayPlugin::getRecommendedUiSize() const {
|
|||
return CompositorHelper::VIRTUAL_SCREEN_SIZE;
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::activate() {
|
||||
void HmdDisplayPlugin::internalActivate() {
|
||||
_monoPreview = _container->getBoolSetting("monoPreview", DEFAULT_MONO_VIEW);
|
||||
|
||||
_container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), MONO_PREVIEW,
|
||||
|
@ -39,11 +40,7 @@ void HmdDisplayPlugin::activate() {
|
|||
_container->setBoolSetting("monoPreview", _monoPreview);
|
||||
}, true, _monoPreview);
|
||||
_container->removeMenu(FRAMERATE);
|
||||
Parent::activate();
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::deactivate() {
|
||||
Parent::deactivate();
|
||||
Parent::internalActivate();
|
||||
}
|
||||
|
||||
void HmdDisplayPlugin::customizeContext() {
|
||||
|
@ -114,7 +111,8 @@ void HmdDisplayPlugin::internalPresent() {
|
|||
|
||||
// screen preview mirroring
|
||||
if (_enablePreview) {
|
||||
auto windowSize = toGlm(_window->size());
|
||||
auto window = _container->getPrimaryWidget();
|
||||
auto windowSize = toGlm(window->size());
|
||||
float windowAspect = aspect(windowSize);
|
||||
float sceneAspect = aspect(_renderTargetSize);
|
||||
if (_monoPreview) {
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
|
||||
#include <QtGlobal>
|
||||
|
||||
#include "../WindowOpenGLDisplayPlugin.h"
|
||||
#include "../OpenGLDisplayPlugin.h"
|
||||
|
||||
class HmdDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
||||
using Parent = WindowOpenGLDisplayPlugin;
|
||||
class HmdDisplayPlugin : public OpenGLDisplayPlugin {
|
||||
using Parent = OpenGLDisplayPlugin;
|
||||
public:
|
||||
bool isHmd() const override final { return true; }
|
||||
float getIPD() const override final { return _ipd; }
|
||||
|
@ -25,13 +25,12 @@ public:
|
|||
bool isDisplayVisible() const override { return isHmdMounted(); }
|
||||
|
||||
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
|
||||
protected:
|
||||
virtual void hmdPresent() = 0;
|
||||
virtual bool isHmdMounted() const = 0;
|
||||
|
||||
void internalActivate() override;
|
||||
void compositeOverlay() override;
|
||||
void compositePointer() override;
|
||||
void internalPresent() override;
|
||||
|
|
|
@ -58,7 +58,7 @@ void InterleavedStereoDisplayPlugin::uncustomizeContext() {
|
|||
}
|
||||
|
||||
glm::uvec2 InterleavedStereoDisplayPlugin::getRecommendedRenderSize() const {
|
||||
uvec2 result = WindowOpenGLDisplayPlugin::getRecommendedRenderSize();
|
||||
uvec2 result = Parent::getRecommendedRenderSize();
|
||||
result.x *= 2;
|
||||
result.y /= 2;
|
||||
return result;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
class InterleavedStereoDisplayPlugin : public StereoDisplayPlugin {
|
||||
Q_OBJECT
|
||||
using Parent = StereoDisplayPlugin;
|
||||
public:
|
||||
const QString& getName() const override { return NAME; }
|
||||
grouping getGrouping() const override { return ADVANCED; }
|
||||
|
|
|
@ -15,11 +15,8 @@
|
|||
|
||||
const QString SideBySideStereoDisplayPlugin::NAME("3D TV - Side by Side Stereo");
|
||||
|
||||
SideBySideStereoDisplayPlugin::SideBySideStereoDisplayPlugin() {
|
||||
}
|
||||
|
||||
glm::uvec2 SideBySideStereoDisplayPlugin::getRecommendedRenderSize() const {
|
||||
uvec2 result = WindowOpenGLDisplayPlugin::getRecommendedRenderSize();
|
||||
uvec2 result = Parent::getRecommendedRenderSize();
|
||||
result.x *= 2;
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -13,8 +13,8 @@ class QScreen;
|
|||
|
||||
class SideBySideStereoDisplayPlugin : public StereoDisplayPlugin {
|
||||
Q_OBJECT
|
||||
using Parent = StereoDisplayPlugin;
|
||||
public:
|
||||
SideBySideStereoDisplayPlugin();
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
virtual grouping getGrouping() const override { return ADVANCED; }
|
||||
virtual glm::uvec2 getRecommendedRenderSize() const override;
|
||||
|
|
|
@ -58,7 +58,7 @@ glm::mat4 StereoDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& basePr
|
|||
static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate";
|
||||
|
||||
std::vector<QAction*> _screenActions;
|
||||
void StereoDisplayPlugin::activate() {
|
||||
void StereoDisplayPlugin::internalActivate() {
|
||||
auto screens = qApp->screens();
|
||||
_screenActions.resize(screens.size());
|
||||
for (int i = 0; i < screens.size(); ++i) {
|
||||
|
@ -77,7 +77,7 @@ void StereoDisplayPlugin::activate() {
|
|||
|
||||
_screen = qApp->primaryScreen();
|
||||
_container->setFullscreen(_screen);
|
||||
WindowOpenGLDisplayPlugin::activate();
|
||||
Parent::internalActivate();
|
||||
}
|
||||
|
||||
void StereoDisplayPlugin::updateScreen() {
|
||||
|
@ -90,15 +90,15 @@ void StereoDisplayPlugin::updateScreen() {
|
|||
}
|
||||
}
|
||||
|
||||
void StereoDisplayPlugin::deactivate() {
|
||||
void StereoDisplayPlugin::internalDeactivate() {
|
||||
_screenActions.clear();
|
||||
_container->unsetFullscreen();
|
||||
WindowOpenGLDisplayPlugin::deactivate();
|
||||
Parent::internalDeactivate();
|
||||
}
|
||||
|
||||
// Derived classes will override the recommended render size based on the window size,
|
||||
// so here we want to fix the aspect ratio based on the window, not on the render size
|
||||
float StereoDisplayPlugin::getRecommendedAspectRatio() const {
|
||||
return aspect(WindowOpenGLDisplayPlugin::getRecommendedRenderSize());
|
||||
return aspect(Parent::getRecommendedRenderSize());
|
||||
}
|
||||
|
||||
|
|
|
@ -7,19 +7,16 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include "../WindowOpenGLDisplayPlugin.h"
|
||||
#include "../OpenGLDisplayPlugin.h"
|
||||
class QScreen;
|
||||
|
||||
class StereoDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
||||
class StereoDisplayPlugin : public OpenGLDisplayPlugin {
|
||||
Q_OBJECT
|
||||
using Parent = WindowOpenGLDisplayPlugin;
|
||||
using Parent = OpenGLDisplayPlugin;
|
||||
public:
|
||||
virtual bool isStereo() const override final { return true; }
|
||||
virtual bool isSupported() const override final;
|
||||
|
||||
virtual void activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
virtual float getRecommendedAspectRatio() const override;
|
||||
virtual glm::mat4 getEyeProjection(Eye eye, const glm::mat4& baseProjection) const override;
|
||||
|
||||
|
@ -32,7 +29,10 @@ public:
|
|||
// virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override;
|
||||
|
||||
protected:
|
||||
virtual void internalActivate() override;
|
||||
virtual void internalDeactivate() override;
|
||||
void updateScreen();
|
||||
|
||||
float _ipd{ 0.064f };
|
||||
QScreen* _screen;
|
||||
};
|
||||
|
|
|
@ -138,34 +138,100 @@ public:
|
|||
// Returns the next available resource provided by the submitter,
|
||||
// or if none is available (which could mean either the submission
|
||||
// list is empty or that the first item on the list isn't yet signaled
|
||||
T fetch() {
|
||||
T result = invalid();
|
||||
// Deprecated... will inject an unecessary GPU bubble
|
||||
bool fetchSignaled(T& t) {
|
||||
bool result = false;
|
||||
// On the one hand using try_lock() reduces the chance of blocking the consumer thread,
|
||||
// but if the produce thread is going fast enough, it could effectively
|
||||
// starve the consumer out of ever actually getting resources.
|
||||
tryLock([&]{
|
||||
tryLock([&] {
|
||||
// May be called on any thread, but must be inside a locked section
|
||||
if (signaled(_submits, 0)) {
|
||||
result = _submits.at(0)._value;
|
||||
result = true;
|
||||
t = _submits.at(0)._value;
|
||||
_submits.pop_front();
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
// Populates t with the next available resource provided by the submitter
|
||||
// and sync with a fence that will be signaled when all write commands for the
|
||||
// item have completed. Returns false if no resources are available
|
||||
bool fetchWithFence(T& t, GLsync& sync) {
|
||||
bool result = false;
|
||||
// On the one hand using try_lock() reduces the chance of blocking the consumer thread,
|
||||
// but if the produce thread is going fast enough, it could effectively
|
||||
// starve the consumer out of ever actually getting resources.
|
||||
tryLock([&] {
|
||||
if (!_submits.empty()) {
|
||||
result = true;
|
||||
// When fetching with sync, we only want the latest item
|
||||
auto item = _submits.back();
|
||||
_submits.pop_back();
|
||||
|
||||
// Throw everything else in the trash
|
||||
for (const auto& oldItem : _submits) {
|
||||
_trash.push_front(oldItem);
|
||||
}
|
||||
_submits.clear();
|
||||
|
||||
t = item._value;
|
||||
sync = item._sync;
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
bool fetchWithGpuWait(T& t) {
|
||||
GLsync sync { 0 };
|
||||
if (fetchWithFence(t, sync)) {
|
||||
// Texture was updated, inject a wait into the GL command stream to ensure
|
||||
// commands on this context until the commands to generate t are finished.
|
||||
if (sync != 0) {
|
||||
glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
|
||||
glDeleteSync(sync);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns the next available resource provided by the submitter,
|
||||
// or if none is available (which could mean either the submission
|
||||
// list is empty or that the first item on the list isn't yet signaled
|
||||
// Also releases any previous texture held by the caller
|
||||
T fetchAndRelease(const T& oldValue) {
|
||||
T result = fetch();
|
||||
if (!result) {
|
||||
return oldValue;
|
||||
bool fetchSignaledAndRelease(T& value) {
|
||||
T originalValue = value;
|
||||
if (fetchSignaled(value)) {
|
||||
if (originalValue != invalid()) {
|
||||
release(originalValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (oldValue) {
|
||||
release(oldValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fetchAndReleaseWithFence(T& value, GLsync& sync) {
|
||||
T originalValue = value;
|
||||
if (fetchWithFence(value, sync)) {
|
||||
if (originalValue != invalid()) {
|
||||
release(originalValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fetchAndReleaseWithGpuWait(T& value) {
|
||||
T originalValue = value;
|
||||
if (fetchWithGpuWait(value)) {
|
||||
if (originalValue != invalid()) {
|
||||
release(originalValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// If fetch returns a non-zero value, it's the responsibility of the
|
||||
|
|
|
@ -498,12 +498,7 @@ void OffscreenQmlSurface::updateQuick() {
|
|||
_render = false;
|
||||
}
|
||||
|
||||
GLuint newTexture = _renderer->_escrow.fetch();
|
||||
if (newTexture) {
|
||||
if (_currentTexture) {
|
||||
_renderer->_escrow.release(_currentTexture);
|
||||
}
|
||||
_currentTexture = newTexture;
|
||||
if (_renderer->_escrow.fetchSignaledAndRelease(_currentTexture)) {
|
||||
emit textureUpdated(_currentTexture);
|
||||
}
|
||||
}
|
||||
|
|
26
libraries/plugins/src/plugins/DisplayPlugin.cpp
Normal file
26
libraries/plugins/src/plugins/DisplayPlugin.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
#include "DisplayPlugin.h"
|
||||
|
||||
#include <ui/Menu.h>
|
||||
|
||||
#include "PluginContainer.h"
|
||||
|
||||
void DisplayPlugin::activate() {
|
||||
Parent::activate();
|
||||
if (isHmd() && (getHmdScreen() >= 0)) {
|
||||
_container->showDisplayPluginsTools();
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayPlugin::deactivate() {
|
||||
_container->showDisplayPluginsTools(false);
|
||||
if (!_container->currentDisplayActions().isEmpty()) {
|
||||
auto menu = _container->getPrimaryMenu();
|
||||
foreach(auto itemInfo, _container->currentDisplayActions()) {
|
||||
menu->removeMenuItem(itemInfo.first, itemInfo.second);
|
||||
}
|
||||
_container->currentDisplayActions().clear();
|
||||
}
|
||||
Parent::deactivate();
|
||||
}
|
||||
|
||||
|
|
@ -57,7 +57,10 @@ namespace gpu {
|
|||
|
||||
class DisplayPlugin : public Plugin {
|
||||
Q_OBJECT
|
||||
using Parent = Plugin;
|
||||
public:
|
||||
void activate() override;
|
||||
void deactivate() override;
|
||||
virtual bool isHmd() const { return false; }
|
||||
virtual int getHmdScreen() const { return -1; }
|
||||
/// By default, all HMDs are stereo
|
||||
|
@ -73,11 +76,6 @@ 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;
|
||||
|
||||
/**
|
||||
* Sends the scene texture to the display plugin.
|
||||
*/
|
||||
|
|
|
@ -55,7 +55,7 @@ public:
|
|||
void unsetFullscreen(const QScreen* avoidScreen = nullptr);
|
||||
|
||||
virtual ui::Menu* getPrimaryMenu() = 0;
|
||||
virtual void showDisplayPluginsTools() = 0;
|
||||
virtual void showDisplayPluginsTools(bool show = true) = 0;
|
||||
virtual void requestReset() = 0;
|
||||
virtual bool makeRenderingContextCurrent() = 0;
|
||||
virtual void releaseSceneTexture(const gpu::TexturePointer& texture) = 0;
|
||||
|
|
|
@ -34,16 +34,10 @@ void OculusBaseDisplayPlugin::customizeContext() {
|
|||
glewExperimental = true;
|
||||
GLenum err = glewInit();
|
||||
glGetError();
|
||||
HmdDisplayPlugin::customizeContext();
|
||||
Parent::customizeContext();
|
||||
}
|
||||
|
||||
void OculusBaseDisplayPlugin::init() {
|
||||
}
|
||||
|
||||
void OculusBaseDisplayPlugin::deinit() {
|
||||
}
|
||||
|
||||
void OculusBaseDisplayPlugin::activate() {
|
||||
void OculusBaseDisplayPlugin::internalActivate() {
|
||||
_session = acquireOculusSession();
|
||||
|
||||
_hmdDesc = ovr_GetHmdDesc(_session);
|
||||
|
@ -90,11 +84,11 @@ void OculusBaseDisplayPlugin::activate() {
|
|||
// This must come after the initialization, so that the values calculated
|
||||
// above are available during the customizeContext call (when not running
|
||||
// in threaded present mode)
|
||||
HmdDisplayPlugin::activate();
|
||||
Parent::internalActivate();
|
||||
}
|
||||
|
||||
void OculusBaseDisplayPlugin::deactivate() {
|
||||
HmdDisplayPlugin::deactivate();
|
||||
void OculusBaseDisplayPlugin::internalDeactivate() {
|
||||
Parent::internalDeactivate();
|
||||
releaseOculusSession();
|
||||
_session = nullptr;
|
||||
}
|
||||
|
|
|
@ -14,21 +14,18 @@
|
|||
#include <OVR_CAPI_GL.h>
|
||||
|
||||
class OculusBaseDisplayPlugin : public HmdDisplayPlugin {
|
||||
using Parent = HmdDisplayPlugin;
|
||||
public:
|
||||
virtual bool isSupported() const override;
|
||||
|
||||
virtual void init() override final;
|
||||
virtual void deinit() override final;
|
||||
|
||||
virtual void activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
// Stereo specific methods
|
||||
virtual void resetSensors() override final;
|
||||
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override;
|
||||
|
||||
protected:
|
||||
virtual void customizeContext() override;
|
||||
void customizeContext() override;
|
||||
void internalActivate() override;
|
||||
void internalDeactivate() override;
|
||||
|
||||
protected:
|
||||
ovrSession _session;
|
||||
|
|
|
@ -10,12 +10,8 @@
|
|||
|
||||
const QString OculusDisplayPlugin::NAME("Oculus Rift");
|
||||
|
||||
void OculusDisplayPlugin::activate() {
|
||||
OculusBaseDisplayPlugin::activate();
|
||||
}
|
||||
|
||||
void OculusDisplayPlugin::customizeContext() {
|
||||
OculusBaseDisplayPlugin::customizeContext();
|
||||
Parent::customizeContext();
|
||||
_sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_session));
|
||||
_sceneFbo->Init(getRecommendedRenderSize());
|
||||
|
||||
|
@ -34,7 +30,7 @@ void OculusDisplayPlugin::uncustomizeContext() {
|
|||
#if (OVR_MAJOR_VERSION >= 6)
|
||||
_sceneFbo.reset();
|
||||
#endif
|
||||
OculusBaseDisplayPlugin::uncustomizeContext();
|
||||
Parent::uncustomizeContext();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ const float TARGET_RATE_Oculus = 75.0f;
|
|||
class OculusDisplayPlugin : public OculusBaseDisplayPlugin {
|
||||
using Parent = OculusBaseDisplayPlugin;
|
||||
public:
|
||||
void activate() override;
|
||||
const QString& getName() const override { return NAME; }
|
||||
|
||||
float getTargetFrameRate() override { return TARGET_RATE_Oculus; }
|
||||
|
|
|
@ -41,7 +41,8 @@ bool OpenVrDisplayPlugin::isSupported() const {
|
|||
return vr::VR_IsHmdPresent();
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::activate() {
|
||||
void OpenVrDisplayPlugin::internalActivate() {
|
||||
Parent::internalActivate();
|
||||
_container->setIsOptionChecked(StandingHMDSensorMode, true);
|
||||
|
||||
if (!_system) {
|
||||
|
@ -67,7 +68,6 @@ void OpenVrDisplayPlugin::activate() {
|
|||
|
||||
_compositor = vr::VRCompositor();
|
||||
Q_ASSERT(_compositor);
|
||||
HmdDisplayPlugin::activate();
|
||||
|
||||
// set up default sensor space such that the UI overlay will align with the front of the room.
|
||||
auto chaperone = vr::VRChaperone();
|
||||
|
@ -85,11 +85,8 @@ void OpenVrDisplayPlugin::activate() {
|
|||
}
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::deactivate() {
|
||||
// Base class deactivate must come before our local deactivate
|
||||
// because the OpenGL base class handles the wait for the present
|
||||
// thread before continuing
|
||||
HmdDisplayPlugin::deactivate();
|
||||
void OpenVrDisplayPlugin::internalDeactivate() {
|
||||
Parent::internalDeactivate();
|
||||
_container->setIsOptionChecked(StandingHMDSensorMode, false);
|
||||
if (_system) {
|
||||
releaseOpenVrSystem();
|
||||
|
@ -106,7 +103,7 @@ void OpenVrDisplayPlugin::customizeContext() {
|
|||
GLenum err = glewInit();
|
||||
glGetError();
|
||||
});
|
||||
HmdDisplayPlugin::customizeContext();
|
||||
Parent::customizeContext();
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::resetSensors() {
|
||||
|
|
|
@ -16,15 +16,13 @@
|
|||
const float TARGET_RATE_OpenVr = 90.0f; // FIXME: get from sdk tracked device property? This number is vive-only.
|
||||
|
||||
class OpenVrDisplayPlugin : public HmdDisplayPlugin {
|
||||
using Parent = HmdDisplayPlugin;
|
||||
public:
|
||||
virtual bool isSupported() const override;
|
||||
virtual const QString& getName() const override { return NAME; }
|
||||
|
||||
virtual float getTargetFrameRate() override { return TARGET_RATE_OpenVr; }
|
||||
|
||||
virtual void activate() override;
|
||||
virtual void deactivate() override;
|
||||
|
||||
virtual void customizeContext() override;
|
||||
|
||||
// Stereo specific methods
|
||||
|
@ -32,6 +30,9 @@ public:
|
|||
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override;
|
||||
|
||||
protected:
|
||||
void internalActivate() override;
|
||||
void internalDeactivate() override;
|
||||
|
||||
void hmdPresent() override;
|
||||
bool isHmdMounted() const override;
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ class PluginContainerProxy : public QObject, PluginContainer {
|
|||
Q_OBJECT
|
||||
public:
|
||||
virtual ~PluginContainerProxy() {}
|
||||
virtual void showDisplayPluginsTools() override {}
|
||||
virtual void showDisplayPluginsTools(bool show) override {}
|
||||
virtual void requestReset() override {}
|
||||
virtual bool makeRenderingContextCurrent() override { return true; }
|
||||
virtual void releaseSceneTexture(const gpu::TexturePointer& texture) override {}
|
||||
|
|
Loading…
Reference in a new issue