diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 44887599d3..358b05222c 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1735,7 +1735,12 @@ void DomainServer::nodePingMonitor() { nodeList->eachNode([now](const SharedNodePointer& node) { quint64 lastHeard = now - node->getLastHeardMicrostamp(); if (lastHeard > 2 * USECS_PER_SECOND) { - qCDebug(domain_server) << "Haven't heard from " << node->getPublicSocket() << " in " << lastHeard / USECS_PER_MSEC << " msec"; + QString username; + DomainServerNodeData* nodeData = static_cast(node->getLinkedData()); + if (nodeData) { + username = nodeData->getUsername(); + } + qCDebug(domain_server) << "Haven't heard from " << node->getPublicSocket() << username << " in " << lastHeard / USECS_PER_MSEC << " msec"; } }); } diff --git a/interface/resources/qml/InteractiveWindow.qml b/interface/resources/qml/InteractiveWindow.qml index da1e9ec2bf..df3475ea7b 100644 --- a/interface/resources/qml/InteractiveWindow.qml +++ b/interface/resources/qml/InteractiveWindow.qml @@ -58,6 +58,7 @@ Windows.Window { } QmlSurface.load(source, contentHolder, function(newObject) { dynamicContent = newObject; + updateInteractiveWindowSizeForMode(); if (dynamicContent && dynamicContent.anchors) { dynamicContent.anchors.fill = contentHolder; } @@ -81,10 +82,12 @@ Windows.Window { } function updateInteractiveWindowSizeForMode() { - if (presentationMode === Desktop.PresentationMode.VIRTUAL) { - width = interactiveWindowSize.width; - height = interactiveWindowSize.height; - } else if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) { + root.width = interactiveWindowSize.width; + root.height = interactiveWindowSize.height; + contentHolder.width = interactiveWindowSize.width; + contentHolder.height = interactiveWindowSize.height; + + if (presentationMode === Desktop.PresentationMode.NATIVE && nativeWindow) { nativeWindow.width = interactiveWindowSize.width; nativeWindow.height = interactiveWindowSize.height; } @@ -134,6 +137,9 @@ Windows.Window { Window { id: root; + width: interactiveWindowSize.width + height: interactiveWindowSize.height + Rectangle { color: hifi.colors.baseGray anchors.fill: parent diff --git a/interface/resources/qml/hifi/models/PSFListModel.qml b/interface/resources/qml/hifi/models/PSFListModel.qml index b9006bc57c..6dce3f185e 100644 --- a/interface/resources/qml/hifi/models/PSFListModel.qml +++ b/interface/resources/qml/hifi/models/PSFListModel.qml @@ -75,21 +75,31 @@ ListModel { // 1: equivalent to paging when reaching end (and not before). // 0: don't getNextPage on scroll at all here. The application code will do it. property real pageAhead: 2.0; - function needsEarlyYFetch() { - return flickable - && !flickable.atYBeginning - && (flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height)); + function onContentXChanged() { + if (flickable && + !flickable.atXBeginning && + (flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width))) { + getNextPage(); + } } - function needsEarlyXFetch() { - return flickable - && !flickable.atXBeginning - && (flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width)); + function onContentYChanged() { + if (flickable && + !flickable.atYBeginning && + (flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height))) { + getNextPage(); + } } - function getNextPageIfHorizontalScroll() { - if (needsEarlyXFetch()) { getNextPage(); } + function onWidthChanged() { + if (flickable && + (flickable.contentX - flickable.originX) >= (flickable.contentWidth - (pageAhead * flickable.width))) { + getNextPage(); + } } - function getNextPageIfVerticalScroll() { - if (needsEarlyYFetch()) { getNextPage(); } + function onHeightChanged() { + if (flickable && + (flickable.contentY - flickable.originY) >= (flickable.contentHeight - (pageAhead * flickable.height))) { + getNextPage(); + } } function needsMoreHorizontalResults() { return flickable @@ -118,8 +128,10 @@ ListModel { initialized = true; if (flickable && pageAhead > 0.0) { // Pun: Scrollers are usually one direction or another, such that only one of the following will actually fire. - flickable.contentXChanged.connect(getNextPageIfHorizontalScroll); - flickable.contentYChanged.connect(getNextPageIfVerticalScroll); + flickable.contentXChanged.connect(onContentXChanged); + flickable.contentYChanged.connect(onContentYChanged); + flickable.widthChanged.connect(onWidthChanged); + flickable.heightChanged.connect(onHeightChanged); flickable.contentWidthChanged.connect(getNextPageIfNotEnoughHorizontalResults); flickable.contentHeightChanged.connect(getNextPageIfNotEnoughVerticalResults); } diff --git a/interface/resources/qml/hifi/models/qmldir b/interface/resources/qml/hifi/models/qmldir new file mode 100644 index 0000000000..d4c78941e7 --- /dev/null +++ b/interface/resources/qml/hifi/models/qmldir @@ -0,0 +1,3 @@ +module hifiModels +PSFListModel 1.0 PSFListModel.qml +S3Model 1.0 S3Model.qml diff --git a/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml index ef9a3cbe24..d52dd3f3d7 100644 --- a/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml +++ b/interface/resources/qml/hifi/simplifiedUI/avatarApp/AvatarApp.qml @@ -10,6 +10,7 @@ import QtQuick 2.10 import "../simplifiedConstants" as SimplifiedConstants +import "../simplifiedControls" as SimplifiedControls import "./components" as AvatarAppComponents import stylesUit 1.0 as HifiStylesUit import TabletScriptingInterface 1.0 @@ -245,6 +246,10 @@ Rectangle { verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter } + + SimplifiedControls.VerticalScrollBar { + parent: inventoryContentsList + } } diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml index 60703a8062..adb8344902 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/SettingsApp.qml @@ -9,7 +9,9 @@ // import QtQuick 2.10 +import QtQuick.Controls 2.3 import "../simplifiedConstants" as SimplifiedConstants +import "../simplifiedControls" as SimplifiedControls import stylesUit 1.0 as HifiStylesUit import "./audio" as AudioSettings import "./general" as GeneralSettings @@ -129,9 +131,7 @@ Rectangle { id: tabViewContainers anchors.top: tabContainer.bottom anchors.left: parent.left - anchors.leftMargin: 26 anchors.right: parent.right - anchors.rightMargin: 26 anchors.bottom: parent.bottom @@ -162,24 +162,20 @@ Rectangle { visible: activeTabView === "devTabView" anchors.fill: parent } - } - Image { - source: { - if (root.activeTabView === "generalTabView") { - "images/accent1.svg" - } else if (root.activeTabView === "audioTabView") { - "images/accent2.svg" - } else if (root.activeTabView === "vrTabView") { - "images/accent3.svg" - } else { - "images/accent3.svg" + SimplifiedControls.VerticalScrollBar { + parent: { + if (activeTabView === "generalTabView") { + generalTabViewContainer + } else if (activeTabView === "audioTabView") { + audioTabViewContainer + } else if (activeTabView === "vrTabView") { + vrTabViewContainer + } else if (activeTabView === "devTabView") { + devTabViewContainer + } } } - anchors.right: parent.right - anchors.top: tabContainer.bottom - width: 106 - height: 200 } diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml index 4dc5e973fc..68a8fa49da 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml @@ -19,8 +19,6 @@ Flickable { id: root contentWidth: parent.width contentHeight: audioColumnLayout.height - topMargin: 24 - bottomMargin: 24 clip: true function changePeakValuesEnabled(enabled) { @@ -33,7 +31,7 @@ Flickable { AudioScriptingInterface.devices.input.peakValuesEnabled = visible; if (visible) { root.contentX = 0; - root.contentY = -root.topMargin; + root.contentY = 0; AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled); } else { AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled); @@ -45,16 +43,35 @@ Flickable { id: simplifiedUI } + + Image { + id: accent + source: "../images/accent2.svg" + anchors.left: parent.left + anchors.top: parent.top + width: 83 + height: 156 + transform: Scale { + xScale: -1 + origin.x: accent.width / 2 + origin.y: accent.height / 2 + } + } + + ColumnLayout { id: audioColumnLayout anchors.left: parent.left + anchors.leftMargin: 26 anchors.right: parent.right + anchors.rightMargin: 26 anchors.top: parent.top spacing: simplifiedUI.margins.settings.spacingBetweenSettings ColumnLayout { id: volumeControlsContainer Layout.preferredWidth: parent.width + Layout.topMargin: 24 spacing: 0 HifiStylesUit.GraphikSemiBold { @@ -289,6 +306,7 @@ Flickable { ColumnLayout { id: outputDeviceContainer Layout.preferredWidth: parent.width + Layout.bottomMargin: 24 spacing: 0 HifiStylesUit.GraphikSemiBold { diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/dev/Dev.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/dev/Dev.qml index a8c0a8f158..fe623e5d78 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/dev/Dev.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/dev/Dev.qml @@ -19,14 +19,12 @@ Flickable { id: root contentWidth: parent.width contentHeight: devColumnLayout.height - topMargin: 24 - bottomMargin: 24 clip: true onVisibleChanged: { if (visible) { root.contentX = 0; - root.contentY = -root.topMargin; + root.contentY = 0; } } @@ -35,16 +33,36 @@ Flickable { id: simplifiedUI } + + Image { + id: accent + source: "../images/accent3.svg" + anchors.left: parent.left + anchors.top: parent.top + width: 83 + height: 156 + transform: Scale { + xScale: -1 + origin.x: accent.width / 2 + origin.y: accent.height / 2 + } + } + + ColumnLayout { id: devColumnLayout anchors.left: parent.left + anchors.leftMargin: 26 anchors.right: parent.right + anchors.rightMargin: 26 anchors.top: parent.top spacing: simplifiedUI.margins.settings.spacingBetweenSettings ColumnLayout { id: uiControlsContainer Layout.preferredWidth: parent.width + Layout.topMargin: 24 + Layout.bottomMargin: 24 spacing: 0 HifiStylesUit.GraphikSemiBold { diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml index f56d0f33bd..af7e9ba4ae 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/general/General.qml @@ -9,6 +9,7 @@ // import QtQuick 2.10 +import QtQuick.Controls 2.3 import "../../simplifiedConstants" as SimplifiedConstants import "../../simplifiedControls" as SimplifiedControls import stylesUit 1.0 as HifiStylesUit @@ -20,8 +21,6 @@ Flickable { id: root contentWidth: parent.width contentHeight: generalColumnLayout.height - topMargin: 24 - bottomMargin: 24 clip: true onAvatarNametagModeChanged: { @@ -31,7 +30,7 @@ Flickable { onVisibleChanged: { if (visible) { root.contentX = 0; - root.contentY = -root.topMargin; + root.contentY = 0; } } @@ -39,16 +38,35 @@ Flickable { id: simplifiedUI } + + Image { + id: accent + source: "../images/accent1.svg" + anchors.left: parent.left + anchors.top: parent.top + width: 83 + height: 156 + transform: Scale { + xScale: -1 + origin.x: accent.width / 2 + origin.y: accent.height / 2 + } + } + + ColumnLayout { id: generalColumnLayout anchors.left: parent.left + anchors.leftMargin: 26 anchors.right: parent.right + anchors.rightMargin: 26 anchors.top: parent.top spacing: simplifiedUI.margins.settings.spacingBetweenSettings ColumnLayout { id: avatarNameTagsContainer Layout.preferredWidth: parent.width + Layout.topMargin: 24 spacing: 0 HifiStylesUit.GraphikSemiBold { @@ -193,29 +211,36 @@ Flickable { } } - HifiStylesUit.GraphikRegular { - id: logoutText - text: (AccountServices.username === "Unknown user" ? "Log In" : "Logout " + AccountServices.username) - wrapMode: Text.Wrap - width: paintedWidth - height: paintedHeight - size: 14 - color: simplifiedUI.colors.text.lightBlue + ColumnLayout { + id: logoutContainer + Layout.preferredWidth: parent.width + Layout.bottomMargin: 24 + spacing: 0 - MouseArea { - anchors.fill: parent - hoverEnabled: true - onEntered: { - parent.color = simplifiedUI.colors.text.lightBlueHover; - } - onExited: { - parent.color = simplifiedUI.colors.text.lightBlue; - } - onClicked: { - if (Account.loggedIn) { - AccountServices.logOut(); - } else { - DialogsManager.showLoginDialog(); + HifiStylesUit.GraphikRegular { + id: logoutText + text: (AccountServices.username === "Unknown user" ? "Log In" : "Logout " + AccountServices.username) + wrapMode: Text.Wrap + width: paintedWidth + height: paintedHeight + size: 14 + color: simplifiedUI.colors.text.lightBlue + + MouseArea { + anchors.fill: parent + hoverEnabled: true + onEntered: { + parent.color = simplifiedUI.colors.text.lightBlueHover; + } + onExited: { + parent.color = simplifiedUI.colors.text.lightBlue; + } + onClicked: { + if (Account.loggedIn) { + AccountServices.logOut(); + } else { + DialogsManager.showLoginDialog(); + } } } } diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml index 9f5ed3ff8f..c1dc3888e2 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml @@ -19,8 +19,6 @@ Flickable { id: root contentWidth: parent.width contentHeight: vrColumnLayout.height - topMargin: 24 - bottomMargin: 24 clip: true function changePeakValuesEnabled(enabled) { @@ -33,7 +31,7 @@ Flickable { AudioScriptingInterface.devices.input.peakValuesEnabled = visible; if (visible) { root.contentX = 0; - root.contentY = -root.topMargin; + root.contentY = 0; AudioScriptingInterface.devices.input.peakValuesEnabledChanged.connect(changePeakValuesEnabled); } else { AudioScriptingInterface.devices.input.peakValuesEnabledChanged.disconnect(changePeakValuesEnabled); @@ -45,16 +43,35 @@ Flickable { id: simplifiedUI } + + Image { + id: accent + source: "../images/accent3.svg" + anchors.left: parent.left + anchors.top: parent.top + width: 83 + height: 156 + transform: Scale { + xScale: -1 + origin.x: accent.width / 2 + origin.y: accent.height / 2 + } + } + + ColumnLayout { id: vrColumnLayout anchors.left: parent.left + anchors.leftMargin: 26 anchors.right: parent.right + anchors.rightMargin: 26 anchors.top: parent.top spacing: simplifiedUI.margins.settings.spacingBetweenSettings ColumnLayout { id: controlsContainer Layout.preferredWidth: parent.width + Layout.topMargin: 24 spacing: 0 HifiStylesUit.GraphikSemiBold { @@ -278,6 +295,7 @@ Flickable { ColumnLayout { id: outputDeviceContainer Layout.preferredWidth: parent.width + Layout.bottomMargin: 24 spacing: 0 HifiStylesUit.GraphikSemiBold { diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml index 5aa94d798e..fb09a7ae1d 100644 --- a/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml @@ -144,6 +144,10 @@ QtObject { readonly property color hover: "#FFFFFF" readonly property color focus: "#FFFFFF" } + readonly property QtObject scrollBar: QtObject { + readonly property color background: "#474747" + readonly property color contentItem: "#0198CB" + } } readonly property color darkSeparator: "#595959" @@ -219,6 +223,10 @@ QtObject { readonly property QtObject textField: QtObject { readonly property int editPencilPadding: 6 } + readonly property QtObject scrollBar: QtObject { + readonly property int backgroundWidth: 9 + readonly property int contentItemWidth: 7 + } } } diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/VerticalScrollBar.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/VerticalScrollBar.qml new file mode 100644 index 0000000000..ab3c0a3f72 --- /dev/null +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/VerticalScrollBar.qml @@ -0,0 +1,51 @@ +// +// VerticalScrollBar.qml +// +// Created by Zach Fox on 2019-06-17 +// Copyright 2019 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +import QtQuick 2.10 +import QtQuick.Controls 2.3 +import "../simplifiedConstants" as SimplifiedConstants + +ScrollBar { + SimplifiedConstants.SimplifiedConstants { + id: simplifiedUI + } + + orientation: Qt.Vertical + policy: ScrollBar.AlwaysOn + anchors.top: parent.top + anchors.topMargin: 4 + anchors.right: parent.right + anchors.rightMargin: 4 + anchors.bottom: parent.bottom + anchors.bottomMargin: 4 + width: simplifiedUI.sizes.controls.scrollBar.backgroundWidth + visible: parent.contentHeight > parent.parent.height + position: parent.contentY / parent.contentHeight + size: parent.parent.height / parent.contentHeight + minimumSize: 0.1 + background: Rectangle { + color: simplifiedUI.colors.controls.scrollBar.background + anchors.fill: parent + } + contentItem: Rectangle { + width: simplifiedUI.sizes.controls.scrollBar.contentItemWidth + color: simplifiedUI.colors.controls.scrollBar.contentItem + anchors { + horizontalCenter: parent.horizontalCenter + topMargin: 1 + bottomMargin: 1 + } + } + onPositionChanged: { + if (pressed) { + parent.contentY = position * parent.contentHeight; + } + } +} \ No newline at end of file diff --git a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml index 6e86849d03..42d53d3f79 100644 --- a/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml +++ b/interface/resources/qml/hifi/simplifiedUI/topBar/SimplifiedTopBar.qml @@ -48,7 +48,8 @@ Rectangle { onSkeletonModelURLChanged: { root.updatePreviewUrl(); - if (MyAvatar.skeletonModelURL.indexOf("defaultAvatar" > -1) && topBarInventoryModel.count > 0) { + if ((MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) && + topBarInventoryModel.count > 0) { Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true); MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url; } @@ -100,7 +101,8 @@ Rectangle { inventoryFullyReceived = true; // If we have an avatar in our inventory AND we haven't already auto-selected an avatar... - if (!Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatar", false) && topBarInventoryModel.count > 0) { + if ((!Settings.getValue("simplifiedUI/alreadyAutoSelectedAvatar", false) || + MyAvatar.skeletonModelURL.indexOf("defaultAvatar") > -1 || MyAvatar.skeletonModelURL.indexOf("fst") === -1) && topBarInventoryModel.count > 0) { Settings.setValue("simplifiedUI/alreadyAutoSelectedAvatar", true); MyAvatar.skeletonModelURL = topBarInventoryModel.get(0).download_url; } diff --git a/interface/src/PerformanceManager.cpp b/interface/src/PerformanceManager.cpp index cf6da11aeb..0a028f95cc 100644 --- a/interface/src/PerformanceManager.cpp +++ b/interface/src/PerformanceManager.cpp @@ -63,9 +63,15 @@ PerformanceManager::PerformancePreset PerformanceManager::getPerformancePreset() void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformancePreset preset) { + // Ugly case that prevent us to run deferred everywhere... + bool isDeferredCapable = platform::Profiler::isRenderMethodDeferredCapable(); + switch (preset) { case PerformancePreset::HIGH: - RenderScriptingInterface::getInstance()->setRenderMethod(RenderScriptingInterface::RenderMethod::DEFERRED); + RenderScriptingInterface::getInstance()->setRenderMethod( ( isDeferredCapable ? + RenderScriptingInterface::RenderMethod::DEFERRED : + RenderScriptingInterface::RenderMethod::FORWARD ) ); + RenderScriptingInterface::getInstance()->setShadowsEnabled(true); qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::REALTIME); @@ -73,7 +79,10 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP break; case PerformancePreset::MID: - RenderScriptingInterface::getInstance()->setRenderMethod(RenderScriptingInterface::RenderMethod::DEFERRED); + RenderScriptingInterface::getInstance()->setRenderMethod((isDeferredCapable ? + RenderScriptingInterface::RenderMethod::DEFERRED : + RenderScriptingInterface::RenderMethod::FORWARD)); + RenderScriptingInterface::getInstance()->setShadowsEnabled(false); qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::INTERACTIVE); DependencyManager::get()->setWorldDetailQuality(0.5f); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index efe3d59d90..c88a934acf 100755 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -435,7 +435,7 @@ DetailedMotionState* AvatarManager::createDetailedMotionState(OtherAvatarPointer return nullptr; } -void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar) { +void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) { if (!avatar->_motionState) { avatar->_motionState = new AvatarMotionState(avatar, nullptr); } @@ -452,20 +452,24 @@ void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction transaction.objectsToAdd.push_back(motionState); } motionState->clearIncomingDirtyFlags(); +} - // Rather than reconcile numbers of joints after change to model or LOD - // we blow away old detailedMotionStates and create anew all around. - +void AvatarManager::removeDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) { // delete old detailedMotionStates auto& detailedMotionStates = avatar->getDetailedMotionStates(); if (detailedMotionStates.size() != 0) { for (auto& detailedMotionState : detailedMotionStates) { transaction.objectsToRemove.push_back(detailedMotionState); } - avatar->resetDetailedMotionStates(); + avatar->forgetDetailedMotionStates(); } +} - // build new detailedMotionStates +void AvatarManager::rebuildDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar) { + // Rather than reconcile numbers of joints after change to model or LOD + // we blow away old detailedMotionStates and create anew all around. + removeDetailedAvatarPhysics(transaction, avatar); + auto& detailedMotionStates = avatar->getDetailedMotionStates(); OtherAvatar::BodyLOD lod = avatar->getBodyLOD(); if (lod == OtherAvatar::BodyLOD::Sphere) { auto dMotionState = createDetailedMotionState(avatar, -1); @@ -483,24 +487,21 @@ void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction } } } - avatar->_needsReinsertion = false; + avatar->_needsDetailedRebuild = false; } void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) { _myAvatar->getCharacterController()->buildPhysicsTransaction(transaction); for (auto avatar : _otherAvatarsToChangeInPhysics) { bool isInPhysics = avatar->isInPhysicsSimulation(); - if (isInPhysics != avatar->shouldBeInPhysicsSimulation() || avatar->_needsReinsertion) { + if (isInPhysics != avatar->shouldBeInPhysicsSimulation()) { if (isInPhysics) { transaction.objectsToRemove.push_back(avatar->_motionState); avatar->_motionState = nullptr; - auto& detailedMotionStates = avatar->getDetailedMotionStates(); - for (auto& motionState : detailedMotionStates) { - transaction.objectsToRemove.push_back(motionState); - } - avatar->resetDetailedMotionStates(); + removeDetailedAvatarPhysics(transaction, avatar); } else { rebuildAvatarPhysics(transaction, avatar); + rebuildDetailedAvatarPhysics(transaction, avatar); } } else if (isInPhysics) { AvatarMotionState* motionState = avatar->_motionState; @@ -519,6 +520,10 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact } motionState->clearIncomingDirtyFlags(); } + + if (avatar->_needsDetailedRebuild) { + rebuildDetailedAvatarPhysics(transaction, avatar); + } } } _otherAvatarsToChangeInPhysics.clear(); diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index db1bc125a4..ce23a80309 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -274,7 +274,9 @@ public slots: protected: AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer) override; DetailedMotionState* createDetailedMotionState(OtherAvatarPointer avatar, int32_t jointIndex); - void rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar); + void rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar); + void removeDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar); + void rebuildDetailedAvatarPhysics(PhysicsEngine::Transaction& transaction, const OtherAvatarPointer& avatar); private: explicit AvatarManager(QObject* parent = 0); diff --git a/interface/src/avatar/MyCharacterController.cpp b/interface/src/avatar/MyCharacterController.cpp index aef1bcd668..2f59b70592 100755 --- a/interface/src/avatar/MyCharacterController.cpp +++ b/interface/src/avatar/MyCharacterController.cpp @@ -398,15 +398,13 @@ DetailedMotionState* MyCharacterController::createDetailedMotionStateForJoint(in } void MyCharacterController::clearDetailedMotionStates() { + // we don't actually clear the MotionStates here + // instead we twiddle some flags as a signal of what to do later _pendingFlags |= PENDING_FLAG_REMOVE_DETAILED_FROM_SIMULATION; // We make sure we don't add them again _pendingFlags &= ~PENDING_FLAG_ADD_DETAILED_TO_SIMULATION; } -void MyCharacterController::resetDetailedMotionStates() { - _detailedMotionStates.clear(); -} - void MyCharacterController::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) { for (size_t i = 0; i < _detailedMotionStates.size(); i++) { _detailedMotionStates[i]->forceActive(); @@ -416,6 +414,8 @@ void MyCharacterController::buildPhysicsTransaction(PhysicsEngine::Transaction& for (size_t i = 0; i < _detailedMotionStates.size(); i++) { transaction.objectsToRemove.push_back(_detailedMotionStates[i]); } + // NOTE: the DetailedMotionStates are deleted after being added to PhysicsEngine::Transaction::_objectsToRemove + // See AvatarManager::handleProcessedPhysicsTransaction() _detailedMotionStates.clear(); } if (_pendingFlags & PENDING_FLAG_ADD_DETAILED_TO_SIMULATION) { diff --git a/interface/src/avatar/MyCharacterController.h b/interface/src/avatar/MyCharacterController.h index 0b64f66850..7ddcf94f67 100644 --- a/interface/src/avatar/MyCharacterController.h +++ b/interface/src/avatar/MyCharacterController.h @@ -48,7 +48,6 @@ public: DetailedMotionState* createDetailedMotionStateForJoint(int32_t jointIndex); std::vector& getDetailedMotionStates() { return _detailedMotionStates; } void clearDetailedMotionStates(); - void resetDetailedMotionStates(); void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction); diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index 6f83c61cd6..a6e2d6a998 100755 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -177,7 +177,7 @@ const btCollisionShape* OtherAvatar::createCollisionShape(int32_t jointIndex, bo return ObjectMotionState::getShapeManager()->getShape(shapeInfo); } -void OtherAvatar::resetDetailedMotionStates() { +void OtherAvatar::forgetDetailedMotionStates() { // NOTE: the DetailedMotionStates are deleted after being added to PhysicsEngine::Transaction::_objectsToRemove // See AvatarManager::handleProcessedPhysicsTransaction() _detailedMotionStates.clear(); @@ -209,7 +209,7 @@ void OtherAvatar::computeShapeLOD() { if (newLOD != _bodyLOD) { _bodyLOD = newLOD; if (isInPhysicsSimulation()) { - _needsReinsertion = true; + _needsDetailedRebuild = true; } } } @@ -224,14 +224,14 @@ bool OtherAvatar::shouldBeInPhysicsSimulation() const { bool OtherAvatar::needsPhysicsUpdate() const { constexpr uint32_t FLAGS_OF_INTEREST = Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS | Simulation::DIRTY_POSITION | Simulation::DIRTY_COLLISION_GROUP; - return (_needsReinsertion || (_motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST))); + return (_needsDetailedRebuild || (_motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST))); } void OtherAvatar::rebuildCollisionShape() { if (_motionState) { // do not actually rebuild here, instead flag for later _motionState->addDirtyFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS); - _needsReinsertion = true; + _needsDetailedRebuild = true; } } diff --git a/interface/src/avatar/OtherAvatar.h b/interface/src/avatar/OtherAvatar.h index 498971d6ee..cfe0c8332d 100644 --- a/interface/src/avatar/OtherAvatar.h +++ b/interface/src/avatar/OtherAvatar.h @@ -54,7 +54,7 @@ public: const btCollisionShape* createCollisionShape(int32_t jointIndex, bool& isBound, std::vector& boundJoints); std::vector& getDetailedMotionStates() { return _detailedMotionStates; } - void resetDetailedMotionStates(); + void forgetDetailedMotionStates(); BodyLOD getBodyLOD() { return _bodyLOD; } void computeShapeLOD(); @@ -90,7 +90,7 @@ protected: int32_t _spaceIndex { -1 }; uint8_t _workloadRegion { workload::Region::INVALID }; BodyLOD _bodyLOD { BodyLOD::Sphere }; - bool _needsReinsertion { false }; + bool _needsDetailedRebuild { false }; }; using OtherAvatarPointer = std::shared_ptr; diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index 02ec62e6a5..b87e3a3dbc 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -262,7 +262,7 @@ class Stats : public QQuickItem { STATS_PROPERTY(int, processing, 0) STATS_PROPERTY(int, processingPending, 0) STATS_PROPERTY(int, triangles, 0) - STATS_PROPERTY(uint32_t, drawcalls, 0) + STATS_PROPERTY(quint32 , drawcalls, 0) STATS_PROPERTY(int, materialSwitches, 0) STATS_PROPERTY(int, itemConsidered, 0) STATS_PROPERTY(int, itemOutOfView, 0) diff --git a/launchers/darwin/CMakeLists.txt b/launchers/darwin/CMakeLists.txt index 2de43d93cb..4da675fcc9 100644 --- a/launchers/darwin/CMakeLists.txt +++ b/launchers/darwin/CMakeLists.txt @@ -64,7 +64,8 @@ function(set_from_env _RESULT_NAME _ENV_VAR_NAME _DEFAULT_VALUE) endfunction() add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${src_files}) -set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${APP_NAME}) +set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${APP_NAME} + MACOSX_BUNDLE_BUNDLE_NAME ${APP_NAME}) set_from_env(LAUNCHER_HMAC_SECRET LAUNCHER_HMAC_SECRET "") if (LAUNCHER_HMAC_SECRET STREQUAL "") message(FATAL_ERROR "LAUNCHER_HMAC_SECRET is not set") diff --git a/launchers/darwin/cmake/modules/MacOSXBundleInfo.plist.in b/launchers/darwin/cmake/modules/MacOSXBundleInfo.plist.in index 62d6856ba9..4c87bff3cf 100644 --- a/launchers/darwin/cmake/modules/MacOSXBundleInfo.plist.in +++ b/launchers/darwin/cmake/modules/MacOSXBundleInfo.plist.in @@ -5,7 +5,7 @@ CFBundleDevelopmentRegion English CFBundleExecutable - ${EXECUTABLE_NAME} + ${APP_NAME} CFBundleIconFile ${MACOSX_BUNDLE_ICON_FILE} CFBundleIdentifier @@ -29,7 +29,9 @@ Window NSPrincipalClass NSApplication + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} CFBundleDisplayName - HQ Launcher + CFBundleName diff --git a/launchers/darwin/images/interface.icns b/launchers/darwin/images/interface.icns index 4aeb8301ce..8dadfd5037 100644 Binary files a/launchers/darwin/images/interface.icns and b/launchers/darwin/images/interface.icns differ diff --git a/launchers/darwin/src/ProcessScreen.m b/launchers/darwin/src/ProcessScreen.m index fb1de799da..4aeb8abda1 100644 --- a/launchers/darwin/src/ProcessScreen.m +++ b/launchers/darwin/src/ProcessScreen.m @@ -25,7 +25,7 @@ break; case CHECKING_UPDATE: [self.boldStatus setStringValue:@"Getting updates..."]; - [self.smallStatus setStringValue:@"We're getting the lastest and greatest for you, one sec."]; + [self.smallStatus setStringValue:@"We're getting the latest and greatest for you, one sec."]; break; case RUNNING_INTERFACE_AFTER_UPDATE: [self.boldStatus setStringValue:@"You're good to go!"]; diff --git a/launchers/win32/res/interface.ico b/launchers/win32/res/interface.ico index cdd4792f56..09a97956a7 100644 Binary files a/launchers/win32/res/interface.ico and b/launchers/win32/res/interface.ico differ diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 8671b3da7e..1ecbcb0c8b 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -256,28 +256,18 @@ void EntityTreeRenderer::clear() { } // reset the engine + if (_wantScripts && !_shuttingDown) { + resetEntitiesScriptEngine(); + } + // remove all entities from the scene auto scene = _viewState->getMain3DScene(); - if (_shuttingDown) { - if (scene) { - render::Transaction transaction; - for (const auto& entry : _entitiesInScene) { - const auto& renderer = entry.second; - renderer->removeFromScene(scene, transaction); - } - scene->enqueueTransaction(transaction); + if (scene) { + for (const auto& entry : _entitiesInScene) { + const auto& renderer = entry.second; + fadeOutRenderable(renderer); } } else { - if (_wantScripts) { - resetEntitiesScriptEngine(); - } - if (scene) { - for (const auto& entry : _entitiesInScene) { - const auto& renderer = entry.second; - fadeOutRenderable(renderer); - } - } else { - qCWarning(entitiesrenderer) << "EntitityTreeRenderer::clear(), Unexpected null scene"; - } + qCWarning(entitiesrenderer) << "EntitityTreeRenderer::clear(), Unexpected null scene, possibly during application shutdown"; } _entitiesInScene.clear(); _renderablesToUpdate.clear(); diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index 1fc8a2382b..54edd3543c 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -368,6 +368,10 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { } if (type == SHAPE_TYPE_COMPOUND) { + if (!_compoundShapeResource || !_compoundShapeResource->isLoaded()) { + return; + } + updateModelBounds(); // should never fall in here when collision model not fully loaded diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 5b5fc08460..3b615ba467 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -7,7 +7,6 @@ // #include "RenderableWebEntityItem.h" -#include #include #include @@ -47,7 +46,7 @@ static uint64_t MAX_NO_RENDER_INTERVAL = 30 * USECS_PER_SECOND; static uint8_t YOUTUBE_MAX_FPS = 30; // Don't allow more than 20 concurrent web views -static std::atomic _currentWebCount(0); +static uint32_t _currentWebCount { 0 }; static const uint32_t MAX_CONCURRENT_WEB_VIEWS = 20; static QTouchDevice _touchDevice; @@ -357,15 +356,16 @@ void WebEntityRenderer::buildWebSurface(const EntityItemPointer& entity, const Q void WebEntityRenderer::destroyWebSurface() { QSharedPointer webSurface; + ContentType contentType = ContentType::NoContent; withWriteLock([&] { webSurface.swap(_webSurface); - _contentType = ContentType::NoContent; - - if (webSurface) { - --_currentWebCount; - WebEntityRenderer::releaseWebSurface(webSurface, _cachedWebSurface, _connections); - } + _contentType = contentType; }); + + if (webSurface) { + --_currentWebCount; + WebEntityRenderer::releaseWebSurface(webSurface, _cachedWebSurface, _connections); + } } glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) const { @@ -469,12 +469,6 @@ void WebEntityRenderer::handlePointerEventAsMouse(const PointerEvent& event) { QCoreApplication::sendEvent(_webSurface->getWindow(), &mouseEvent); } -void WebEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity) { - // HACK: destroyWebSurface() here to avoid a crash on shutdown. - // TODO: fix the real problem: EntityRenderer<>::dtor never called on shutdown for smart-pointer resource leak. - destroyWebSurface(); -} - void WebEntityRenderer::setProxyWindow(QWindow* proxyWindow) { withReadLock([&] { if (_webSurface) { diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.h b/libraries/entities-renderer/src/RenderableWebEntityItem.h index 6cda1601c8..7118774d30 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.h +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.h @@ -64,7 +64,6 @@ protected: void handlePointerEventAsTouch(const PointerEvent& event); void handlePointerEventAsMouse(const PointerEvent& event); - void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; private: void onTimeout(); void buildWebSurface(const EntityItemPointer& entity, const QString& newSourceURL); diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index b442463ac8..3512b02d11 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -559,6 +559,8 @@ void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { + auto nodeList = DependencyManager::get(); - auto nodeList = DependencyManager::get(); + if (_checkInPacketsSinceLastReply > SILENT_DOMAIN_TRAFFIC_DROP_MIN) { + qCDebug(networking_ice) << _checkInPacketsSinceLastReply << "seconds since last domain list request, squelching traffic"; + nodeList->setDropOutgoingNodeTraffic(true); + } + + if (_checkInPacketsSinceLastReply > MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { // we haven't heard back from DS in MAX_SILENT_DOMAIN_SERVER_CHECK_INS // so emit our signal that says that diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 9f4eb39013..8fefe5820c 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -409,6 +409,16 @@ qint64 LimitedNodeList::sendUnreliablePacket(const NLPacket& packet, const HifiS Q_ASSERT_X(!packet.isReliable(), "LimitedNodeList::sendUnreliablePacket", "Trying to send a reliable packet unreliably."); + if (_dropOutgoingNodeTraffic) { + auto destinationNode = findNodeWithAddr(sockAddr); + + // findNodeWithAddr returns null for the address of the domain server + if (!destinationNode.isNull()) { + // This only suppresses individual unreliable packets, not unreliable packet lists + return ERROR_SENDING_PACKET_BYTES; + } + } + fillPacketHeader(packet, hmacAuth); return _nodeSocket.writePacket(packet, sockAddr); diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index bd5e6bd013..f9f6bf3b3e 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -335,6 +335,8 @@ public: float getInboundKbps() const { return _inboundKbps; } float getOutboundKbps() const { return _outboundKbps; } + void setDropOutgoingNodeTraffic(bool squelchOutgoingNodeTraffic) { _dropOutgoingNodeTraffic = squelchOutgoingNodeTraffic; } + const std::set SOLO_NODE_TYPES = { NodeType::AvatarMixer, NodeType::AudioMixer, @@ -493,6 +495,8 @@ private: int _outboundPPS { 0 }; float _inboundKbps { 0.0f }; float _outboundKbps { 0.0f }; + + bool _dropOutgoingNodeTraffic { false }; }; #endif // hifi_LimitedNodeList_h diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 86b33bbe20..3d367bc761 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -306,7 +306,8 @@ void NodeList::sendDomainServerCheckIn() { // may be called by multiple threads. if (!_sendDomainServerCheckInEnabled) { - qCDebug(networking_ice) << "Refusing to send a domain-server check in while it is disabled."; + static const QString DISABLED_CHECKIN_DEBUG{ "Refusing to send a domain-server check in while it is disabled." }; + HIFI_FCDEBUG(networking_ice(), DISABLED_CHECKIN_DEBUG); return; } @@ -450,13 +451,8 @@ void NodeList::sendDomainServerCheckIn() { // Send duplicate check-ins in the exponentially increasing sequence 1, 1, 2, 4, ... static const int MAX_CHECKINS_TOGETHER = 20; - static const int REBIND_CHECKIN_COUNT = 2; int outstandingCheckins = _domainHandler.getCheckInPacketsSinceLastReply(); - if (outstandingCheckins > REBIND_CHECKIN_COUNT) { - _nodeSocket.rebind(); - } - int checkinCount = outstandingCheckins > 1 ? std::pow(2, outstandingCheckins - 2) : 1; checkinCount = std::min(checkinCount, MAX_CHECKINS_TOGETHER); for (int i = 1; i < checkinCount; ++i) { @@ -710,6 +706,7 @@ void NodeList::processDomainServerList(QSharedPointer message) // this is a packet from the domain server, reset the count of un-replied check-ins _domainHandler.clearPendingCheckins(); + setDropOutgoingNodeTraffic(false); // emit our signal so listeners know we just heard from the DS emit receivedDomainServerList(); diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index fc6d2cbe2a..3a7a056c77 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -230,7 +230,7 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc // _udpSocket.writeDatagram will return an error anyway, but there are // potential crashes in Qt when that happens. if (_udpSocket.state() != QAbstractSocket::BoundState) { - qCDebug(networking) << "Attempt to writeDatagram when in unbound state"; + qCDebug(networking) << "Attempt to writeDatagram when in unbound state to" << sockAddr; return -1; } qint64 bytesWritten = _udpSocket.writeDatagram(datagram, sockAddr.getAddress(), sockAddr.getPort()); @@ -240,11 +240,11 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc #ifdef WIN32 wsaError = WSAGetLastError(); #endif - qCDebug(networking) << "udt::writeDatagram (" << _udpSocket.state() << ") error - " << wsaError << _udpSocket.error() << "(" << _udpSocket.errorString() << ")" + qCDebug(networking) << "udt::writeDatagram (" << _udpSocket.state() << sockAddr << ") error - " << wsaError << _udpSocket.error() << "(" << _udpSocket.errorString() << ")" << (pending ? "pending bytes:" : "pending:") << pending; #ifdef DEBUG_EVENT_QUEUE int nodeListQueueSize = ::hifi::qt::getEventQueueSize(thread()); - qCDebug(networking) << "Networking queue size - " << nodeListQueueSize; + qCDebug(networking) << "Networking queue size - " << nodeListQueueSize << "writing datagram to" << sockAddr; #endif // DEBUG_EVENT_QUEUE } diff --git a/libraries/platform/src/platform/Profiler.cpp b/libraries/platform/src/platform/Profiler.cpp index f77bbec46b..1c055a5ec9 100644 --- a/libraries/platform/src/platform/Profiler.cpp +++ b/libraries/platform/src/platform/Profiler.cpp @@ -12,6 +12,7 @@ #include "Platform.h" #include "PlatformKeys.h" +#include using namespace platform; @@ -124,4 +125,40 @@ bool filterOnProcessors(const platform::json& computer, const platform::json& cp // Not able to profile return false; -} \ No newline at end of file +} + +// Ugly very adhoc capability check to know if a particular hw can REnder with Deferred method or not +// YES for PC windows and linux +// NO for android +// YES on macos EXCEPT for macbookair with gpu intel iris or intel HD 6000 +bool Profiler::isRenderMethodDeferredCapable() { +#if defined(Q_OS_MAC) + auto computer = platform::getComputer(); + const auto computerModel = (computer.count(keys::computer::model) ? computer[keys::computer::model].get() : ""); + + auto gpuInfo = platform::getGPU(0); + const auto gpuModel = (gpuInfo.count(keys::gpu::model) ? gpuInfo[keys::gpu::model].get() : ""); + + + // Macbook air 2018 are a problem + if ((computerModel.find("MacBookAir7,2") != std::string::npos) && (gpuModel.find("Intel HD Graphics 6000") != std::string::npos)) { + return false; + } + + // We know for fact that the Mac BOok Pro 13 from Mid 2014 INtel Iris is problematic, + if ((computerModel.find("MacBookPro11,1") != std::string::npos) && (gpuModel.find("Intel Iris") != std::string::npos)) { + return false; + } + + // TO avoid issues for the next few days, we are excluding all of intel chipset... + if ((gpuModel.find("Intel ") != std::string::npos)) { + return false; + } + + return true; +#elif defined(Q_OS_ANDROID) + return false; +#else + return true; +#endif +} diff --git a/libraries/platform/src/platform/Profiler.h b/libraries/platform/src/platform/Profiler.h index fea0622c89..c47f2587f2 100644 --- a/libraries/platform/src/platform/Profiler.h +++ b/libraries/platform/src/platform/Profiler.h @@ -28,6 +28,9 @@ public: static const std::array TierNames; static Tier profilePlatform(); + + // Ugly very adhoc capability check to know if a particular hw can REnder with Deferred method or not + static bool isRenderMethodDeferredCapable(); }; } diff --git a/libraries/shared/src/GPUIdent.cpp b/libraries/shared/src/GPUIdent.cpp index d5c2f3ec6c..f092a56c17 100644 --- a/libraries/shared/src/GPUIdent.cpp +++ b/libraries/shared/src/GPUIdent.cpp @@ -47,6 +47,7 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) GLint rendererInfoCount; CGLError err = CGLQueryRendererInfo(cglDisplayMask, &rendererInfo, &rendererInfoCount); GLint j, numRenderers = 0, deviceVRAM, bestVRAM = 0; + int bestGPUid = 0; err = CGLQueryRendererInfo(cglDisplayMask, &rendererInfo, &numRenderers); if (0 == err) { // Iterate over all of them and use the figure for the one with the most VRAM, @@ -55,6 +56,7 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) for (j = 0; j < numRenderers; j++) { CGLDescribeRenderer(rendererInfo, j, kCGLRPVideoMemoryMegabytes, &deviceVRAM); if (deviceVRAM > bestVRAM) { + bestGPUid = j; bestVRAM = deviceVRAM; _isValid = true; } @@ -78,6 +80,8 @@ GPUIdent* GPUIdent::ensureQuery(const QString& vendor, const QString& renderer) for (int i = 0; i < parts.size(); ++i) { if (parts[i].toLower().contains("radeon") || parts[i].toLower().contains("nvidia")) { _name=parts[i]; + } else if (i == bestGPUid) { + _name=parts[i]; } } diff --git a/scripts/developer/utilities/render/luci.qml b/scripts/developer/utilities/render/luci.qml index 2dc8fda081..98fd3039d1 100644 --- a/scripts/developer/utilities/render/luci.qml +++ b/scripts/developer/utilities/render/luci.qml @@ -26,8 +26,9 @@ Rectangle { color: global.color ScrollView { - id: control + id: scrollView anchors.fill: parent + contentWidth: parent.width clip: true Column { diff --git a/scripts/developer/utilities/render/performanceSetup.qml b/scripts/developer/utilities/render/performanceSetup.qml index ab00d31f2b..4654736f72 100644 --- a/scripts/developer/utilities/render/performanceSetup.qml +++ b/scripts/developer/utilities/render/performanceSetup.qml @@ -24,9 +24,12 @@ Rectangle { color: global.colorBack ScrollView { + id: scrollView anchors.fill: parent + contentWidth: parent.width clip: true - Column { + + Column { anchors.left: parent.left anchors.right: parent.right @@ -35,8 +38,6 @@ Rectangle { isUnfold: true panelFrameData: Component { PerformanceSettings { - anchors.left: parent.left - anchors.right: parent.right } } } @@ -45,8 +46,6 @@ Rectangle { isUnfold: true panelFrameData: Component { RenderSettings { - anchors.left: parent.left - anchors.right: parent.right } } } @@ -54,8 +53,6 @@ Rectangle { label: "Platform" panelFrameData: Component { Platform { - anchors.left: parent.left - anchors.right: parent.right } } } diff --git a/scripts/simplifiedUI/system/progress.js b/scripts/simplifiedUI/system/progress.js index b373612790..a641dd4556 100644 --- a/scripts/simplifiedUI/system/progress.js +++ b/scripts/simplifiedUI/system/progress.js @@ -83,9 +83,7 @@ // The initial delay cooldown keeps us from tracking progress before the allotted time // has passed. INITIAL_DELAY_COOLDOWN_TIME = 1000, - initialDelayCooldown = 0, - - isInInterstitialMode = false; + initialDelayCooldown = 0; function fade() { @@ -267,7 +265,7 @@ // Update state if (!visible) { // Not visible because no recent downloads - if ((displayProgress < 100 || gpuTextures > 0) && !isInInterstitialMode && !isInterstitialOverlaysVisible) { // Have started downloading so fade in + if (displayProgress < 100 || gpuTextures > 0) { // Have started downloading so fade in visible = true; alphaDelta = ALPHA_DELTA_IN; fadeTimer = Script.setInterval(fade, FADE_INTERVAL); @@ -307,9 +305,6 @@ } else { x = x * BAR_HMD_REPEAT; } - if (isInInterstitialMode || isInterstitialOverlaysVisible) { - visible = false; - } // Update progress bar Overlays.editOverlay(barDesktop.overlay, { @@ -349,10 +344,6 @@ } } - function interstitialModeChanged(inMode) { - isInInterstitialMode = inMode; - } - function setUp() { var is4k = Window.innerWidth > 3000; @@ -378,7 +369,6 @@ } setUp(); - Window.interstitialModeChanged.connect(interstitialModeChanged); GlobalServices.downloadInfoChanged.connect(onDownloadInfoChanged); GlobalServices.updateDownloadInfo(); Script.setInterval(update, 1000 / 60); diff --git a/scripts/simplifiedUI/ui/simplifiedStatusIndicator/simplifiedStatusIndicator.js b/scripts/simplifiedUI/ui/simplifiedStatusIndicator/simplifiedStatusIndicator.js index 9968260034..789c497104 100644 --- a/scripts/simplifiedUI/ui/simplifiedStatusIndicator/simplifiedStatusIndicator.js +++ b/scripts/simplifiedUI/ui/simplifiedStatusIndicator/simplifiedStatusIndicator.js @@ -152,7 +152,7 @@ function simplifiedStatusIndicator(properties) { // When avatar goes away, set status to busy - var previousStatus; + var previousStatus = "available"; function onWentAway() { previousStatus = currentStatus; if (currentStatus !== "busy") { diff --git a/scripts/simplifiedUI/ui/simplifiedUI.js b/scripts/simplifiedUI/ui/simplifiedUI.js index 16f081fb6b..70679b09bd 100644 --- a/scripts/simplifiedUI/ui/simplifiedUI.js +++ b/scripts/simplifiedUI/ui/simplifiedUI.js @@ -415,7 +415,7 @@ function getInputDeviceMutedOverlayTopY() { var inputDeviceMutedOverlay = false; var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_X_PX = 353; var INPUT_DEVICE_MUTED_OVERLAY_DEFAULT_Y_PX = 95; -var INPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX = 20; +var INPUT_DEVICE_MUTED_MARGIN_BOTTOM_PX = 20 + TOP_BAR_HEIGHT_PX; function updateInputDeviceMutedOverlay(isMuted) { if (isMuted) { var props = {