History

Merge branch 'master' of https://github.com/highfidelity/hifi into orange

Sam Gateau committed 9 years ago

Commit 156c20d2 parents ca7e782 baf6318191 files · +5682 −2482Browse files

Showing the changes to interface/src/Application.cpp (1 of 191 files). Show all

Unified · Split

interface/src/Application.cpp+427−192
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525 #include <QtCore/QCommandLineParser>
2626 #include <QtCore/QMimeData>
2727 #include <QtCore/QThreadPool>
28+#include <QtConcurrent/QtConcurrentRun>
2829
2930 #include <QtGui/QScreen>
3031 #include <QtGui/QWindow>
@@ -48,6 +49,7 @@ · 17 unmodified lines
4849
4950 #include <gl/QOpenGLContextWrapper.h>
5051
52+#include <shared/QtHelpers.h>
5153 #include <shared/GlobalAppProperties.h>
5254 #include <StatTracker.h>
5355 #include <Trace.h>
@@ -142,7 +144,6 @@ · 88 unmodified lines
142144 #include "avatar/MyHead.h"
143145 #include "CrashHandler.h"
144146 #include "devices/DdeFaceTracker.h"
145−#include "devices/Leapmotion.h"
146147 #include "DiscoverabilityManager.h"
147148 #include "GLCanvas.h"
148149 #include "InterfaceDynamicFactory.h"
@@ -477,6 +478,12 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { · 328 unmodified lines
477478 static const auto SUPPRESS_SETTINGS_RESET = "--suppress-settings-reset";
478479 bool suppressPrompt = cmdOptionExists(argc, const_cast<const char**>(argv), SUPPRESS_SETTINGS_RESET);
479480 bool previousSessionCrashed = CrashHandler::checkForResetSettings(runningMarkerExisted, suppressPrompt);
481+ // get dir to use for cache
482+ static const auto CACHE_SWITCH = "--cache";
483+ QString cacheDir = getCmdOption(argc, const_cast<const char**>(argv), CACHE_SWITCH);
484+ if (!cacheDir.isEmpty()) {
485+ qApp->setProperty(hifi::properties::APP_LOCAL_DATA_PATH, cacheDir);
486+ }
480487
481488 Setting::init();
482489
@@ -942,58 +949,68 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 459 unmodified lines
942949 // Make sure we don't time out during slow operations at startup
943950 updateHeartbeat();
944951
945−
946− // sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
947− // The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
948− static const QString TESTER = "HIFI_TESTER";
949− auto gpuIdent = GPUIdent::getInstance();
950− auto glContextData = getGLContextData();
951− QJsonObject properties = {
952− { "version", applicationVersion() },
953− { "tester", QProcessEnvironment::systemEnvironment().contains(TESTER) },
954− { "previousSessionCrashed", _previousSessionCrashed },
955− { "previousSessionRuntime", sessionRunTime.get() },
956− { "cpu_architecture", QSysInfo::currentCpuArchitecture() },
957− { "kernel_type", QSysInfo::kernelType() },
958− { "kernel_version", QSysInfo::kernelVersion() },
959− { "os_type", QSysInfo::productType() },
960− { "os_version", QSysInfo::productVersion() },
961− { "gpu_name", gpuIdent->getName() },
962− { "gpu_driver", gpuIdent->getDriver() },
963− { "gpu_memory", static_cast<qint64>(gpuIdent->getMemory()) },
964− { "gl_version_int", glVersionToInteger(glContextData.value("version").toString()) },
965− { "gl_version", glContextData["version"] },
966− { "gl_vender", glContextData["vendor"] },
967− { "gl_sl_version", glContextData["sl_version"] },
968− { "gl_renderer", glContextData["renderer"] },
969− { "ideal_thread_count", QThread::idealThreadCount() }
970− };
971− auto macVersion = QSysInfo::macVersion();
972− if (macVersion != QSysInfo::MV_None) {
973− properties["os_osx_version"] = QSysInfo::macVersion();
974− }
975− auto windowsVersion = QSysInfo::windowsVersion();
976− if (windowsVersion != QSysInfo::WV_None) {
977− properties["os_win_version"] = QSysInfo::windowsVersion();
978− }
979−
980− ProcessorInfo procInfo;
981− if (getProcessorInfo(procInfo)) {
982− properties["processor_core_count"] = procInfo.numProcessorCores;
983− properties["logical_processor_count"] = procInfo.numLogicalProcessors;
984− properties["processor_l1_cache_count"] = procInfo.numProcessorCachesL1;
985− properties["processor_l2_cache_count"] = procInfo.numProcessorCachesL2;
986− properties["processor_l3_cache_count"] = procInfo.numProcessorCachesL3;
987− }
988−
989− // add firstRun flag from settings to launch event
990952 Setting::Handle<bool> firstRun { Settings::firstRun, true };
991− properties["first_run"] = firstRun.get();
992953
993− // add the user's machine ID to the launch event
994− properties["machine_fingerprint"] = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint());
995−
996− UserActivityLogger::getInstance().logAction("launch", properties);
954+ // once the settings have been loaded, check if we need to flip the default for UserActivityLogger
955+ auto& userActivityLogger = UserActivityLogger::getInstance();
956+ if (!userActivityLogger.isDisabledSettingSet()) {
957+ // the user activity logger is opt-out for Interface
958+ // but it's defaulted to disabled for other targets
959+ // so we need to enable it here if it has never been disabled by the user
960+ userActivityLogger.disable(false);
961+ }
962+
963+ if (userActivityLogger.isEnabled()) {
964+ // sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
965+ // The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
966+ static const QString TESTER = "HIFI_TESTER";
967+ auto gpuIdent = GPUIdent::getInstance();
968+ auto glContextData = getGLContextData();
969+ QJsonObject properties = {
970+ { "version", applicationVersion() },
971+ { "tester", QProcessEnvironment::systemEnvironment().contains(TESTER) },
972+ { "previousSessionCrashed", _previousSessionCrashed },
973+ { "previousSessionRuntime", sessionRunTime.get() },
974+ { "cpu_architecture", QSysInfo::currentCpuArchitecture() },
975+ { "kernel_type", QSysInfo::kernelType() },
976+ { "kernel_version", QSysInfo::kernelVersion() },
977+ { "os_type", QSysInfo::productType() },
978+ { "os_version", QSysInfo::productVersion() },
979+ { "gpu_name", gpuIdent->getName() },
980+ { "gpu_driver", gpuIdent->getDriver() },
981+ { "gpu_memory", static_cast<qint64>(gpuIdent->getMemory()) },
982+ { "gl_version_int", glVersionToInteger(glContextData.value("version").toString()) },
983+ { "gl_version", glContextData["version"] },
984+ { "gl_vender", glContextData["vendor"] },
985+ { "gl_sl_version", glContextData["sl_version"] },
986+ { "gl_renderer", glContextData["renderer"] },
987+ { "ideal_thread_count", QThread::idealThreadCount() }
988+ };
989+ auto macVersion = QSysInfo::macVersion();
990+ if (macVersion != QSysInfo::MV_None) {
991+ properties["os_osx_version"] = QSysInfo::macVersion();
992+ }
993+ auto windowsVersion = QSysInfo::windowsVersion();
994+ if (windowsVersion != QSysInfo::WV_None) {
995+ properties["os_win_version"] = QSysInfo::windowsVersion();
996+ }
997+
998+ ProcessorInfo procInfo;
999+ if (getProcessorInfo(procInfo)) {
1000+ properties["processor_core_count"] = procInfo.numProcessorCores;
1001+ properties["logical_processor_count"] = procInfo.numLogicalProcessors;
1002+ properties["processor_l1_cache_count"] = procInfo.numProcessorCachesL1;
1003+ properties["processor_l2_cache_count"] = procInfo.numProcessorCachesL2;
1004+ properties["processor_l3_cache_count"] = procInfo.numProcessorCachesL3;
1005+ }
1006+
1007+ properties["first_run"] = firstRun.get();
1008+
1009+ // add the user's machine ID to the launch event
1010+ properties["machine_fingerprint"] = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint());
1011+
1012+ userActivityLogger.logAction("launch", properties);
1013+ }
9971014
9981015 // Tell our entity edit sender about our known jurisdictions
9991016 _entityEditSender.setServerJurisdictions(&_entityServerJurisdictions);
@@ -1205,15 +1222,26 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo · 205 unmodified lines
12051222 // Make sure we don't time out during slow operations at startup
12061223 updateHeartbeat();
12071224
1208− int SAVE_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND; // Let's save every seconds for now
1209− connect(&_settingsTimer, &QTimer::timeout, this, &Application::saveSettings);
1210− connect(&_settingsThread, SIGNAL(started()), &_settingsTimer, SLOT(start()));
1211− connect(&_settingsThread, SIGNAL(finished()), &_settingsTimer, SLOT(stop()));
1212− _settingsTimer.moveToThread(&_settingsThread);
1213− _settingsTimer.setSingleShot(false);
1214− _settingsTimer.setInterval(SAVE_SETTINGS_INTERVAL); // 10s, Qt::CoarseTimer acceptable
1215− _settingsThread.setPriority(QThread::LowestPriority);
1216− _settingsThread.start();
1225+
1226+ QTimer* settingsTimer = new QTimer();
1227+ moveToNewNamedThread(settingsTimer, "Settings Thread", [this, settingsTimer]{
1228+ connect(qApp, &Application::beforeAboutToQuit, [this, settingsTimer]{
1229+ // Disconnect the signal from the save settings
1230+ QObject::disconnect(settingsTimer, &QTimer::timeout, this, &Application::saveSettings);
1231+ // Stop the settings timer
1232+ settingsTimer->stop();
1233+ // Delete it (this will trigger the thread destruction
1234+ settingsTimer->deleteLater();
1235+ // Mark the settings thread as finished, so we know we can safely save in the main application
1236+ // shutdown code
1237+ _settingsGuard.trigger();
1238+ });
1239+
1240+ int SAVE_SETTINGS_INTERVAL = 10 * MSECS_PER_SECOND; // Let's save every seconds for now
1241+ settingsTimer->setSingleShot(false);
1242+ settingsTimer->setInterval(SAVE_SETTINGS_INTERVAL); // 10s, Qt::CoarseTimer acceptable
1243+ QObject::connect(settingsTimer, &QTimer::timeout, this, &Application::saveSettings);
1244+ }, QThread::LowestPriority);
12171245
12181246 if (Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson)) {
12191247 getMyAvatar()->setBoomLength(MyAvatar::ZOOM_MIN); // So that camera doesn't auto-switch to third person.
@@ -1641,7 +1669,7 @@ QString Application::getUserAgent() { · 421 unmodified lines
16411669 if (QThread::currentThread() != thread()) {
16421670 QString userAgent;
16431671
1644− QMetaObject::invokeMethod(this, "getUserAgent", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, userAgent));
1672+ BLOCKING_INVOKE_METHOD(this, "getUserAgent", Q_RETURN_ARG(QString, userAgent));
16451673
16461674 return userAgent;
16471675 }
@@ -1799,11 +1827,13 @@ void Application::cleanupBeforeQuit() { · 151 unmodified lines
17991827 locationUpdateTimer.stop();
18001828 identityPacketTimer.stop();
18011829 pingTimer.stop();
1802− QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection);
18031830
1804− // save state
1805− _settingsThread.quit();
1806− saveSettings();
1831+ // Wait for the settings thread to shut down, and save the settings one last time when it's safe
1832+ if (_settingsGuard.wait()) {
1833+ // save state
1834+ saveSettings();
1835+ }
1836+
18071837 _window->saveGeometry();
18081838
18091839 // Destroy third party processes after scripts have finished using them.
@@ -1827,8 +1857,7 @@ void Application::cleanupBeforeQuit() { · 17 unmodified lines
18271857
18281858 // FIXME: something else is holding a reference to AudioClient,
18291859 // so it must be explicitly synchronously stopped here
1830− QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(),
1831− "cleanupBeforeQuit", Qt::BlockingQueuedConnection);
1860+ DependencyManager::get<AudioClient>()->cleanupBeforeQuit();
18321861
18331862 // destroy Audio so it and its threads have a chance to go down safely
18341863 // this must happen after QML, as there are unexplained audio crashes originating in qtwebengine
@@ -1883,8 +1912,6 @@ Application::~Application() { · 48 unmodified lines
18831912 // remove the NodeList from the DependencyManager
18841913 DependencyManager::destroy<NodeList>();
18851914
1886− Leapmotion::destroy();
1887−
18881915 if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
18891916 steamClient->shutdown();
18901917 }
@@ -2152,48 +2179,74 @@ void Application::paintGL() { · 261 unmodified lines
21522179 return;
21532180 }
21542181
2155− auto displayPlugin = getActiveDisplayPlugin();
2156− // FIXME not needed anymore?
2157− _offscreenContext->makeCurrent();
2182+ DisplayPluginPointer displayPlugin;
2183+ {
2184+ PROFILE_RANGE(render, "/getActiveDisplayPlugin");
2185+ displayPlugin = getActiveDisplayPlugin();
2186+ }
21582187
2159− // If a display plugin loses it's underlying support, it
2160− // needs to be able to signal us to not use it
2161− if (!displayPlugin->beginFrameRender(_frameCount)) {
2162− _inPaint = false;
2163− updateDisplayMode();
2164− return;
2188+ {
2189+ PROFILE_RANGE(render, "/offscreenMakeCurrent");
2190+ // FIXME not needed anymore?
2191+ _offscreenContext->makeCurrent();
2192+ }
2193+
2194+ {
2195+ PROFILE_RANGE(render, "/pluginBeginFrameRender");
2196+ // If a display plugin loses it's underlying support, it
2197+ // needs to be able to signal us to not use it
2198+ if (!displayPlugin->beginFrameRender(_frameCount)) {
2199+ _inPaint = false;
2200+ updateDisplayMode();
2201+ return;
2202+ }
21652203 }
21662204
21672205 // update the avatar with a fresh HMD pose
2168− getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose());
2206+ {
2207+ PROFILE_RANGE(render, "/updateAvatar");
2208+ getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose());
2209+ }
21692210
21702211 auto lodManager = DependencyManager::get<LODManager>();
21712212
2213+ RenderArgs renderArgs;
21722214 {
2173− QMutexLocker viewLocker(&_viewMutex);
2174− _viewFrustum.calculate();
2215+ PROFILE_RANGE(render, "/buildFrustrumAndArgs");
2216+ {
2217+ QMutexLocker viewLocker(&_viewMutex);
2218+ _viewFrustum.calculate();
2219+ }
2220+ renderArgs = RenderArgs(_gpuContext, getEntities(), lodManager->getOctreeSizeScale(),
2221+ lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
2222+ RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
2223+ {
2224+ QMutexLocker viewLocker(&_viewMutex);
2225+ renderArgs.setViewFrustum(_viewFrustum);
2226+ }
21752227 }
2176− RenderArgs renderArgs(_gpuContext, getEntities(), lodManager->getOctreeSizeScale(),
2177− lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE,
2178− RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE);
2228+
21792229 {
2180− QMutexLocker viewLocker(&_viewMutex);
2181− renderArgs.setViewFrustum(_viewFrustum);
2230+ PROFILE_RANGE(render, "/resizeGL");
2231+ PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
2232+ bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
2233+ PerformanceWarning warn(showWarnings, "Application::paintGL()");
2234+ resizeGL();
21822235 }
21832236
2184− PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings));
2185− bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
2186− PerformanceWarning warn(showWarnings, "Application::paintGL()");
2187− resizeGL();
2237+ {
2238+ PROFILE_RANGE(render, "/gpuContextReset");
2239+ _gpuContext->beginFrame(getHMDSensorPose());
2240+ // Reset the gpu::Context Stages
2241+ // Back to the default framebuffer;
2242+ gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) {
2243+ batch.resetStages();
2244+ });
2245+ }
21882246
2189− _gpuContext->beginFrame(getHMDSensorPose());
2190− // Reset the gpu::Context Stages
2191− // Back to the default framebuffer;
2192− gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) {
2193− batch.resetStages();
2194− });
21952247
21962248 {
2249+ PROFILE_RANGE(render, "/renderOverlay");
21972250 PerformanceTimer perfTimer("renderOverlay");
21982251 // NOTE: There is no batch associated with this renderArgs
21992252 // the ApplicationOverlay class assumes it's viewport is setup to be the device size
@@ -2204,114 +2257,127 @@ void Application::paintGL() { · 4 unmodified lines
22042257
22052258 glm::vec3 boomOffset;
22062259 {
2207− PerformanceTimer perfTimer("CameraUpdates");
2260+ PROFILE_RANGE(render, "/updateCamera");
2261+ {
2262+ PerformanceTimer perfTimer("CameraUpdates");
22082263
2209− auto myAvatar = getMyAvatar();
2210− boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD;
2264+ auto myAvatar = getMyAvatar();
2265+ boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD;
22112266
2212− if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
2213− Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
2214− Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
2215− cameraMenuChanged();
2216− }
2267+ if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON || _myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
2268+ Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN);
2269+ Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, !(myAvatar->getBoomLength() <= MyAvatar::ZOOM_MIN));
2270+ cameraMenuChanged();
2271+ }
22172272
2218− // The render mode is default or mirror if the camera is in mirror mode, assigned further below
2219− renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
2273+ // The render mode is default or mirror if the camera is in mirror mode, assigned further below
2274+ renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE;
22202275
2221− // Always use the default eye position, not the actual head eye position.
2222− // Using the latter will cause the camera to wobble with idle animations,
2223− // or with changes from the face tracker
2224− if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
2225− if (isHMDMode()) {
2226− mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
2227− _myCamera.setPosition(extractTranslation(camMat));
2228− _myCamera.setOrientation(glm::quat_cast(camMat));
2229− } else {
2230− _myCamera.setPosition(myAvatar->getDefaultEyePosition());
2231− _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation());
2232− }
2233− } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
2234− if (isHMDMode()) {
2235− auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
2236− _myCamera.setOrientation(glm::normalize(glm::quat_cast(hmdWorldMat)));
2237− _myCamera.setPosition(extractTranslation(hmdWorldMat) +
2238− myAvatar->getOrientation() * boomOffset);
2239− } else {
2240− _myCamera.setOrientation(myAvatar->getHead()->getOrientation());
2241− if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) {
2242− _myCamera.setPosition(myAvatar->getDefaultEyePosition()
2243− + _myCamera.getOrientation() * boomOffset);
2276+ // Always use the default eye position, not the actual head eye position.
2277+ // Using the latter will cause the camera to wobble with idle animations,
2278+ // or with changes from the face tracker
2279+ if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) {
2280+ if (isHMDMode()) {
2281+ mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
2282+ _myCamera.setPosition(extractTranslation(camMat));
2283+ _myCamera.setOrientation(glm::quat_cast(camMat));
22442284 } else {
2245− _myCamera.setPosition(myAvatar->getDefaultEyePosition()
2246− + myAvatar->getOrientation() * boomOffset);
2285+ _myCamera.setPosition(myAvatar->getDefaultEyePosition());
2286+ _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation());
22472287 }
2248− }
2249− } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
2250− if (isHMDMode()) {
2251− auto mirrorBodyOrientation = myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f));
2252−
2253− glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
2254− // Mirror HMD yaw and roll
2255− glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation);
2256− mirrorHmdEulers.y = -mirrorHmdEulers.y;
2257− mirrorHmdEulers.z = -mirrorHmdEulers.z;
2258− glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers);
2288+ } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) {
2289+ if (isHMDMode()) {
2290+ auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix();
2291+ _myCamera.setOrientation(glm::normalize(glm::quat_cast(hmdWorldMat)));
2292+ _myCamera.setPosition(extractTranslation(hmdWorldMat) +
2293+ myAvatar->getOrientation() * boomOffset);
2294+ } else {
2295+ _myCamera.setOrientation(myAvatar->getHead()->getOrientation());
2296+ if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) {
2297+ _myCamera.setPosition(myAvatar->getDefaultEyePosition()
2298+ + _myCamera.getOrientation() * boomOffset);
2299+ } else {
2300+ _myCamera.setPosition(myAvatar->getDefaultEyePosition()
2301+ + myAvatar->getOrientation() * boomOffset);
2302+ }
2303+ }
2304+ } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) {
2305+ if (isHMDMode()) {
2306+ auto mirrorBodyOrientation = myAvatar->getWorldAlignedOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f));
22592307
2260− glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation;
2308+ glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
2309+ // Mirror HMD yaw and roll
2310+ glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation);
2311+ mirrorHmdEulers.y = -mirrorHmdEulers.y;
2312+ mirrorHmdEulers.z = -mirrorHmdEulers.z;
2313+ glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers);
22612314
2262− _myCamera.setOrientation(worldMirrorRotation);
2315+ glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation;
22632316
2264− glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
2265− // Mirror HMD lateral offsets
2266− hmdOffset.x = -hmdOffset.x;
2317+ _myCamera.setOrientation(worldMirrorRotation);
22672318
2268− _myCamera.setPosition(myAvatar->getDefaultEyePosition()
2269− + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
2270− + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
2271− + mirrorBodyOrientation * hmdOffset);
2272− } else {
2273− _myCamera.setOrientation(myAvatar->getWorldAlignedOrientation()
2274− * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
2275− _myCamera.setPosition(myAvatar->getDefaultEyePosition()
2276− + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
2277− + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
2278− glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
2279− }
2280− renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
2281− } else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) {
2282− EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer();
2283− if (cameraEntity != nullptr) {
2284− if (isHMDMode()) {
2285− glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
2286− _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation);
22872319 glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
2288− _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset));
2320+ // Mirror HMD lateral offsets
2321+ hmdOffset.x = -hmdOffset.x;
2322+
2323+ _myCamera.setPosition(myAvatar->getDefaultEyePosition()
2324+ + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
2325+ + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror
2326+ + mirrorBodyOrientation * hmdOffset);
22892327 } else {
2290− _myCamera.setOrientation(cameraEntity->getRotation());
2291− _myCamera.setPosition(cameraEntity->getPosition());
2328+ _myCamera.setOrientation(myAvatar->getWorldAlignedOrientation()
2329+ * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)));
2330+ _myCamera.setPosition(myAvatar->getDefaultEyePosition()
2331+ + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0)
2332+ + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) *
2333+ glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror);
2334+ }
2335+ renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
2336+ } else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) {
2337+ EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer();
2338+ if (cameraEntity != nullptr) {
2339+ if (isHMDMode()) {
2340+ glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix());
2341+ _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation);
2342+ glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix());
2343+ _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset));
2344+ } else {
2345+ _myCamera.setOrientation(cameraEntity->getRotation());
2346+ _myCamera.setPosition(cameraEntity->getPosition());
2347+ }
22922348 }
22932349 }
2294− }
2295− // Update camera position
2296− if (!isHMDMode()) {
2297− _myCamera.update(1.0f / _frameCounter.rate());
2350+ // Update camera position
2351+ if (!isHMDMode()) {
2352+ _myCamera.update(1.0f / _frameCounter.rate());
2353+ }
22982354 }
22992355 }
23002356
2301− getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform());
2357+ {
2358+ PROFILE_RANGE(render, "/updateCompositor");
2359+ getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform());
2360+ }
23022361
2303− // Primary rendering pass
2304− auto framebufferCache = DependencyManager::get<FramebufferCache>();
2305− const QSize size = framebufferCache->getFrameBufferSize();
2306− // Final framebuffer that will be handled to the display-plugin
2307− auto finalFramebuffer = framebufferCache->getFramebuffer();
2362+ gpu::FramebufferPointer finalFramebuffer;
2363+ QSize finalFramebufferSize;
2364+ {
2365+ PROFILE_RANGE(render, "/getOutputFramebuffer");
2366+ // Primary rendering pass
2367+ auto framebufferCache = DependencyManager::get<FramebufferCache>();
2368+ finalFramebufferSize = framebufferCache->getFrameBufferSize();
2369+ // Final framebuffer that will be handled to the display-plugin
2370+ finalFramebuffer = framebufferCache->getFramebuffer();
2371+ }
23082372
23092373 {
23102374 PROFILE_RANGE(render, "/mainRender");
23112375 PerformanceTimer perfTimer("mainRender");
23122376 renderArgs._boomOffset = boomOffset;
2377+ // FIXME is this ever going to be different from the size previously set in the render args
2378+ // in the overlay render?
23132379 // Viewport is assigned to the size of the framebuffer
2314− renderArgs._viewport = ivec4(0, 0, size.width(), size.height());
2380+ renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height());
23152381 if (displayPlugin->isStereo()) {
23162382 // Stereo modes will typically have a larger projection matrix overall,
23172383 // so we ask for the 'mono' projection matrix, which for stereo and HMD
@@ -3611,6 +3677,133 @@ bool Application::shouldPaint(float nsecsElapsed) { · 1293 unmodified lines
36113677 #include <TCHAR.h>
36123678 #include <pdh.h>
36133679 #pragma comment(lib, "pdh.lib")
3680+#pragma comment(lib, "ntdll.lib")
3681+
3682+extern "C" {
3683+ enum SYSTEM_INFORMATION_CLASS {
3684+ SystemBasicInformation = 0,
3685+ SystemProcessorPerformanceInformation = 8,
3686+ };
3687+
3688+ struct SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
3689+ LARGE_INTEGER IdleTime;
3690+ LARGE_INTEGER KernelTime;
3691+ LARGE_INTEGER UserTime;
3692+ LARGE_INTEGER DpcTime;
3693+ LARGE_INTEGER InterruptTime;
3694+ ULONG InterruptCount;
3695+ };
3696+
3697+ struct SYSTEM_BASIC_INFORMATION {
3698+ ULONG Reserved;
3699+ ULONG TimerResolution;
3700+ ULONG PageSize;
3701+ ULONG NumberOfPhysicalPages;
3702+ ULONG LowestPhysicalPageNumber;
3703+ ULONG HighestPhysicalPageNumber;
3704+ ULONG AllocationGranularity;
3705+ ULONG_PTR MinimumUserModeAddress;
3706+ ULONG_PTR MaximumUserModeAddress;
3707+ ULONG_PTR ActiveProcessorsAffinityMask;
3708+ CCHAR NumberOfProcessors;
3709+ };
3710+
3711+ NTSYSCALLAPI NTSTATUS NTAPI NtQuerySystemInformation(
3712+ _In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
3713+ _Out_writes_bytes_opt_(SystemInformationLength) PVOID SystemInformation,
3714+ _In_ ULONG SystemInformationLength,
3715+ _Out_opt_ PULONG ReturnLength
3716+ );
3717+
3718+}
3719+template <typename T>
3720+NTSTATUS NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, T& t) {
3721+ return NtQuerySystemInformation(SystemInformationClass, &t, (ULONG)sizeof(T), nullptr);
3722+}
3723+
3724+template <typename T>
3725+NTSTATUS NtQuerySystemInformation(SYSTEM_INFORMATION_CLASS SystemInformationClass, std::vector<T>& t) {
3726+ return NtQuerySystemInformation(SystemInformationClass, t.data(), (ULONG)(sizeof(T) * t.size()), nullptr);
3727+}
3728+
3729+
3730+template <typename T>
3731+void updateValueAndDelta(std::pair<T, T>& pair, T newValue) {
3732+ auto& value = pair.first;
3733+ auto& delta = pair.second;
3734+ delta = (value != 0) ? newValue - value : 0;
3735+ value = newValue;
3736+}
3737+
3738+struct MyCpuInfo {
3739+ using ValueAndDelta = std::pair<LONGLONG, LONGLONG>;
3740+ std::string name;
3741+ ValueAndDelta kernel { 0, 0 };
3742+ ValueAndDelta user { 0, 0 };
3743+ ValueAndDelta idle { 0, 0 };
3744+ float kernelUsage { 0.0f };
3745+ float userUsage { 0.0f };
3746+
3747+ void update(const SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION& cpuInfo) {
3748+ updateValueAndDelta(kernel, cpuInfo.KernelTime.QuadPart);
3749+ updateValueAndDelta(user, cpuInfo.UserTime.QuadPart);
3750+ updateValueAndDelta(idle, cpuInfo.IdleTime.QuadPart);
3751+ auto totalTime = kernel.second + user.second + idle.second;
3752+ if (totalTime != 0) {
3753+ kernelUsage = (FLOAT)kernel.second / totalTime;
3754+ userUsage = (FLOAT)user.second / totalTime;
3755+ } else {
3756+ kernelUsage = userUsage = 0.0f;
3757+ }
3758+ }
3759+};
3760+
3761+void updateCpuInformation() {
3762+ static std::once_flag once;
3763+ static SYSTEM_BASIC_INFORMATION systemInfo {};
3764+ static SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION cpuTotals;
3765+ static std::vector<SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION> cpuInfos;
3766+ static std::vector<MyCpuInfo> myCpuInfos;
3767+ static MyCpuInfo myCpuTotals;
3768+ std::call_once(once, [&] {
3769+ NtQuerySystemInformation( SystemBasicInformation, systemInfo);
3770+ cpuInfos.resize(systemInfo.NumberOfProcessors);
3771+ myCpuInfos.resize(systemInfo.NumberOfProcessors);
3772+ for (size_t i = 0; i < systemInfo.NumberOfProcessors; ++i) {
3773+ myCpuInfos[i].name = "cpu." + std::to_string(i);
3774+ }
3775+ myCpuTotals.name = "cpu.total";
3776+ });
3777+ NtQuerySystemInformation(SystemProcessorPerformanceInformation, cpuInfos);
3778+
3779+ // Zero the CPU totals.
3780+ memset(&cpuTotals, 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
3781+ for (size_t i = 0; i < systemInfo.NumberOfProcessors; ++i) {
3782+ auto& cpuInfo = cpuInfos[i];
3783+ // KernelTime includes IdleTime.
3784+ cpuInfo.KernelTime.QuadPart -= cpuInfo.IdleTime.QuadPart;
3785+
3786+ // Update totals
3787+ cpuTotals.IdleTime.QuadPart += cpuInfo.IdleTime.QuadPart;
3788+ cpuTotals.KernelTime.QuadPart += cpuInfo.KernelTime.QuadPart;
3789+ cpuTotals.UserTime.QuadPart += cpuInfo.UserTime.QuadPart;
3790+
3791+ // Update friendly structure
3792+ auto& myCpuInfo = myCpuInfos[i];
3793+ myCpuInfo.update(cpuInfo);
3794+ PROFILE_COUNTER(app, myCpuInfo.name.c_str(), {
3795+ { "kernel", myCpuInfo.kernelUsage },
3796+ { "user", myCpuInfo.userUsage }
3797+ });
3798+ }
3799+
3800+ myCpuTotals.update(cpuTotals);
3801+ PROFILE_COUNTER(app, myCpuTotals.name.c_str(), {
3802+ { "kernel", myCpuTotals.kernelUsage },
3803+ { "user", myCpuTotals.userUsage }
3804+ });
3805+}
3806+
36143807
36153808 static ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU;
36163809 static int numProcessors;
@@ -3663,6 +3856,26 @@ void getCpuUsage(vec3& systemAndUser) { · 46 unmodified lines
36633856 systemAndUser.z = (float)counterVal.doubleValue;
36643857 }
36653858
3859+void setupCpuMonitorThread() {
3860+ initCpuUsage();
3861+ auto cpuMonitorThread = QThread::currentThread();
3862+
3863+ QTimer* timer = new QTimer();
3864+ timer->setInterval(50);
3865+ QObject::connect(timer, &QTimer::timeout, [] {
3866+ updateCpuInformation();
3867+ vec3 kernelUserAndSystem;
3868+ getCpuUsage(kernelUserAndSystem);
3869+ PROFILE_COUNTER(app, "cpuProcess", { { "system", kernelUserAndSystem.x }, { "user", kernelUserAndSystem.y } });
3870+ PROFILE_COUNTER(app, "cpuSystem", { { "system", kernelUserAndSystem.z } });
3871+ });
3872+ QObject::connect(cpuMonitorThread, &QThread::finished, [=] {
3873+ timer->deleteLater();
3874+ cpuMonitorThread->deleteLater();
3875+ });
3876+ timer->start();
3877+}
3878+
36663879 #endif
36673880
36683881
@@ -3683,15 +3896,17 @@ void Application::idle(float nsecsElapsed) { · 14 unmodified lines
36833896 }
36843897
36853898 #ifdef Q_OS_WIN
3899+ // If tracing is enabled then monitor the CPU in a separate thread
36863900 static std::once_flag once;
3687− std::call_once(once, [] {
3688− initCpuUsage();
3901+ std::call_once(once, [&] {
3902+ if (trace_app().isDebugEnabled()) {
3903+ QThread* cpuMonitorThread = new QThread(qApp);
3904+ cpuMonitorThread->setObjectName("cpuMonitorThread");
3905+ QObject::connect(cpuMonitorThread, &QThread::started, [this] { setupCpuMonitorThread(); });
3906+ QObject::connect(qApp, &QCoreApplication::aboutToQuit, cpuMonitorThread, &QThread::quit);
3907+ cpuMonitorThread->start();
3908+ }
36893909 });
3690−
3691− vec3 kernelUserAndSystem;
3692− getCpuUsage(kernelUserAndSystem);
3693− PROFILE_COUNTER(app, "cpuProcess", { { "system", kernelUserAndSystem.x }, { "user", kernelUserAndSystem.y } });
3694− PROFILE_COUNTER(app, "cpuSystem", { { "system", kernelUserAndSystem.z } });
36953910 #endif
36963911
36973912
@@ -4053,8 +4268,6 @@ void Application::init() { · 355 unmodified lines
40534268
40544269 qCDebug(interfaceapp) << "Loaded settings";
40554270
4056− Leapmotion::init();
4057−
40584271 // fire off an immediate domain-server check in now that settings are loaded
40594272 DependencyManager::get<NodeList>()->sendDomainServerCheckIn();
40604273
@@ -4518,7 +4731,6 @@ void Application::update(float deltaTime) { · 457 unmodified lines
45184731
45194732 {
45204733 PerformanceTimer perfTimer("devices");
4521− DeviceTracker::updateAll();
45224734
45234735 FaceTracker* tracker = getSelectedFaceTracker();
45244736 if (tracker && Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking) != tracker->isMuted()) {
@@ -4587,8 +4799,6 @@ void Application::update(float deltaTime) { · 62 unmodified lines
45874799 keyboardMousePlugin->pluginUpdate(deltaTime, calibrationData);
45884800 }
45894801
4590− _controllerScriptingInterface->updateInputControllers();
4591−
45924802 // Transfer the user inputs to the driveKeys
45934803 // FIXME can we drop drive keys and just have the avatar read the action states directly?
45944804 myAvatar->clearDriveKeys();
@@ -4613,6 +4823,31 @@ void Application::update(float deltaTime) { · 18 unmodified lines
46134823 auto avatarToSensorMatrix = worldToSensorMatrix * myAvatarMatrix;
46144824 myAvatar->setHandControllerPosesInSensorFrame(leftHandPose.transform(avatarToSensorMatrix), rightHandPose.transform(avatarToSensorMatrix));
46154825
4826+ // If have previously done finger poses or there are new valid finger poses, update finger pose values. This so that if
4827+ // fingers are not being controlled, finger joints are not updated in MySkeletonModel.
4828+ // Assumption: Finger poses are either all present and valid or not present at all; thus can test just one joint.
4829+ MyAvatar::FingerPosesMap leftHandFingerPoses;
4830+ if (myAvatar->getLeftHandFingerControllerPosesInSensorFrame().size() > 0
4831+ || userInputMapper->getPoseState(controller::Action::LEFT_HAND_THUMB1).isValid()) {
4832+ for (int i = (int)controller::Action::LEFT_HAND_THUMB1; i <= (int)controller::Action::LEFT_HAND_PINKY4; i++) {
4833+ leftHandFingerPoses[i] = {
4834+ userInputMapper->getPoseState((controller::Action)i).transform(avatarToSensorMatrix),
4835+ userInputMapper->getActionName((controller::Action)i)
4836+ };
4837+ }
4838+ }
4839+ MyAvatar::FingerPosesMap rightHandFingerPoses;
4840+ if (myAvatar->getRightHandFingerControllerPosesInSensorFrame().size() > 0
4841+ || userInputMapper->getPoseState(controller::Action::RIGHT_HAND_THUMB1).isValid()) {
4842+ for (int i = (int)controller::Action::RIGHT_HAND_THUMB1; i <= (int)controller::Action::RIGHT_HAND_PINKY4; i++) {
4843+ rightHandFingerPoses[i] = {
4844+ userInputMapper->getPoseState((controller::Action)i).transform(avatarToSensorMatrix),
4845+ userInputMapper->getActionName((controller::Action)i)
4846+ };
4847+ }
4848+ }
4849+ myAvatar->setFingerControllerPosesInSensorFrame(leftHandFingerPoses, rightHandFingerPoses);
4850+
46164851 controller::Pose leftFootPose = userInputMapper->getPoseState(controller::Action::LEFT_FOOT);
46174852 controller::Pose rightFootPose = userInputMapper->getPoseState(controller::Action::RIGHT_FOOT);
46184853 myAvatar->setFootControllerPosesInSensorFrame(leftFootPose.transform(avatarToSensorMatrix), rightFootPose.transform(avatarToSensorMatrix));