mirror of
https://github.com/overte-org/overte.git
synced 2025-04-07 12:53:44 +02:00
Working on splash rendering
This commit is contained in:
parent
a0e1d2e54e
commit
d478204722
8 changed files with 302 additions and 186 deletions
|
@ -1266,9 +1266,32 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Make sure the window is set to the correct size by processing the pending events
|
||||
QCoreApplication::processEvents();
|
||||
_glWidget->createContext();
|
||||
_glWidget->makeCurrent();
|
||||
|
||||
// Create the main thread context, the GPU backend, and the display plugins
|
||||
initializeGL();
|
||||
qCDebug(interfaceapp, "Initialized Display.");
|
||||
// Create the rendering engine. This can be slow on some machines due to lots of
|
||||
// GPU pipeline creation.
|
||||
initializeRenderEngine();
|
||||
qCDebug(interfaceapp, "Initialized Render Engine.");
|
||||
|
||||
// Initialize the user interface and menu system
|
||||
// Needs to happen AFTER the render engine initialization to access its configuration
|
||||
initializeUi();
|
||||
|
||||
init();
|
||||
qCDebug(interfaceapp, "init() complete.");
|
||||
|
||||
// create thread for parsing of octree data independent of the main network and rendering threads
|
||||
_octreeProcessor.initialize(_enableProcessOctreeThread);
|
||||
connect(&_octreeProcessor, &OctreePacketProcessor::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
|
||||
_entityEditSender.initialize(_enableProcessOctreeThread);
|
||||
|
||||
_idleLoopStdev.reset();
|
||||
|
||||
// update before the first render
|
||||
update(0);
|
||||
|
||||
// Make sure we don't time out during slow operations at startup
|
||||
updateHeartbeat();
|
||||
|
||||
|
@ -2430,48 +2453,47 @@ void Application::initializeGL() {
|
|||
_isGLInitialized = true;
|
||||
}
|
||||
|
||||
// Build a shared canvas / context for the Chromium processes
|
||||
_glWidget->makeCurrent();
|
||||
glClearColor(0.2f, 0.2f, 0.2f, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
_glWidget->swapBuffers();
|
||||
|
||||
#if !defined(DISABLE_QML)
|
||||
// Chromium rendering uses some GL functions that prevent nSight from capturing
|
||||
// frames, so we only create the shared context if nsight is NOT active.
|
||||
if (!nsightActive()) {
|
||||
_chromiumShareContext = new OffscreenGLCanvas();
|
||||
_chromiumShareContext->setObjectName("ChromiumShareContext");
|
||||
_chromiumShareContext->create(_glWidget->qglContext());
|
||||
_chromiumShareContext->makeCurrent();
|
||||
if (!_chromiumShareContext->makeCurrent()) {
|
||||
qCWarning(interfaceapp, "Unable to make chromium shared context current");
|
||||
}
|
||||
qt_gl_set_global_share_context(_chromiumShareContext->getContext());
|
||||
} else {
|
||||
qCWarning(interfaceapp) << "nSIGHT detected, disabling chrome rendering";
|
||||
// Build an offscreen GL context for the main thread.
|
||||
_offscreenContext = new OffscreenGLCanvas();
|
||||
_offscreenContext->setObjectName("MainThreadContext");
|
||||
_offscreenContext->create(_glWidget->qglContext());
|
||||
if (!_offscreenContext->makeCurrent()) {
|
||||
qFatal("Unable to make offscreen context current");
|
||||
}
|
||||
#endif
|
||||
_offscreenContext->doneCurrent();
|
||||
_offscreenContext->setThreadContext();
|
||||
|
||||
// Build a shared canvas / context for the QML rendering
|
||||
_glWidget->makeCurrent();
|
||||
_qmlShareContext = new OffscreenGLCanvas();
|
||||
_qmlShareContext->setObjectName("QmlShareContext");
|
||||
_qmlShareContext->create(_glWidget->qglContext());
|
||||
if (!_qmlShareContext->makeCurrent()) {
|
||||
qCWarning(interfaceapp, "Unable to make QML shared context current");
|
||||
// Move the GL widget context to the render event handler thread
|
||||
_renderEventHandler = new RenderEventHandler(_glWidget->qglContext());
|
||||
if (!_offscreenContext->makeCurrent()) {
|
||||
qFatal("Unable to make offscreen context current");
|
||||
}
|
||||
OffscreenQmlSurface::setSharedContext(_qmlShareContext->getContext());
|
||||
_qmlShareContext->doneCurrent();
|
||||
|
||||
// Create the GPU backend
|
||||
|
||||
// Requires the window context, because that's what's used in the actual rendering
|
||||
// and the GPU backend will make things like the VAO which cannot be shared across
|
||||
// contexts
|
||||
_glWidget->makeCurrent();
|
||||
gpu::Context::init<gpu::gl::GLBackend>();
|
||||
qApp->setProperty(hifi::properties::gl::MAKE_PROGRAM_CALLBACK,
|
||||
QVariant::fromValue((void*)(&gpu::gl::GLBackend::makeProgram)));
|
||||
_gpuContext = std::make_shared<gpu::Context>();
|
||||
// The gpu context can make child contexts for transfers, so
|
||||
// we need to restore primary rendering context
|
||||
_glWidget->makeCurrent();
|
||||
_gpuContext = std::make_shared<gpu::Context>();
|
||||
|
||||
initDisplay();
|
||||
qCDebug(interfaceapp, "Initialized Display.");
|
||||
// Restore the default main thread context
|
||||
_offscreenContext->makeCurrent();
|
||||
|
||||
updateDisplayMode();
|
||||
}
|
||||
|
||||
void Application::initializeRenderEngine() {
|
||||
_offscreenContext->makeCurrent();
|
||||
|
||||
// FIXME: on low end systems os the shaders take up to 1 minute to compile, so we pause the deadlock watchdog thread.
|
||||
DeadlockWatchdogThread::withPause([&] {
|
||||
|
@ -2488,66 +2510,44 @@ void Application::initializeGL() {
|
|||
// Now that OpenGL is initialized, we are sure we have a valid context and can create the various pipeline shaders with success.
|
||||
DependencyManager::get<GeometryCache>()->initializeShapePipelines();
|
||||
});
|
||||
|
||||
_offscreenContext = new OffscreenGLCanvas();
|
||||
_offscreenContext->setObjectName("MainThreadContext");
|
||||
_offscreenContext->create(_glWidget->qglContext());
|
||||
if (!_offscreenContext->makeCurrent()) {
|
||||
qFatal("Unable to make offscreen context current");
|
||||
}
|
||||
_offscreenContext->doneCurrent();
|
||||
_offscreenContext->setThreadContext();
|
||||
_renderEventHandler = new RenderEventHandler(_glWidget->qglContext());
|
||||
|
||||
// The UI can't be created until the primary OpenGL
|
||||
// context is created, because it needs to share
|
||||
// texture resources
|
||||
// Needs to happen AFTER the render engine initialization to access its configuration
|
||||
if (!_offscreenContext->makeCurrent()) {
|
||||
qFatal("Unable to make offscreen context current");
|
||||
}
|
||||
|
||||
initializeUi();
|
||||
qCDebug(interfaceapp, "Initialized Offscreen UI.");
|
||||
|
||||
if (!_offscreenContext->makeCurrent()) {
|
||||
qFatal("Unable to make offscreen context current");
|
||||
}
|
||||
init();
|
||||
qCDebug(interfaceapp, "init() complete.");
|
||||
|
||||
// create thread for parsing of octree data independent of the main network and rendering threads
|
||||
_octreeProcessor.initialize(_enableProcessOctreeThread);
|
||||
connect(&_octreeProcessor, &OctreePacketProcessor::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
|
||||
_entityEditSender.initialize(_enableProcessOctreeThread);
|
||||
|
||||
_idleLoopStdev.reset();
|
||||
|
||||
|
||||
// Restore the primary GL content for the main thread
|
||||
if (!_offscreenContext->makeCurrent()) {
|
||||
qFatal("Unable to make offscreen context current");
|
||||
}
|
||||
|
||||
// update before the first render
|
||||
update(0);
|
||||
}
|
||||
|
||||
extern void setupPreferences();
|
||||
|
||||
void Application::initializeUi() {
|
||||
// Build a shared canvas / context for the Chromium processes
|
||||
#if !defined(DISABLE_QML)
|
||||
// Chromium rendering uses some GL functions that prevent nSight from capturing
|
||||
// frames, so we only create the shared context if nsight is NOT active.
|
||||
if (!nsightActive()) {
|
||||
_chromiumShareContext = new OffscreenGLCanvas();
|
||||
_chromiumShareContext->setObjectName("ChromiumShareContext");
|
||||
_chromiumShareContext->create(_offscreenContext->getContext());
|
||||
if (!_chromiumShareContext->makeCurrent()) {
|
||||
qCWarning(interfaceapp, "Unable to make chromium shared context current");
|
||||
}
|
||||
qt_gl_set_global_share_context(_chromiumShareContext->getContext());
|
||||
_chromiumShareContext->doneCurrent();
|
||||
// Restore the GL widget context
|
||||
_offscreenContext->makeCurrent();
|
||||
} else {
|
||||
qCWarning(interfaceapp) << "nSIGHT detected, disabling chrome rendering";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Build a shared canvas / context for the QML rendering
|
||||
_qmlShareContext = new OffscreenGLCanvas();
|
||||
_qmlShareContext->setObjectName("QmlShareContext");
|
||||
_qmlShareContext->create(_offscreenContext->getContext());
|
||||
if (!_qmlShareContext->makeCurrent()) {
|
||||
qCWarning(interfaceapp, "Unable to make QML shared context current");
|
||||
}
|
||||
OffscreenQmlSurface::setSharedContext(_qmlShareContext->getContext());
|
||||
_qmlShareContext->doneCurrent();
|
||||
// Restore the GL widget context
|
||||
_offscreenContext->makeCurrent();
|
||||
// Make sure all QML surfaces share the main thread GL context
|
||||
OffscreenQmlSurface::setSharedContext(_offscreenContext->getContext());
|
||||
OffscreenQmlSurface::addWhitelistContextHandler(QUrl{ "OverlayWindowTest.qml" },
|
||||
[](QQmlContext* context) {
|
||||
qDebug() << "Whitelist OverlayWindow worked";
|
||||
context->setContextProperty("OverlayWindowTestString", "TestWorked");
|
||||
});
|
||||
OffscreenQmlSurface::addWhitelistContextHandler(QUrl{ "hifi/audio/Audio.qml" },
|
||||
[](QQmlContext* context) {
|
||||
qDebug() << "QQQ" << __FUNCTION__ << "Whitelist Audio worked";
|
||||
});
|
||||
|
||||
|
||||
AddressBarDialog::registerType();
|
||||
ErrorDialog::registerType();
|
||||
|
@ -2650,6 +2650,10 @@ void Application::initializeUi() {
|
|||
auto offscreenSurfaceCache = DependencyManager::get<OffscreenQmlSurfaceCache>();
|
||||
offscreenSurfaceCache->reserve(TabletScriptingInterface::QML, 1);
|
||||
offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2);
|
||||
|
||||
// Now that the menu is instantiated, ensure the display plugin menu is properly updated
|
||||
updateDisplayMode();
|
||||
flushMenuUpdates();
|
||||
}
|
||||
|
||||
|
||||
|
@ -4607,11 +4611,8 @@ QVector<EntityItemID> Application::pasteEntities(float x, float y, float z) {
|
|||
return _entityClipboard->sendEntities(&_entityEditSender, getEntities()->getTree(), x, y, z);
|
||||
}
|
||||
|
||||
void Application::initDisplay() {
|
||||
}
|
||||
|
||||
void Application::init() {
|
||||
|
||||
_offscreenContext->makeCurrent();
|
||||
// Make sure Login state is up to date
|
||||
DependencyManager::get<DialogsManager>()->toggleLoginDialog();
|
||||
if (!DISABLE_DEFERRED) {
|
||||
|
@ -7500,21 +7501,34 @@ void Application::updateDisplayMode() {
|
|||
qFatal("Attempted to switch display plugins from a non-main thread");
|
||||
}
|
||||
|
||||
auto menu = Menu::getInstance();
|
||||
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
|
||||
|
||||
// Once time initialization code
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
bool first = true;
|
||||
|
||||
// first sort the plugins into groupings: standard, advanced, developer
|
||||
DisplayPluginList standard;
|
||||
DisplayPluginList advanced;
|
||||
DisplayPluginList developer;
|
||||
foreach(auto displayPlugin, displayPlugins) {
|
||||
displayPlugin->setContext(_gpuContext);
|
||||
auto grouping = displayPlugin->getGrouping();
|
||||
switch (grouping) {
|
||||
QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged,
|
||||
[this](const QSize& size) { resizeGL(); });
|
||||
QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset);
|
||||
}
|
||||
});
|
||||
|
||||
// Once time initialization code that depends on the UI being available
|
||||
auto menu = Menu::getInstance();
|
||||
if (menu) {
|
||||
static std::once_flag onceUi;
|
||||
std::call_once(onceUi, [&] {
|
||||
bool first = true;
|
||||
|
||||
// first sort the plugins into groupings: standard, advanced, developer
|
||||
DisplayPluginList standard;
|
||||
DisplayPluginList advanced;
|
||||
DisplayPluginList developer;
|
||||
foreach(auto displayPlugin, displayPlugins) {
|
||||
displayPlugin->setContext(_gpuContext);
|
||||
auto grouping = displayPlugin->getGrouping();
|
||||
switch (grouping) {
|
||||
case Plugin::ADVANCED:
|
||||
advanced.push_back(displayPlugin);
|
||||
break;
|
||||
|
@ -7524,42 +7538,40 @@ void Application::updateDisplayMode() {
|
|||
default:
|
||||
standard.push_back(displayPlugin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// concatenate the groupings into a single list in the order: standard, advanced, developer
|
||||
standard.insert(std::end(standard), std::begin(advanced), std::end(advanced));
|
||||
standard.insert(std::end(standard), std::begin(developer), std::end(developer));
|
||||
// concatenate the groupings into a single list in the order: standard, advanced, developer
|
||||
standard.insert(std::end(standard), std::begin(advanced), std::end(advanced));
|
||||
standard.insert(std::end(standard), std::begin(developer), std::end(developer));
|
||||
|
||||
foreach(auto displayPlugin, standard) {
|
||||
addDisplayPluginToMenu(displayPlugin, first);
|
||||
auto displayPluginName = displayPlugin->getName();
|
||||
QObject::connect(displayPlugin.get(), &DisplayPlugin::recommendedFramebufferSizeChanged, [this](const QSize & size) {
|
||||
resizeGL();
|
||||
});
|
||||
QObject::connect(displayPlugin.get(), &DisplayPlugin::resetSensorsRequested, this, &Application::requestReset);
|
||||
first = false;
|
||||
}
|
||||
foreach(auto displayPlugin, standard) {
|
||||
addDisplayPluginToMenu(displayPlugin, first);
|
||||
first = false;
|
||||
}
|
||||
|
||||
// after all plugins have been added to the menu, add a separator to the menu
|
||||
auto menu = Menu::getInstance();
|
||||
auto parent = menu->getMenu(MenuOption::OutputMenu);
|
||||
parent->addSeparator();
|
||||
});
|
||||
// after all plugins have been added to the menu, add a separator to the menu
|
||||
auto parent = menu->getMenu(MenuOption::OutputMenu);
|
||||
parent->addSeparator();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Default to the first item on the list, in case none of the menu items match
|
||||
DisplayPluginPointer newDisplayPlugin = displayPlugins.at(0);
|
||||
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
|
||||
QString name = displayPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
// Menu might have been removed if the display plugin lost
|
||||
if (!action) {
|
||||
continue;
|
||||
}
|
||||
if (action->isChecked()) {
|
||||
newDisplayPlugin = displayPlugin;
|
||||
break;
|
||||
if (menu) {
|
||||
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
|
||||
QString name = displayPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
// Menu might have been removed if the display plugin lost
|
||||
if (!action) {
|
||||
continue;
|
||||
}
|
||||
if (action->isChecked()) {
|
||||
newDisplayPlugin = displayPlugin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7567,8 +7579,13 @@ void Application::updateDisplayMode() {
|
|||
return;
|
||||
}
|
||||
|
||||
setDisplayPlugin(newDisplayPlugin);
|
||||
}
|
||||
|
||||
void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
auto desktop = offscreenUi->getDesktop();
|
||||
auto menu = Menu::getInstance();
|
||||
|
||||
// Make the switch atomic from the perspective of other threads
|
||||
{
|
||||
|
@ -7589,6 +7606,8 @@ void Application::updateDisplayMode() {
|
|||
bool active = newDisplayPlugin->activate();
|
||||
|
||||
if (!active) {
|
||||
auto displayPlugins = PluginManager::getInstance()->getDisplayPlugins();
|
||||
|
||||
// If the new plugin fails to activate, fallback to last display
|
||||
qWarning() << "Failed to activate display: " << newDisplayPlugin->getName();
|
||||
newDisplayPlugin = oldDisplayPlugin;
|
||||
|
@ -7609,13 +7628,6 @@ void Application::updateDisplayMode() {
|
|||
if (!active) {
|
||||
qFatal("Failed to activate fallback plugin");
|
||||
}
|
||||
|
||||
// We've changed the selection - it should be reflected in the menu
|
||||
QAction* action = menu->getActionForOption(newDisplayPlugin->getName());
|
||||
if (!action) {
|
||||
qFatal("Failed to find activated plugin");
|
||||
}
|
||||
action->setChecked(true);
|
||||
}
|
||||
|
||||
offscreenUi->resize(fromGlm(newDisplayPlugin->getRecommendedUiSize()));
|
||||
|
@ -7642,14 +7654,21 @@ void Application::updateDisplayMode() {
|
|||
getMyAvatar()->reset(false);
|
||||
|
||||
// switch to first person if entering hmd and setting is checked
|
||||
if (isHmd && menu->isOptionChecked(MenuOption::FirstPersonHMD)) {
|
||||
menu->setIsOptionChecked(MenuOption::FirstPerson, true);
|
||||
cameraMenuChanged();
|
||||
}
|
||||
if (menu) {
|
||||
QAction* action = menu->getActionForOption(newDisplayPlugin->getName());
|
||||
if (action) {
|
||||
action->setChecked(true);
|
||||
}
|
||||
|
||||
// Remove the mirror camera option from menu if in HMD mode
|
||||
auto mirrorAction = menu->getActionForOption(MenuOption::FullscreenMirror);
|
||||
mirrorAction->setVisible(!isHmd);
|
||||
if (isHmd && menu->isOptionChecked(MenuOption::FirstPersonHMD)) {
|
||||
menu->setIsOptionChecked(MenuOption::FirstPerson, true);
|
||||
cameraMenuChanged();
|
||||
}
|
||||
|
||||
// Remove the mirror camera option from menu if in HMD mode
|
||||
auto mirrorAction = menu->getActionForOption(MenuOption::FullscreenMirror);
|
||||
mirrorAction->setVisible(!isHmd);
|
||||
}
|
||||
|
||||
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
|
||||
}
|
||||
|
@ -7725,15 +7744,18 @@ void Application::unresponsiveApplication() {
|
|||
}
|
||||
|
||||
void Application::setActiveDisplayPlugin(const QString& pluginName) {
|
||||
auto menu = Menu::getInstance();
|
||||
foreach(DisplayPluginPointer displayPlugin, PluginManager::getInstance()->getDisplayPlugins()) {
|
||||
DisplayPluginPointer newDisplayPlugin;
|
||||
for (DisplayPluginPointer displayPlugin : PluginManager::getInstance()->getDisplayPlugins()) {
|
||||
QString name = displayPlugin->getName();
|
||||
QAction* action = menu->getActionForOption(name);
|
||||
if (pluginName == name) {
|
||||
action->setChecked(true);
|
||||
newDisplayPlugin = displayPlugin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
updateDisplayMode();
|
||||
|
||||
if (newDisplayPlugin) {
|
||||
setDisplayPlugin(newDisplayPlugin);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::handleLocalServerConnection() const {
|
||||
|
|
|
@ -145,6 +145,7 @@ public:
|
|||
Q_INVOKABLE QString getUserAgent();
|
||||
|
||||
void initializeGL();
|
||||
void initializeRenderEngine();
|
||||
void initializeUi();
|
||||
|
||||
void updateCamera(RenderArgs& renderArgs, float deltaTime);
|
||||
|
@ -437,6 +438,7 @@ private slots:
|
|||
static void packetSent(quint64 length);
|
||||
static void addingEntityWithCertificate(const QString& certificateID, const QString& placeName);
|
||||
void updateDisplayMode();
|
||||
void setDisplayPlugin(DisplayPluginPointer newPlugin);
|
||||
void domainConnectionRefused(const QString& reasonMessage, int reason, const QString& extraInfo);
|
||||
|
||||
void addAssetToWorldCheckModelSize();
|
||||
|
@ -449,7 +451,6 @@ private slots:
|
|||
void switchDisplayMode();
|
||||
|
||||
private:
|
||||
static void initDisplay();
|
||||
void init();
|
||||
bool handleKeyEventForFocusedEntityOrOverlay(QEvent* event);
|
||||
bool handleFileOpenEvent(QFileOpenEvent* event);
|
||||
|
|
|
@ -56,10 +56,8 @@ glm::mat4 StereoDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& basePr
|
|||
|
||||
static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate";
|
||||
|
||||
std::vector<QAction*> _screenActions;
|
||||
bool StereoDisplayPlugin::internalActivate() {
|
||||
auto screens = qApp->screens();
|
||||
_screenActions.resize(screens.size());
|
||||
for (int i = 0; i < screens.size(); ++i) {
|
||||
auto screen = screens.at(i);
|
||||
QString name = QString("Screen %1: %2").arg(i + 1).arg(screen->name());
|
||||
|
@ -67,9 +65,9 @@ bool StereoDisplayPlugin::internalActivate() {
|
|||
if (screen == qApp->primaryScreen()) {
|
||||
checked = true;
|
||||
}
|
||||
auto action = _container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), name,
|
||||
[this](bool clicked) { updateScreen(); }, true, checked, "Screens");
|
||||
_screenActions[i] = action;
|
||||
const uint32_t screenIndex = i;
|
||||
_container->addMenuItem(PluginType::DISPLAY_PLUGIN, MENU_PATH(), name,
|
||||
[=](bool clicked) { updateScreen(screenIndex); }, true, checked, "Screens");
|
||||
}
|
||||
|
||||
_container->removeMenu(FRAMERATE);
|
||||
|
@ -80,18 +78,12 @@ bool StereoDisplayPlugin::internalActivate() {
|
|||
return Parent::internalActivate();
|
||||
}
|
||||
|
||||
void StereoDisplayPlugin::updateScreen() {
|
||||
for (uint32_t i = 0; i < _screenActions.size(); ++i) {
|
||||
if (_screenActions[i]->isChecked()) {
|
||||
_screen = qApp->screens().at(i);
|
||||
_container->setFullscreen(_screen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
void StereoDisplayPlugin::updateScreen(uint32_t i) {
|
||||
_screen = qApp->screens().at(i);
|
||||
_container->setFullscreen(_screen);
|
||||
}
|
||||
|
||||
void StereoDisplayPlugin::internalDeactivate() {
|
||||
_screenActions.clear();
|
||||
_container->unsetFullscreen();
|
||||
Parent::internalDeactivate();
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
protected:
|
||||
virtual bool internalActivate() override;
|
||||
virtual void internalDeactivate() override;
|
||||
void updateScreen();
|
||||
void updateScreen(uint32_t i);
|
||||
|
||||
float _ipd{ 0.064f };
|
||||
QScreen* _screen;
|
||||
|
|
|
@ -72,6 +72,10 @@ void GLWidget::createContext() {
|
|||
_context->doneCurrent();
|
||||
}
|
||||
|
||||
void GLWidget::swapBuffers() {
|
||||
_context->swapBuffers();
|
||||
}
|
||||
|
||||
bool GLWidget::makeCurrent() {
|
||||
gl::Context::makeCurrent(_context->qglContext(), windowHandle());
|
||||
return _context->makeCurrent();
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
void createContext();
|
||||
bool makeCurrent();
|
||||
void doneCurrent();
|
||||
void swapBuffers();
|
||||
gl::Context* context() { return _context; }
|
||||
QOpenGLContext* qglContext();
|
||||
|
||||
|
|
|
@ -34,48 +34,140 @@ PluginContainer::~PluginContainer() {
|
|||
INSTANCE = nullptr;
|
||||
};
|
||||
|
||||
struct MenuCache {
|
||||
QSet<QString> menus;
|
||||
struct Item {
|
||||
QString path;
|
||||
std::function<void(bool)> onClicked;
|
||||
bool checkable;
|
||||
bool checked;
|
||||
QString groupName;
|
||||
};
|
||||
QHash<QString, Item> items;
|
||||
std::map<QString, QActionGroup*> _exclusiveGroups;
|
||||
|
||||
void addMenu(ui::Menu* menu, const QString& menuName) {
|
||||
if (!menu) {
|
||||
menus.insert(menuName);
|
||||
return;
|
||||
}
|
||||
|
||||
flushCache(menu);
|
||||
menu->addMenu(menuName);
|
||||
}
|
||||
|
||||
void removeMenu(ui::Menu* menu, const QString& menuName) {
|
||||
if (!menu) {
|
||||
menus.remove(menuName);
|
||||
return;
|
||||
}
|
||||
flushCache(menu);
|
||||
menu->removeMenu(menuName);
|
||||
}
|
||||
|
||||
void addMenuItem(ui::Menu* menu, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
|
||||
if (!menu) {
|
||||
items[name] = Item{ path, onClicked, checkable, checked, groupName };
|
||||
return;
|
||||
}
|
||||
flushCache(menu);
|
||||
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);
|
||||
}
|
||||
QObject::connect(action, &QAction::triggered, [=] {
|
||||
onClicked(action->isChecked());
|
||||
});
|
||||
action->setCheckable(checkable);
|
||||
action->setChecked(checked);
|
||||
}
|
||||
void removeMenuItem(ui::Menu* menu, const QString& menuName, const QString& menuItemName) {
|
||||
if (!menu) {
|
||||
items.remove(menuItemName);
|
||||
return;
|
||||
}
|
||||
flushCache(menu);
|
||||
menu->removeMenuItem(menuName, menuItemName);
|
||||
}
|
||||
|
||||
bool isOptionChecked(ui::Menu* menu, const QString& name) {
|
||||
if (!menu) {
|
||||
return items.contains(name) && items[name].checked;
|
||||
}
|
||||
flushCache(menu);
|
||||
return menu->isOptionChecked(name);
|
||||
}
|
||||
|
||||
void setIsOptionChecked(ui::Menu* menu, const QString& name, bool checked) {
|
||||
if (!menu) {
|
||||
if (items.contains(name)) {
|
||||
items[name].checked = checked;
|
||||
}
|
||||
return;
|
||||
}
|
||||
flushCache(menu);
|
||||
|
||||
}
|
||||
|
||||
void flushCache(ui::Menu* menu) {
|
||||
if (!menu) {
|
||||
return;
|
||||
}
|
||||
static bool flushed = false;
|
||||
if (flushed) {
|
||||
return;
|
||||
}
|
||||
flushed = true;
|
||||
for (const auto& menuName : menus) {
|
||||
addMenu(menu, menuName);
|
||||
}
|
||||
menus.clear();
|
||||
|
||||
for (const auto& menuItemName : items.keys()) {
|
||||
const auto menuItem = items[menuItemName];
|
||||
addMenuItem(menu, menuItem.path, menuItemName, menuItem.onClicked, menuItem.checkable, menuItem.checked, menuItem.groupName);
|
||||
}
|
||||
items.clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static MenuCache& getMenuCache() {
|
||||
static MenuCache cache;
|
||||
return cache;
|
||||
}
|
||||
|
||||
void PluginContainer::addMenu(const QString& menuName) {
|
||||
getPrimaryMenu()->addMenu(menuName);
|
||||
getMenuCache().addMenu(getPrimaryMenu(), menuName);
|
||||
}
|
||||
|
||||
void PluginContainer::removeMenu(const QString& menuName) {
|
||||
getPrimaryMenu()->removeMenu(menuName);
|
||||
getMenuCache().removeMenu(getPrimaryMenu(), menuName);
|
||||
}
|
||||
|
||||
QAction* PluginContainer::addMenuItem(PluginType type, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
|
||||
auto menu = getPrimaryMenu();
|
||||
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);
|
||||
}
|
||||
QObject::connect(action, &QAction::triggered, [=] {
|
||||
onClicked(action->isChecked());
|
||||
});
|
||||
action->setCheckable(checkable);
|
||||
action->setChecked(checked);
|
||||
void PluginContainer::addMenuItem(PluginType type, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable, bool checked, const QString& groupName) {
|
||||
getMenuCache().addMenuItem(getPrimaryMenu(), path, name, onClicked, checkable, checked, groupName);
|
||||
if (type == PluginType::DISPLAY_PLUGIN) {
|
||||
_currentDisplayPluginActions.push_back({ path, name });
|
||||
} else {
|
||||
_currentInputPluginActions.push_back({ path, name });
|
||||
}
|
||||
return action;
|
||||
}
|
||||
|
||||
void PluginContainer::removeMenuItem(const QString& menuName, const QString& menuItem) {
|
||||
getPrimaryMenu()->removeMenuItem(menuName, menuItem);
|
||||
getMenuCache().removeMenuItem(getPrimaryMenu(), menuName, menuItem);
|
||||
}
|
||||
|
||||
bool PluginContainer::isOptionChecked(const QString& name) {
|
||||
return getPrimaryMenu()->isOptionChecked(name);
|
||||
return getMenuCache().isOptionChecked(getPrimaryMenu(), name);
|
||||
}
|
||||
|
||||
void PluginContainer::setIsOptionChecked(const QString& path, bool checked) {
|
||||
|
@ -161,3 +253,7 @@ void PluginContainer::setBoolSetting(const QString& settingName, bool value) {
|
|||
Setting::Handle<bool> settingValue(settingName, value);
|
||||
return settingValue.set(value);
|
||||
}
|
||||
|
||||
void PluginContainer::flushMenuUpdates() {
|
||||
getMenuCache().flushCache(getPrimaryMenu());
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public:
|
|||
|
||||
void addMenu(const QString& menuName);
|
||||
void removeMenu(const QString& menuName);
|
||||
QAction* addMenuItem(PluginType pluginType, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "");
|
||||
void addMenuItem(PluginType pluginType, const QString& path, const QString& name, std::function<void(bool)> onClicked, bool checkable = false, bool checked = false, const QString& groupName = "");
|
||||
void removeMenuItem(const QString& menuName, const QString& menuItem);
|
||||
bool isOptionChecked(const QString& name);
|
||||
void setIsOptionChecked(const QString& path, bool checked);
|
||||
|
@ -77,9 +77,9 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
void flushMenuUpdates();
|
||||
QVector<QPair<QString, QString>> _currentDisplayPluginActions;
|
||||
QVector<QPair<QString, QString>> _currentInputPluginActions;
|
||||
std::map<QString, QActionGroup*> _exclusiveGroups;
|
||||
QRect _savedGeometry { 10, 120, 800, 600 };
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue