Showing the changes to interface/src/Application.cpp (1 of 112 files). Show all
Unified · Split
| @@ -105,6 +105,7 @@ · 104 unmodified lines | |||
| 105 | #include <RenderableWebEntityItem.h> | 105 | #include <RenderableWebEntityItem.h> |
| 106 | 106 | ||
| 107 | #include "AudioClient.h" | 107 | #include "AudioClient.h" |
| 108 | #include "CrashHandler.h" | ||
| 108 | #include "DiscoverabilityManager.h" | 109 | #include "DiscoverabilityManager.h" |
| 109 | #include "GLCanvas.h" | 110 | #include "GLCanvas.h" |
| 110 | #include "LODManager.h" | 111 | #include "LODManager.h" |
| @@ -190,6 +191,11 @@ static QTimer* billboardPacketTimer = NULL; · 79 unmodified lines | |||
| 190 | static QTimer* checkFPStimer = NULL; | 191 | static QTimer* checkFPStimer = NULL; |
| 191 | static QTimer* idleTimer = NULL; | 192 | static QTimer* idleTimer = NULL; |
| 192 | 193 | ||
| 194 | static const unsigned int TARGET_SIM_FRAMERATE = 60; | ||
| 195 | static const unsigned int THROTTLED_SIM_FRAMERATE = 15; | ||
| 196 | static const int TARGET_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / TARGET_SIM_FRAMERATE; | ||
| 197 | static const int THROTTLED_SIM_FRAME_PERIOD_MS = MSECS_PER_SECOND / THROTTLED_SIM_FRAMERATE; | ||
| 198 | |||
| 193 | const QString CHECK_VERSION_URL = "https://highfidelity.com/latestVersion.xml"; | 199 | const QString CHECK_VERSION_URL = "https://highfidelity.com/latestVersion.xml"; |
| 194 | const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/hifi.skipversion"; | 200 | const QString SKIP_FILENAME = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/hifi.skipversion"; |
| 195 | 201 | ||
| @@ -258,6 +264,12 @@ bool setupEssentials(int& argc, char** argv) { · 62 unmodified lines | |||
| 258 | // Set build version | 264 | // Set build version |
| 259 | QCoreApplication::setApplicationVersion(BUILD_VERSION); | 265 | QCoreApplication::setApplicationVersion(BUILD_VERSION); |
| 260 | 266 | ||
| 267 | Setting::preInit(); | ||
| 268 | |||
| 269 | CrashHandler::checkForAndHandleCrash(); | ||
| 270 | CrashHandler::writeRunningMarkerFiler(); | ||
| 271 | qAddPostRoutine(CrashHandler::deleteRunningMarkerFile); | ||
| 272 | |||
| 261 | DependencyManager::registerInheritance<LimitedNodeList, NodeList>(); | 273 | DependencyManager::registerInheritance<LimitedNodeList, NodeList>(); |
| 262 | DependencyManager::registerInheritance<AvatarHashMap, AvatarManager>(); | 274 | DependencyManager::registerInheritance<AvatarHashMap, AvatarManager>(); |
| 263 | DependencyManager::registerInheritance<EntityActionFactoryInterface, InterfaceActionFactory>(); | 275 | DependencyManager::registerInheritance<EntityActionFactoryInterface, InterfaceActionFactory>(); |
| @@ -349,7 +361,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 85 unmodified lines | |||
| 349 | _trayIcon(new QSystemTrayIcon(_window)), | 361 | _trayIcon(new QSystemTrayIcon(_window)), |
| 350 | _lastNackTime(usecTimestampNow()), | 362 | _lastNackTime(usecTimestampNow()), |
| 351 | _lastSendDownstreamAudioStats(usecTimestampNow()), | 363 | _lastSendDownstreamAudioStats(usecTimestampNow()), |
| 352 | _isVSyncOn(true), | ||
| 353 | _isThrottleFPSEnabled(true), | 364 | _isThrottleFPSEnabled(true), |
| 354 | _aboutToQuit(false), | 365 | _aboutToQuit(false), |
| 355 | _notifiedPacketVersionMismatchThisDomain(false), | 366 | _notifiedPacketVersionMismatchThisDomain(false), |
| @@ -757,8 +768,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) : · 401 unmodified lines | |||
| 757 | }); | 768 | }); |
| 758 | 769 | ||
| 759 | connect(this, &Application::applicationStateChanged, this, &Application::activeChanged); | 770 | connect(this, &Application::applicationStateChanged, this, &Application::activeChanged); |
| 760 | |||
| 761 | setVSyncEnabled(); // make sure VSync is set properly at startup | ||
| 762 | } | 771 | } |
| 763 | 772 | ||
| 764 | void Application::aboutToQuit() { | 773 | void Application::aboutToQuit() { |
| @@ -932,7 +941,7 @@ void Application::initializeGL() { · 167 unmodified lines | |||
| 932 | // call our idle function whenever we can | 941 | // call our idle function whenever we can |
| 933 | idleTimer = new QTimer(this); | 942 | idleTimer = new QTimer(this); |
| 934 | connect(idleTimer, SIGNAL(timeout()), SLOT(idle())); | 943 | connect(idleTimer, SIGNAL(timeout()), SLOT(idle())); |
| 935 | idleTimer->start(0); | 944 | idleTimer->start(TARGET_SIM_FRAME_PERIOD_MS); |
| 936 | _idleLoopStdev.reset(); | 945 | _idleLoopStdev.reset(); |
| 937 | 946 | ||
| 938 | if (_justStarted) { | 947 | if (_justStarted) { |
| @@ -1439,7 +1448,6 @@ void Application::keyPressEvent(QKeyEvent* event) { · 500 unmodified lines | |||
| 1439 | bool isMeta = event->modifiers().testFlag(Qt::ControlModifier); | 1448 | bool isMeta = event->modifiers().testFlag(Qt::ControlModifier); |
| 1440 | bool isOption = event->modifiers().testFlag(Qt::AltModifier); | 1449 | bool isOption = event->modifiers().testFlag(Qt::AltModifier); |
| 1441 | switch (event->key()) { | 1450 | switch (event->key()) { |
| 1442 | break; | ||
| 1443 | case Qt::Key_Enter: | 1451 | case Qt::Key_Enter: |
| 1444 | case Qt::Key_Return: | 1452 | case Qt::Key_Return: |
| 1445 | if (isOption) { | 1453 | if (isOption) { |
| @@ -2047,38 +2055,38 @@ void Application::checkFPS() { · 601 unmodified lines | |||
| 2047 | } | 2055 | } |
| 2048 | 2056 | ||
| 2049 | void Application::idle() { | 2057 | void Application::idle() { |
| 2050 | PROFILE_RANGE(__FUNCTION__); | 2058 | if (_aboutToQuit) { |
| 2051 | static SimpleAverage<float> interIdleDurations; | 2059 | return; // bail early, nothing to do here. |
| 2060 | } | ||
| 2052 | 2061 | ||
| 2053 | static uint64_t lastIdleStart{ 0 }; | 2062 | // depending on whether we're throttling or not. |
| 2054 | static uint64_t lastIdleEnd{ 0 }; | 2063 | // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in |
| 2055 | uint64_t now = usecTimestampNow(); | 2064 | // perpetuity and not expect events to get backed up. |
| 2056 | uint64_t idleStartToStartDuration = now - lastIdleStart; | 2065 | bool isThrottled = getActiveDisplayPlugin()->isThrottled(); |
| 2066 | // Only run simulation code if more than the targetFramePeriod have passed since last time we ran | ||
| 2067 | // This attempts to lock the simulation at 60 updates per second, regardless of framerate | ||
| 2068 | float timeSinceLastUpdateUs = (float)_lastTimeUpdated.nsecsElapsed() / NSECS_PER_USEC; | ||
| 2069 | float secondsSinceLastUpdate = timeSinceLastUpdateUs / USECS_PER_SECOND; | ||
| 2057 | 2070 | ||
| 2058 | if (lastIdleStart > 0 && idleStartToStartDuration > 0) { | 2071 | if (isThrottled && (timeSinceLastUpdateUs / USECS_PER_MSEC) < THROTTLED_SIM_FRAME_PERIOD_MS) { |
| 2059 | _simsPerSecond.updateAverage((float)USECS_PER_SECOND / (float)idleStartToStartDuration); | 2072 | return; // bail early, we're throttled and not enough time has elapsed |
| 2060 | } | 2073 | } |
| 2061 | 2074 | ||
| 2062 | lastIdleStart = now; | 2075 | _lastTimeUpdated.start(); |
| 2063 | 2076 | ||
| 2064 | if (lastIdleEnd != 0) { | 2077 | |
| 2065 | interIdleDurations.update(now - lastIdleEnd); | 2078 | { |
| 2066 | static uint64_t lastReportTime = now; | 2079 | PROFILE_RANGE(__FUNCTION__); |
| 2067 | if ((now - lastReportTime) >= (USECS_PER_SECOND)) { | 2080 | uint64_t now = usecTimestampNow(); |
| 2068 | static QString LOGLINE("Average inter-idle time: %1 us for %2 samples"); | 2081 | static uint64_t lastIdleStart{ now }; |
| 2069 | if (Menu::getInstance()->isOptionChecked(MenuOption::LogExtraTimings)) { | 2082 | uint64_t idleStartToStartDuration = now - lastIdleStart; |
| 2070 | qCDebug(interfaceapp_timing) << LOGLINE.arg((int)interIdleDurations.getAverage()).arg(interIdleDurations.getCount()); | 2083 | if (idleStartToStartDuration != 0) { |
| 2071 | } | 2084 | _simsPerSecond.updateAverage((float)USECS_PER_SECOND / (float)idleStartToStartDuration); |
| 2072 | interIdleDurations.reset(); | ||
| 2073 | lastReportTime = now; | ||
| 2074 | } | 2085 | } |
| 2086 | lastIdleStart = now; | ||
| 2075 | } | 2087 | } |
| 2076 | 2088 | ||
| 2077 | PerformanceTimer perfTimer("idle"); | 2089 | PerformanceTimer perfTimer("idle"); |
| 2078 | if (_aboutToQuit) { | ||
| 2079 | return; // bail early, nothing to do here. | ||
| 2080 | } | ||
| 2081 | |||
| 2082 | // Drop focus from _keyboardFocusedItem if no keyboard messages for 30 seconds | 2090 | // Drop focus from _keyboardFocusedItem if no keyboard messages for 30 seconds |
| 2083 | if (!_keyboardFocusedItem.isInvalidID()) { | 2091 | if (!_keyboardFocusedItem.isInvalidID()) { |
| 2084 | const quint64 LOSE_FOCUS_AFTER_ELAPSED_TIME = 30 * USECS_PER_SECOND; // if idle for 30 seconds, drop focus | 2092 | const quint64 LOSE_FOCUS_AFTER_ELAPSED_TIME = 30 * USECS_PER_SECOND; // if idle for 30 seconds, drop focus |
| @@ -2094,69 +2102,42 @@ void Application::idle() { · 9 unmodified lines | |||
| 2094 | bool showWarnings = getLogger()->extraDebugging(); | 2102 | bool showWarnings = getLogger()->extraDebugging(); |
| 2095 | PerformanceWarning warn(showWarnings, "idle()"); | 2103 | PerformanceWarning warn(showWarnings, "idle()"); |
| 2096 | 2104 | ||
| 2097 | // Only run simulation code if more than the targetFramePeriod have passed since last time we ran | 2105 | { |
| 2098 | double targetFramePeriod = 0.0; | 2106 | PerformanceTimer perfTimer("update"); |
| 2099 | unsigned int targetFramerate = getRenderTargetFramerate(); | 2107 | PerformanceWarning warn(showWarnings, "Application::idle()... update()"); |
| 2100 | if (targetFramerate > 0) { | 2108 | static const float BIGGEST_DELTA_TIME_SECS = 0.25f; |
| 2101 | targetFramePeriod = 1000.0 / targetFramerate; | 2109 | update(glm::clamp(secondsSinceLastUpdate, 0.0f, BIGGEST_DELTA_TIME_SECS)); |
| 2102 | } | 2110 | } |
| 2103 | double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0; | 2111 | { |
| 2104 | if (timeSinceLastUpdate > targetFramePeriod) { | 2112 | PerformanceTimer perfTimer("pluginIdle"); |
| 2105 | _lastTimeUpdated.start(); | 2113 | PerformanceWarning warn(showWarnings, "Application::idle()... pluginIdle()"); |
| 2106 | { | 2114 | getActiveDisplayPlugin()->idle(); |
| 2107 | PerformanceTimer perfTimer("update"); | 2115 | auto inputPlugins = PluginManager::getInstance()->getInputPlugins(); |
| 2108 | PerformanceWarning warn(showWarnings, "Application::idle()... update()"); | 2116 | foreach(auto inputPlugin, inputPlugins) { |
| 2109 | const float BIGGEST_DELTA_TIME_SECS = 0.25f; | 2117 | QString name = inputPlugin->getName(); |
| 2110 | PROFILE_RANGE(__FUNCTION__ "/idleUpdate"); | 2118 | QAction* action = Menu::getInstance()->getActionForOption(name); |
| 2111 | update(glm::clamp((float)timeSinceLastUpdate / 1000.0f, 0.0f, BIGGEST_DELTA_TIME_SECS)); | 2119 | if (action && action->isChecked()) { |
| 2112 | } | 2120 | inputPlugin->idle(); |
| 2113 | { | ||
| 2114 | PerformanceTimer perfTimer("updateGL"); | ||
| 2115 | PerformanceWarning warn(showWarnings, "Application::idle()... updateGL()"); | ||
| 2116 | getActiveDisplayPlugin()->idle(); | ||
| 2117 | auto inputPlugins = PluginManager::getInstance()->getInputPlugins(); | ||
| 2118 | foreach(auto inputPlugin, inputPlugins) { | ||
| 2119 | QString name = inputPlugin->getName(); | ||
| 2120 | QAction* action = Menu::getInstance()->getActionForOption(name); | ||
| 2121 | if (action && action->isChecked()) { | ||
| 2122 | inputPlugin->idle(); | ||
| 2123 | } | ||
| 2124 | } | ||
| 2125 | } | ||
| 2126 | { | ||
| 2127 | PerformanceTimer perfTimer("rest"); | ||
| 2128 | PerformanceWarning warn(showWarnings, "Application::idle()... rest of it"); | ||
| 2129 | _idleLoopStdev.addValue(timeSinceLastUpdate); | ||
| 2130 | |||
| 2131 | // Record standard deviation and reset counter if needed | ||
| 2132 | const int STDEV_SAMPLES = 500; | ||
| 2133 | if (_idleLoopStdev.getSamples() > STDEV_SAMPLES) { | ||
| 2134 | _idleLoopMeasuredJitter = _idleLoopStdev.getStDev(); | ||
| 2135 | _idleLoopStdev.reset(); | ||
| 2136 | } | 2121 | } |
| 2137 | } | 2122 | } |
| 2138 | 2123 | } | |
| 2139 | float secondsSinceLastUpdate = (float)timeSinceLastUpdate / 1000.0f; | 2124 | { |
| 2140 | _overlayConductor.update(secondsSinceLastUpdate); | 2125 | PerformanceTimer perfTimer("rest"); |
| 2141 | 2126 | PerformanceWarning warn(showWarnings, "Application::idle()... rest of it"); | |
| 2142 | // depending on whether we're throttling or not. | 2127 | _idleLoopStdev.addValue(secondsSinceLastUpdate); |
| 2143 | // Once rendering is off on another thread we should be able to have Application::idle run at start(0) in | 2128 | |
| 2144 | // perpetuity and not expect events to get backed up. | 2129 | // Record standard deviation and reset counter if needed |
| 2145 | 2130 | const int STDEV_SAMPLES = 500; | |
| 2146 | bool isThrottled = getActiveDisplayPlugin()->isThrottled(); | 2131 | if (_idleLoopStdev.getSamples() > STDEV_SAMPLES) { |
| 2147 | static const int THROTTLED_IDLE_TIMER_DELAY = MSECS_PER_SECOND / 15; | 2132 | _idleLoopMeasuredJitter = _idleLoopStdev.getStDev(); |
| 2148 | static const int IDLE_TIMER_DELAY_MS = 2; | 2133 | _idleLoopStdev.reset(); |
| 2149 | int desiredInterval = isThrottled ? THROTTLED_IDLE_TIMER_DELAY : IDLE_TIMER_DELAY_MS; | ||
| 2150 | //qDebug() << "isThrottled:" << isThrottled << "desiredInterval:" << desiredInterval; | ||
| 2151 | |||
| 2152 | if (idleTimer->interval() != desiredInterval) { | ||
| 2153 | idleTimer->start(desiredInterval); | ||
| 2154 | } | 2134 | } |
| 2155 | } | 2135 | } |
| 2136 | |||
| 2137 | _overlayConductor.update(secondsSinceLastUpdate); | ||
| 2156 | 2138 | ||
| 2157 | // check for any requested background downloads. | 2139 | // check for any requested background downloads. |
| 2158 | emit checkBackgroundDownloads(); | 2140 | emit checkBackgroundDownloads(); |
| 2159 | lastIdleEnd = usecTimestampNow(); | ||
| 2160 | } | 2141 | } |
| 2161 | 2142 | ||
| 2162 | float Application::getAverageSimsPerSecond() { | 2143 | float Application::getAverageSimsPerSecond() { |
| @@ -4497,90 +4478,10 @@ void Application::takeSnapshot() { · 2334 unmodified lines | |||
| 4497 | 4478 | ||
| 4498 | } | 4479 | } |
| 4499 | 4480 | ||
| 4500 | void Application::setVSyncEnabled() { | ||
| 4501 | _glWidget->makeCurrent(); | ||
| 4502 | #if defined(Q_OS_WIN) | ||
| 4503 | bool vsyncOn = Menu::getInstance()->isOptionChecked(MenuOption::RenderTargetFramerateVSyncOn); | ||
| 4504 | if (wglewGetExtension("WGL_EXT_swap_control")) { | ||
| 4505 | wglSwapIntervalEXT(vsyncOn); | ||
| 4506 | int swapInterval = wglGetSwapIntervalEXT(); | ||
| 4507 | qCDebug(interfaceapp, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); | ||
| 4508 | } else { | ||
| 4509 | qCDebug(interfaceapp, "V-Sync is FORCED ON on this system\n"); | ||
| 4510 | } | ||
| 4511 | #elif defined(Q_OS_LINUX) | ||
| 4512 | // TODO: write the poper code for linux | ||
| 4513 | /* | ||
| 4514 | if (glQueryExtension.... ("GLX_EXT_swap_control")) { | ||
| 4515 | glxSwapIntervalEXT(vsyncOn); | ||
| 4516 | int swapInterval = xglGetSwapIntervalEXT(); | ||
| 4517 | _isVSyncOn = swapInterval; | ||
| 4518 | qCDebug(interfaceapp, "V-Sync is %s\n", (swapInterval > 0 ? "ON" : "OFF")); | ||
| 4519 | } else { | ||
| 4520 | qCDebug(interfaceapp, "V-Sync is FORCED ON on this system\n"); | ||
| 4521 | } | ||
| 4522 | */ | ||
| 4523 | #else | ||
| 4524 | qCDebug(interfaceapp, "V-Sync is FORCED ON on this system\n"); | ||
| 4525 | #endif | ||
| 4526 | _offscreenContext->makeCurrent(); | ||
| 4527 | } | ||
| 4528 | |||
| 4529 | void Application::setThrottleFPSEnabled() { | 4481 | void Application::setThrottleFPSEnabled() { |
| 4530 | _isThrottleFPSEnabled = Menu::getInstance()->isOptionChecked(MenuOption::ThrottleFPSIfNotFocus); | 4482 | _isThrottleFPSEnabled = Menu::getInstance()->isOptionChecked(MenuOption::ThrottleFPSIfNotFocus); |
| 4531 | } | 4483 | } |
| 4532 | 4484 | ||
| 4533 | bool Application::isVSyncOn() const { | ||
| 4534 | #if defined(Q_OS_WIN) | ||
| 4535 | if (wglewGetExtension("WGL_EXT_swap_control")) { | ||
| 4536 | int swapInterval = wglGetSwapIntervalEXT(); | ||
| 4537 | return (swapInterval > 0); | ||
| 4538 | } | ||
| 4539 | #elif defined(Q_OS_LINUX) | ||
| 4540 | // TODO: write the poper code for linux | ||
| 4541 | /* | ||
| 4542 | if (glQueryExtension.... ("GLX_EXT_swap_control")) { | ||
| 4543 | int swapInterval = xglGetSwapIntervalEXT(); | ||
| 4544 | return (swapInterval > 0); | ||
| 4545 | } else { | ||
| 4546 | return true; | ||
| 4547 | } | ||
| 4548 | */ | ||
| 4549 | #endif | ||
| 4550 | return true; | ||
| 4551 | } | ||
| 4552 | |||
| 4553 | bool Application::isVSyncEditable() const { | ||
| 4554 | #if defined(Q_OS_WIN) | ||
| 4555 | if (wglewGetExtension("WGL_EXT_swap_control")) { | ||
| 4556 | return true; | ||
| 4557 | } | ||
| 4558 | #elif defined(Q_OS_LINUX) | ||
| 4559 | // TODO: write the poper code for linux | ||
| 4560 | /* | ||
| 4561 | if (glQueryExtension.... ("GLX_EXT_swap_control")) { | ||
| 4562 | return true; | ||
| 4563 | } | ||
| 4564 | */ | ||
| 4565 | #endif | ||
| 4566 | return false; | ||
| 4567 | } | ||
| 4568 | |||
| 4569 | unsigned int Application::getRenderTargetFramerate() const { | ||
| 4570 | if (Menu::getInstance()->isOptionChecked(MenuOption::RenderTargetFramerateUnlimited)) { | ||
| 4571 | return 0; | ||
| 4572 | } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderTargetFramerate60)) { | ||
| 4573 | return 60; | ||
| 4574 | } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderTargetFramerate50)) { | ||
| 4575 | return 50; | ||
| 4576 | } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderTargetFramerate40)) { | ||
| 4577 | return 40; | ||
| 4578 | } else if (Menu::getInstance()->isOptionChecked(MenuOption::RenderTargetFramerate30)) { | ||
| 4579 | return 30; | ||
| 4580 | } | ||
| 4581 | return 0; | ||
| 4582 | } | ||
| 4583 | |||
| 4584 | float Application::getRenderResolutionScale() const { | 4485 | float Application::getRenderResolutionScale() const { |
| 4585 | if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionOne)) { | 4486 | if (Menu::getInstance()->isOptionChecked(MenuOption::RenderResolutionOne)) { |
| 4586 | return 1.0f; | 4487 | return 1.0f; |
| @@ -5162,3 +5063,9 @@ void Application::emulateMouse(Hand* hand, float click, float shift, int index) · 575 unmodified lines | |||
| 5162 | _oldHandLeftClick[index] = false; | 5063 | _oldHandLeftClick[index] = false; |
| 5163 | } | 5064 | } |
| 5164 | } | 5065 | } |
| 5066 | |||
| 5067 | void Application::crashApplication() { | ||
| 5068 | QObject* object = nullptr; | ||
| 5069 | bool value = object->isWindowType(); | ||
| 5070 | qCDebug(interfaceapp) << "Intentionally crashed Interface"; | ||
| 5071 | } | ||