diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2c58156d2a..bbc36e8623 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4777,19 +4777,18 @@ void Application::updateDisplayMode() { return; } - if (!_currentDisplayPluginActions.isEmpty()) { + + if (!_pluginContainer->currentDisplayActions().isEmpty()) { auto menu = Menu::getInstance(); - foreach(auto itemInfo, _currentDisplayPluginActions) { + foreach(auto itemInfo, _pluginContainer->currentDisplayActions()) { menu->removeMenuItem(itemInfo.first, itemInfo.second); } - _currentDisplayPluginActions.clear(); + _pluginContainer->currentDisplayActions().clear(); } if (newDisplayPlugin) { _offscreenContext->makeCurrent(); - _activatingDisplayPlugin = true; newDisplayPlugin->activate(); - _activatingDisplayPlugin = false; _offscreenContext->makeCurrent(); offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize())); _offscreenContext->makeCurrent(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 1af252de95..d12d29cde8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -427,8 +427,6 @@ private: InputPluginList _activeInputPlugins; bool _activatingDisplayPlugin { false }; - QVector> _currentDisplayPluginActions; - QVector> _currentInputPluginActions; QMap _lockedFramebufferMap; MainWindow* _window; diff --git a/interface/src/PluginContainerProxy.cpp b/interface/src/PluginContainerProxy.cpp index 8774eecd77..abb52380d0 100644 --- a/interface/src/PluginContainerProxy.cpp +++ b/interface/src/PluginContainerProxy.cpp @@ -36,37 +36,31 @@ void PluginContainerProxy::removeMenu(const QString& menuName) { Menu::getInstance()->removeMenu(menuName); } -extern bool _activatingDisplayPlugin; -extern QVector> _currentDisplayPluginActions; -extern QVector> _currentInputPluginActions; -std::map _exclusiveGroups; - -QAction* PluginContainerProxy::addMenuItem(const QString& path, const QString& name, std::function onClicked, bool checkable, bool checked, const QString& groupName) { - //auto menu = Menu::getInstance(); - //MenuWrapper* parentItem = menu->getMenu(path); - //QAction* action = menu->addActionToQMenuAndActionHash(parentItem, name); - //if (!groupName.isEmpty()) { - // QActionGroup* group{ nullptr }; - // if (!_exclusiveGroups.count(groupName)) { - // group = _exclusiveGroups[groupName] = new QActionGroup(menu); - // group->setExclusive(true); - // } else { - // group = _exclusiveGroups[groupName]; - // } - // group->addAction(action); - //} - //connect(action, &QAction::triggered, [=] { - // onClicked(action->isChecked()); - //}); - //action->setCheckable(checkable); - //action->setChecked(checked); - //if (_activatingDisplayPlugin) { - // _currentDisplayPluginActions.push_back({ path, name }); - //} else { - // _currentInputPluginActions.push_back({ path, name }); - //} - //return action; - return nullptr; +QAction* PluginContainerProxy::addMenuItem(PluginType type, const QString& path, const QString& name, std::function onClicked, bool checkable, bool checked, const QString& groupName) { + auto menu = Menu::getInstance(); + MenuWrapper* parentItem = menu->getMenu(path); + QAction* action = menu->addActionToQMenuAndActionHash(parentItem, name); + if (!groupName.isEmpty()) { + QActionGroup* group{ nullptr }; + if (!_exclusiveGroups.count(groupName)) { + group = _exclusiveGroups[groupName] = new QActionGroup(menu); + group->setExclusive(true); + } else { + group = _exclusiveGroups[groupName]; + } + group->addAction(action); + } + connect(action, &QAction::triggered, [=] { + onClicked(action->isChecked()); + }); + action->setCheckable(checkable); + action->setChecked(checked); + if (type == PluginType::DISPLAY_PLUGIN) { + _currentDisplayPluginActions.push_back({ path, name }); + } else { + _currentInputPluginActions.push_back({ path, name }); + } + return action; } void PluginContainerProxy::removeMenuItem(const QString& menuName, const QString& menuItem) { @@ -188,5 +182,13 @@ void PluginContainerProxy::releaseSceneTexture(uint32_t texture) { } void PluginContainerProxy::releaseOverlayTexture(uint32_t texture) { - + // FIXME implement present thread compositing +} + +QVector>& PluginContainerProxy::currentDisplayActions() { + return _currentDisplayPluginActions; +} + +QVector>& PluginContainerProxy::currentInputActions() { + return _currentInputPluginActions; } diff --git a/interface/src/PluginContainerProxy.h b/interface/src/PluginContainerProxy.h index 5cc1cc8583..cd15510885 100644 --- a/interface/src/PluginContainerProxy.h +++ b/interface/src/PluginContainerProxy.h @@ -2,19 +2,23 @@ #ifndef hifi_PluginContainerProxy_h #define hifi_PluginContainerProxy_h -#include -#include +#include +#include #include #include +class QActionGroup; + class PluginContainerProxy : public QObject, PluginContainer { Q_OBJECT PluginContainerProxy(); virtual ~PluginContainerProxy(); + virtual QVector>& currentDisplayActions() override; + virtual QVector>& currentInputActions() override; virtual void addMenu(const QString& menuName) override; virtual void removeMenu(const QString& menuName) override; - virtual QAction* addMenuItem(const QString& path, const QString& name, std::function onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") override; + virtual QAction* addMenuItem(PluginType type, const QString& path, const QString& name, std::function onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") override; virtual void removeMenuItem(const QString& menuName, const QString& menuItem) override; virtual bool isOptionChecked(const QString& name) override; virtual void setIsOptionChecked(const QString& path, bool checked) override; @@ -32,8 +36,12 @@ class PluginContainerProxy : public QObject, PluginContainer { virtual const DisplayPlugin* getActiveDisplayPlugin() const override; QRect _savedGeometry{ 10, 120, 800, 600 }; + std::map _exclusiveGroups; + QVector> _currentDisplayPluginActions; + QVector> _currentInputPluginActions; friend class Application; + }; #endif \ No newline at end of file diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 36216f8912..6c450e0735 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -31,60 +31,59 @@ const QString& Basic2DWindowOpenGLDisplayPlugin::getName() const { } void Basic2DWindowOpenGLDisplayPlugin::activate() { - //_framerateActions.clear(); - //_container->addMenuItem(MENU_PATH(), FULLSCREEN, - // [this](bool clicked) { - // if (clicked) { - // _container->setFullscreen(getFullscreenTarget()); - // } else { - // _container->unsetFullscreen(); - // } - // }, true, false); - //_container->addMenu(FRAMERATE); - //_framerateActions.push_back( - // _container->addMenuItem(FRAMERATE, FRAMERATE_UNLIMITED, - // [this](bool) { updateFramerate(); }, true, true, FRAMERATE)); - //_framerateActions.push_back( - // _container->addMenuItem(FRAMERATE, FRAMERATE_60, - // [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); - //_framerateActions.push_back( - // _container->addMenuItem(FRAMERATE, FRAMERATE_50, - // [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); - //_framerateActions.push_back( - // _container->addMenuItem(FRAMERATE, FRAMERATE_40, - // [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); - //_framerateActions.push_back( - // _container->addMenuItem(FRAMERATE, FRAMERATE_30, - // [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); - WindowOpenGLDisplayPlugin::activate(); - //// Vsync detection happens in the parent class activate, so we need to check after that - //if (_vsyncSupported) { - // _vsyncAction = _container->addMenuItem(MENU_PATH(), VSYNC_ON, [this](bool) {}, true, true); - //} else { - // _vsyncAction = nullptr; - //} + _framerateActions.clear(); + _container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), FULLSCREEN, + [this](bool clicked) { + if (clicked) { + _container->setFullscreen(getFullscreenTarget()); + } else { + _container->unsetFullscreen(); + } + }, true, false); + _container->addMenu(FRAMERATE); + _framerateActions.push_back( + _container->addMenuItem(PluginType::DISPLAY_PLUGIN, FRAMERATE, FRAMERATE_UNLIMITED, + [this](bool) { updateFramerate(); }, true, true, FRAMERATE)); + _framerateActions.push_back( + _container->addMenuItem(PluginType::DISPLAY_PLUGIN, FRAMERATE, FRAMERATE_60, + [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); + _framerateActions.push_back( + _container->addMenuItem(PluginType::DISPLAY_PLUGIN, FRAMERATE, FRAMERATE_50, + [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); + _framerateActions.push_back( + _container->addMenuItem(PluginType::DISPLAY_PLUGIN, FRAMERATE, FRAMERATE_40, + [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); + _framerateActions.push_back( + _container->addMenuItem(PluginType::DISPLAY_PLUGIN, FRAMERATE, FRAMERATE_30, + [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); + + // Vsync detection happens in the parent class activate, so we need to check after that + if (_vsyncSupported) { + _vsyncAction = _container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), VSYNC_ON, [this](bool) {}, true, true); + } else { + _vsyncAction = nullptr; + } updateFramerate(); } -void Basic2DWindowOpenGLDisplayPlugin::deactivate() { - WindowOpenGLDisplayPlugin::deactivate(); -} - void Basic2DWindowOpenGLDisplayPlugin::submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) { if (_vsyncAction) { _wantVsync = _vsyncAction->isChecked(); - //bool vsyncEnabed = isVsyncEnabled(); - //if (vsyncEnabed ^ wantVsync) { - // enableVsync(wantVsync); - //} } WindowOpenGLDisplayPlugin::submitSceneTexture(frameIndex, sceneTexture, sceneSize); } +void Basic2DWindowOpenGLDisplayPlugin::internalPresent() { + if (_wantVsync != isVsyncEnabled()) { + enableVsync(_wantVsync); + } + WindowOpenGLDisplayPlugin::internalPresent(); +} + int Basic2DWindowOpenGLDisplayPlugin::getDesiredInterval() const { static const int THROTTLED_PAINT_TIMER_DELAY_MS = MSECS_PER_SECOND / 15; static const int ULIMIITED_PAINT_TIMER_DELAY_MS = 1; diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index 80aebf9efc..36a1a73b94 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -19,10 +19,11 @@ public: virtual const QString & getName() const override; virtual void activate() override; - virtual void deactivate() override; virtual void submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) override; + virtual void internalPresent() override; + virtual bool isThrottled() const override; protected: diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 45e6daef31..12aa37cd56 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -145,6 +145,8 @@ private: QGLContext* _context { nullptr }; }; +bool OpenGLDisplayPlugin::_vsyncSupported = false; + OpenGLDisplayPlugin::OpenGLDisplayPlugin() { _sceneTextureEscrow.setRecycler([this](GLuint texture){ cleanupForSceneTexture(texture); @@ -175,10 +177,18 @@ void OpenGLDisplayPlugin::activate() { // Start the present thread if necessary auto presentThread = DependencyManager::get(); if (!presentThread) { + auto widget = _container->getPrimaryWidget(); + + // TODO: write the proper code for linux +#if defined(Q_OS_WIN) + widget->makeCurrent(); + _vsyncSupported = wglewGetExtension("WGL_EXT_swap_control"); + widget->doneCurrent(); +#endif + DependencyManager::set(); presentThread = DependencyManager::get(); presentThread->setObjectName("Presentation Thread"); - auto widget = _container->getPrimaryWidget(); presentThread->setContext(widget->context()); // Start execution presentThread->start(); @@ -201,10 +211,6 @@ void OpenGLDisplayPlugin::customizeContext() { auto presentThread = DependencyManager::get(); Q_ASSERT(thread() == presentThread->thread()); - // TODO: write the proper code for linux -#if defined(Q_OS_WIN) - _vsyncSupported = wglewGetExtension("WGL_EXT_swap_control"); -#endif enableVsync(); using namespace oglplus; diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 809a52ef7f..747d8b810b 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -70,7 +70,6 @@ protected: mutable QTimer _timer; ProgramPtr _program; ShapeWrapperPtr _plane; - bool _vsyncSupported { false }; Mutex _mutex; SimpleMovingAverage _usecsPerFrame { 10 }; @@ -81,6 +80,8 @@ protected: GLTextureEscrow _overlayTextureEscrow; GLTextureEscrow _sceneTextureEscrow; + + static bool _vsyncSupported; }; diff --git a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h index b9b3566349..7116363e44 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/stereo/InterleavedStereoDisplayPlugin.h @@ -19,7 +19,6 @@ public: virtual void customizeContext() override; virtual glm::uvec2 getRecommendedRenderSize() const override; - void internalPresent() override; private: diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index f7e71313df..a691f375eb 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -74,7 +74,7 @@ void StereoDisplayPlugin::activate() { if (screen == qApp->primaryScreen()) { checked = true; } - auto action = _container->addMenuItem(MENU_PATH(), name, + auto action = _container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), name, [this](bool clicked) { updateScreen(); }, true, checked, "Screens"); _screenActions[i] = action; } diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp index 18fdc9ddad..5dd0248224 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp @@ -68,7 +68,7 @@ void SixenseManager::activate() { #ifdef HAVE_SIXENSE _container->addMenu(MENU_PATH); - _container->addMenuItem(MENU_PATH, TOGGLE_SMOOTH, + _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, TOGGLE_SMOOTH, [this] (bool clicked) { setSixenseFilter(clicked); }, true, true); diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp index ec0c35cc96..b315a7a3d9 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp @@ -60,7 +60,7 @@ void ViveControllerManager::activate() { InputPlugin::activate(); #ifdef Q_OS_WIN _container->addMenu(MENU_PATH); - _container->addMenuItem(MENU_PATH, RENDER_CONTROLLERS, + _container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, RENDER_CONTROLLERS, [this] (bool clicked) { this->setRenderControllers(clicked); }, true, true); diff --git a/libraries/plugins/src/plugins/Forward.h b/libraries/plugins/src/plugins/Forward.h index 8d8259ba4f..036b42f7d7 100644 --- a/libraries/plugins/src/plugins/Forward.h +++ b/libraries/plugins/src/plugins/Forward.h @@ -10,6 +10,11 @@ #include #include +enum class PluginType { + DISPLAY_PLUGIN, + INPUT_PLUGIN, +}; + class DisplayPlugin; class InputPlugin; class Plugin; diff --git a/libraries/plugins/src/plugins/PluginContainer.h b/libraries/plugins/src/plugins/PluginContainer.h index 25c2bcb11f..337ffd3c57 100644 --- a/libraries/plugins/src/plugins/PluginContainer.h +++ b/libraries/plugins/src/plugins/PluginContainer.h @@ -10,6 +10,10 @@ #include #include #include +#include +#include + +#include "Forward.h" class QAction; class QGLWidget; @@ -24,9 +28,11 @@ public: static PluginContainer& getInstance(); PluginContainer(); virtual ~PluginContainer(); + virtual QVector>& currentDisplayActions() = 0; + virtual QVector>& currentInputActions() = 0; virtual void addMenu(const QString& menuName) = 0; virtual void removeMenu(const QString& menuName) = 0; - virtual QAction* addMenuItem(const QString& path, const QString& name, std::function onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") = 0; + virtual QAction* addMenuItem(PluginType pluginType, const QString& path, const QString& name, std::function onClicked, bool checkable = false, bool checked = false, const QString& groupName = "") = 0; virtual void removeMenuItem(const QString& menuName, const QString& menuItem) = 0; virtual bool isOptionChecked(const QString& name) = 0; virtual void setIsOptionChecked(const QString& path, bool checked) = 0; diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index b6690ea76e..7c057c7152 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -68,6 +68,7 @@ void OculusBaseDisplayPlugin::deinit() { } void OculusBaseDisplayPlugin::activate() { + WindowOpenGLDisplayPlugin::activate(); #if (OVR_MAJOR_VERSION >= 6) if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { qFatal("Could not init OVR"); @@ -134,8 +135,6 @@ void OculusBaseDisplayPlugin::activate() { qFatal("Could not attach to sensor device"); } #endif - - WindowOpenGLDisplayPlugin::activate(); } void OculusBaseDisplayPlugin::deactivate() { diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index 21c318677e..8846b8a6a6 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -144,7 +144,7 @@ static const QString MONO_PREVIEW = "Mono Preview"; static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate"; void OculusDisplayPlugin::activate() { - _container->addMenuItem(MENU_PATH(), MONO_PREVIEW, + _container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), MONO_PREVIEW, [this](bool clicked) { _monoPreview = clicked; }, true, true);