HifiExperimentsruntime gl api switchingebcc81c6 months agoHistory
964 lines · 33.2 KB · C
RawDownload
////  Application.h//  interface/src////  Created by Andrzej Kapolka on 5/10/13.//  Copyright 2013 High Fidelity, Inc.//  Copyright 2020 Vircadia contributors.//  Copyright 2022-2023 Overte e.V.////  Distributed under the Apache License, Version 2.0.//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html//  SPDX-License-Identifier: Apache-2.0// #ifndef hifi_Application_h#define hifi_Application_h #include <QtWidgets/QApplication> #include <AbstractScriptingServicesInterface.h>#include <AbstractUriHandler.h>#include <AbstractViewStateInterface.h>#include <AvatarHashMap.h>#include <EntityEditPacketSender.h>#include <ModerationFlags.h>#include <OctreeQuery.h>#include <PhysicsEngine.h>#include <ShapeManager.h>#include <TouchEvent.h>#include <ui-plugins/PluginContainer.h> #include "avatar/MyAvatar.h"#include "ConnectionMonitor.h"#include "CursorManager.h"#include "FancyCamera.h"#include "graphics/GraphicsEngine.h"#include "LoginStateManager.h"#include "octree/OctreePacketProcessor.h"#include "PerformanceManager.h"#include "RefreshRateManager.h"#include "scripting/DialogsManagerScriptingInterface.h"#include "ui/ApplicationOverlay.h"#include "ui/OverlayConductor.h"#include "ui/overlays/Overlays.h"#include "VisionSqueeze.h"#include "workload/GameWorkload.h"#ifndef USE_GL#include "VKCanvas.h"#endif class ArchiveDownloadInterface;class AudioInjector;class CompositorHelper;class ControllerScriptingInterface;class DiscordPresence;class EntityScriptServerLogDialog;class FileLogger;class GLCanvas;class KeyboardMouseDevice;class LogDialog;class MainWindow;class ModalDialogListener;class OffscreenUi;class TouchscreenDevice;class TouchscreenVirtualPadDevice;class QCommandLineParser;class QGestureEvent;class QQmlContext;class QQuickItem; namespace controller {    class StateController;} class Application;#if defined(qApp)#undef qApp#endif#define qApp (static_cast<Application*>(QCoreApplication::instance())) class Application : public QApplication,                    public AbstractViewStateInterface,                    public AbstractScriptingServicesInterface,                    public AbstractUriHandler,                    public PluginContainer{    Q_OBJECT public:    Application(        int& argc, char** argv,        QElapsedTimer& startup_time    );    ~Application();     /**     * @brief Initialize everything     *     * This is a QApplication, and for Qt reasons it's desirable to create this object     * as early as possible. Without that some Qt functions don't work, like QCoreApplication::applicationDirPath()     *     * So we keep the constructor as minimal as possible, and do the rest of the work in     * this function.     */    void initialize(const QCommandLineParser &parser);     MainWindow* getWindow() const { return _window; }    virtual QThread* getMainThread() override { return thread(); }     bool isAboutToQuit() const { return _aboutToQuit; }    bool isServerlessMode() const;    bool isInterstitialMode() const { return _interstitialMode; }    bool failedToConnectToEntityServer() const { return _failedToConnectToEntityServer; }     void setPreviousSessionCrashed(bool value) { _previousSessionCrashed = value; }     // Return an HTTP User-Agent string with OS and device information.    Q_INVOKABLE QString getUserAgent();     PerformanceManager& getPerformanceManager() { return _performanceManager; }    RefreshRateManager& getRefreshRateManager() { return _refreshRateManager; }    float getGameLoopRate() const { return _gameLoopCounter.rate(); } #ifndef Q_OS_ANDROID    FileLogger* getLogger() const { return _logger; }#endif     bool getUseDiscordPresence() const { return _useDiscordPresence.get(); }    void setUseDiscordPresence(bool enable);     QString getPreviousScriptLocation() { return _previousScriptLocation.get(); }    void setPreviousScriptLocation(const QString& previousScriptLocation) { _previousScriptLocation.set(previousScriptLocation); }     void replaceDomainContent(const QString& url, const QString& itemName);     void openDirectory(const QString& path);     void overrideEntry() { _overrideEntry = true; }    void forceDisplayName(const QString& displayName) { getMyAvatar()->setDisplayName(displayName); }    void forceLoginWithTokens(const QString& tokens);    void setConfigFileURL(const QString& fileUrl);     void loadAvatarScripts(const QVector<QString>& urls);    void unloadAvatarScripts();     Q_INVOKABLE void copyToClipboard(const QString& text);     Q_INVOKABLE void setMinimumGPUTextureMemStabilityCount(int stabilityCount) { _minimumGPUTextureMemSizeStabilityCount = stabilityCount; }     virtual ControllerScriptingInterface* getControllerScriptingInterface() { return _controllerScriptingInterface; }    virtual void registerScriptEngineWithApplicationServices(ScriptManagerPointer& scriptManager) override;     // used by preferences and HMDScriptingInterface...    VisionSqueeze& getVisionSqueeze() { return _visionSqueeze; }      // UI    virtual ui::Menu* getPrimaryMenu() override;    virtual void showDisplayPluginsTools(bool show) override;#ifdef USE_GL    virtual GLWidget* getPrimaryWidget() override;#else    virtual VKWidget* getPrimaryWidget() override;#endif    virtual MainWindow* getPrimaryWindow() override;    virtual QOpenGLContext* getPrimaryContext() override;    virtual bool isForeground() const override;     bool hasFocus() const;    void setFocus();    void raise();     void showCursor(const Cursor::Icon& cursor);     Overlays& getOverlays() { return _overlays; }    ApplicationOverlay& getApplicationOverlay() { return *_applicationOverlay; }    const ApplicationOverlay& getApplicationOverlay() const { return *_applicationOverlay; }    CompositorHelper& getApplicationCompositor() const;     virtual PickRay computePickRay(float x, float y) const override;     static void setupQmlSurface(QQmlContext* surfaceContext, bool setAdditionalContextProperties);     float getHMDTabletScale() { return _hmdTabletScale.get(); }    void setHMDTabletScale(float hmdTabletScale) { _hmdTabletScale.set(hmdTabletScale); }    float getDesktopTabletScale() { return _desktopTabletScale.get(); }    void setDesktopTabletScale(float desktopTabletScale) { _desktopTabletScale.set(desktopTabletScale); }     bool getDesktopTabletBecomesToolbarSetting() { return _desktopTabletBecomesToolbarSetting.get(); }    void setDesktopTabletBecomesToolbarSetting(bool value);    bool getHmdTabletBecomesToolbarSetting() { return _hmdTabletBecomesToolbarSetting.get(); }    void setHmdTabletBecomesToolbarSetting(bool value);     bool getLogWindowOnTopSetting() { return _keepLogWindowOnTop.get(); }    void setLogWindowOnTopSetting(bool keepOnTop) { _keepLogWindowOnTop.set(keepOnTop); }    bool getPreferStylusOverLaser() { return _preferStylusOverLaserSetting.get(); }    void setPreferStylusOverLaser(bool value) { _preferStylusOverLaserSetting.set(value); }    bool getPreferAvatarFingerOverStylus() { return _preferAvatarFingerOverStylusSetting.get(); }    void setPreferAvatarFingerOverStylus(bool value) { _preferAvatarFingerOverStylusSetting.set(value); }        void setMouseCaptureVR(bool value);    bool getMouseCaptureVR();     bool getMiniTabletEnabled() { return _miniTabletEnabledSetting.get(); }    void setMiniTabletEnabled(bool enabled);     float getSettingConstrainToolbarPosition() { return _constrainToolbarPosition.get(); }    void setSettingConstrainToolbarPosition(bool setting);     float getAwayStateWhenFocusLostInVREnabled() { return _awayStateWhenFocusLostInVREnabled.get(); }    void setAwayStateWhenFocusLostInVREnabled(bool setting);     QUuid getTabletScreenID() const;    QUuid getTabletHomeButtonID() const;    QUuid getTabletFrameID() const;    QVector<QUuid> getTabletIDs() const;     void confirmConnectWithoutAvatarEntities();     bool getLoginDialogPoppedUp() const { return _loginDialogPoppedUp; }    void createLoginDialog();    void updateLoginDialogPosition();     void createAvatarInputsBar();    void destroyAvatarInputsBar();      // Plugins    /**     * @brief Initialize the plugin manager     *     * This both does the initial startup and parses arguments. This     * is necessary because the plugin manager's options must be set     * before any usage of it is made, or they won't apply.     *     * @param parser     */    void initializePluginManager(const QCommandLineParser& parser);     virtual void requestReset() override { resetSensors(false); }    virtual bool makeRenderingContextCurrent() override { return true; }     static void shutdownPlugins();     void initializeDisplayPlugins();    virtual DisplayPluginPointer getActiveDisplayPlugin() const override;    void setActiveDisplayPlugin(const QString& pluginName);     glm::uvec2 getUiSize() const;    QRect getRecommendedHUDRect() const;    glm::vec2 getDeviceSize() const;    bool isThrottleRendering() const;    float getTargetRenderFrameRate() const;  // frames/second     // Check if a headset is connected    bool hasRiftControllers();    bool hasViveControllers();     // the isHMDMode is true whenever we use the interface from an HMD and not a standard flat display    // rendering of several elements depend on that    // TODO: carry that information on the Camera as a setting    virtual bool isHMDMode() const override;    glm::mat4 getHMDSensorPose() const;    glm::mat4 getEyeOffset(int eye) const;    glm::mat4 getEyeProjection(int eye) const;      // Graphics    void initializeGL();    void initializeRenderEngine();    void initializeUi();     void resizeGL();     glm::uvec2 getCanvasSize() const;    float getRenderResolutionScale() const;     render::ScenePointer getMain3DScene() override { return _graphicsEngine->getRenderScene(); }    render::EnginePointer getRenderEngine() override { return _graphicsEngine->getRenderEngine(); }    gpu::ContextPointer getGPUContext() const { return _graphicsEngine->getGPUContext(); }    float getRenderLoopRate() const { return _graphicsEngine->getRenderLoopRate(); }      // Events    bool notify(QObject*, QEvent*) override;    bool event(QEvent* event) override;    bool eventFilter(QObject* object, QEvent* event) override;     void postLambdaEvent(const std::function<void()>& f) override;    void sendLambdaEvent(const std::function<void()>& f) override;    virtual void pushPostUpdateLambda(void* key, const std::function<void()>& func) override;      // Camera    Camera& getCamera() { return _myCamera; }    const Camera& getCamera() const { return _myCamera; }    // Represents the current view frustum of the avatar.    void copyViewFrustum(ViewFrustum& viewOut) const;    // Represents the view frustum of the current rendering pass,    // which might be different from the viewFrustum, i.e. shadowmap    // passes, mirror window passes, etc    void copyDisplayViewFrustum(ViewFrustum& viewOut) const;     void updateCamera(RenderArgs& renderArgs, float deltaTime);    void updateSecondaryCameraViewFrustum();     const ConicalViewFrustums& getConicalViews() const override { return _conicalViews; }     float getFieldOfView() { return _fieldOfView.get(); }    void setFieldOfView(float fov);     bool getCameraClippingEnabled() { return _cameraClippingEnabled.get(); }    void setCameraClippingEnabled(bool enabled);     void updateMyAvatarLookAtPosition(float deltaTime);      // Entities    QSharedPointer<EntityTreeRenderer> getEntities() const { return DependencyManager::get<EntityTreeRenderer>(); }    EntityTreePointer getEntityClipboard() const { return _entityClipboard; }    const OctreePacketProcessor& getOctreePacketProcessor() const { return *_octreeProcessor; }    std::shared_ptr<EntityEditPacketSender> getEntityEditPacketSender() { return _entityEditSender; }     void setMaxOctreePacketsPerSecond(int maxOctreePPS);    int getMaxOctreePacketsPerSecond() const { return _maxOctreePPS; }    bool isMissingSequenceNumbers() { return _isMissingSequenceNumbers; }     NodeToOctreeSceneStats* getOcteeSceneStats() { return _octreeProcessor->getOctreeSceneStats(); }      // Assets    virtual bool canAcceptURL(const QString& url) const override;    virtual bool acceptURL(const QString& url, bool defaultUpload = false) override;      // Physics    bool isPhysicsEnabled() const { return _physicsEnabled; }    PhysicsEnginePointer getPhysicsEngine() { return _physicsEngine; }    const GameWorkload& getGameWorkload() const { return _gameWorkload; }     float getNumCollisionObjects() const { return _physicsEngine ? _physicsEngine->getNumCollisionObjects() : 0; }    void saveNextPhysicsStats(QString filename) { _physicsEngine->saveNextPhysicsStats(filename); }      // Avatar    virtual glm::vec3 getAvatarPosition() const override { return getMyAvatar()->getWorldPosition(); }     void clearAvatarOverrideUrl() { _avatarOverrideUrl = QUrl(); _saveAvatarOverrideUrl = false; }    QUrl getAvatarOverrideUrl() { return _avatarOverrideUrl; }    bool getSaveAvatarOverrideUrl() { return _saveAvatarOverrideUrl; }     int getOtherAvatarsReplicaCount() { return DependencyManager::get<AvatarHashMap>()->getReplicaCount(); }    void setOtherAvatarsReplicaCount(int count) { DependencyManager::get<AvatarHashMap>()->setReplicaCount(count); }      // Snapshots    using SnapshotOperator = std::tuple<std::function<void(const QImage&)>, float, bool>;    void addSnapshotOperator(const SnapshotOperator& snapshotOperator);    bool takeSnapshotOperators(std::queue<SnapshotOperator>& snapshotOperators);     void takeSnapshot(bool notify, bool includeAnimated = false, float aspectRatio = 0.0f, const QString& filename = QString());    void takeSecondaryCameraSnapshot(const bool& notify, const QString& filename = QString());    void takeSecondaryCamera360Snapshot(const glm::vec3& cameraPosition,                                        const bool& cubemapOutputFormat,                                        const bool& notify,                                        const QString& filename = QString());    void shareSnapshot(const QString& filename, const QUrl& href = QUrl(""));  #if defined(Q_OS_ANDROID)    void beforeEnterBackground();    void enterBackground();    void enterForeground();    void toggleAwayMode();#endif signals:    void svoImportRequested(const QString& url);     void fullAvatarURLChanged(const QString& newValue, const QString& modelName);     void beforeAboutToQuit();    void activeDisplayPluginChanged();     void uploadRequest(QString path);     void interstitialModeChanged(bool isInInterstitialMode);     void loginDialogFocusEnabled();    void loginDialogFocusDisabled();     void miniTabletEnabledChanged(bool enabled);    void awayStateWhenFocusLostInVRChanged(bool enabled);     void darkThemePreferenceChanged(bool useDarkTheme);    void menuBarVisibilityChanged(bool visible); public slots:    void updateThreadPoolCount() const;     static void gotoTutorial();    void goToErrorDomainURL(QUrl errorDomainURL);    void handleLocalServerConnection() const;    void readArgumentsFromLocalSocket() const;    void showUrlHandler(const QUrl& url); #if (PR_BUILD || DEV_BUILD)    void sendWrongProtocolVersionsSignature(bool checked) { ::sendWrongProtocolVersionsSignature(checked); }#endif     void hmdVisibleChanged(bool visible);     void reloadResourceCaches();     void updateHeartbeat() const;     static void deadlockApplication();    static void unresponsiveApplication();  // cause main thread to be unresponsive for 35 seconds    void crashOnShutdown(); // used to test "shutdown" crash annotation.     void rotationModeChanged() const;     void setIsServerlessMode(bool serverlessDomain);    std::map<QString, QString> prepareServerlessDomainContents(QUrl domainURL, QByteArray data);     void loadServerlessDomain(QUrl domainURL);    void loadErrorDomain(QUrl domainURL);    void setIsInterstitialMode(bool interstitialMode);     void updateVerboseLogging();     void setCachebustRequire();     QString getGraphicsCardType();    bool gpuTextureMemSizeStable();     Q_INVOKABLE SharedSoundPointer getSampleSound() const { return _sampleSound; }     static void runTests();     // UI    void showDialog(const QUrl& widgetUrl, const QUrl& tabletUrl, const QString& name) const;    Q_INVOKABLE void loadDialog();    Q_INVOKABLE void loadScriptURLDialog() const;    void toggleLogDialog();    void recreateLogWindow(int);    void toggleEntityScriptServerLogDialog();    Q_INVOKABLE void showAssetServerWidget(QString filePath = "");    Q_INVOKABLE void loadAddAvatarBookmarkDialog() const;    Q_INVOKABLE void loadAvatarBrowser() const;     void showLoginScreen();    static void showHelp();     void updateSystemTabletMode();     void captureMouseChanged(bool captureMouse);    void toggleOverlays();    void setOverlaysVisible(bool visible);    Q_INVOKABLE void centerUI() { _overlayConductor.centerUI(); }     void addAssetToWorldMessageClose();     void loadLODToolsDialog();    void loadEntityStatisticsDialog();    void loadDomainConnectionDialog();    void showScriptLogs();     const QString getPreferredCursor() const { return _preferredCursor.get(); }    void setPreferredCursor(const QString& cursor);     bool getDarkThemePreference() const { return _darkTheme.get(); }    void setDarkThemePreference(bool value);     bool getMenuBarVisible() const { return _menuBarVisible.get(); }    void setMenuBarVisible(bool visible);     /**     * @brief Shows/hides VR keyboard input for Overlay windows     *     * This is used by QML scripts to show and hide VR keyboard. Unlike JS API Keyboard.raised = true,     * with showVRKeyboardForHudUI the input is passed to the active window on the overlay first.     *     * @param show     * If set to true, then keyboard is shown, for false it's hidden.     */    Q_INVOKABLE void showVRKeyboardForHudUI(bool show);      // Plugins    void resetSensors(bool andReload = false);      // Entities    QVector<EntityItemID> pasteEntities(const QString& entityHostType, float x, float y, float z);    bool exportEntities(const QString& filename, const QVector<QUuid>& entityIDs, const glm::vec3* givenOffset = nullptr, const QVariantMap& options = QVariantMap());    bool exportEntities(const QString& filename, float x, float y, float z, float scale, const QVariantMap& options = QVariantMap());    bool importEntities(const QString& url, const bool isObservable = true, const qint64 callerId = -1);     void setKeyboardFocusHighlight(const glm::vec3& position, const glm::quat& rotation, const glm::vec3& dimensions);

Lines 1–500 of 964.