Merge branch 'master' into DOC-79

This commit is contained in:
David Rowe 2019-06-22 12:11:22 +12:00
commit b2b7a6ae99
377 changed files with 48325 additions and 698 deletions

View file

@ -33,7 +33,7 @@ If you do not wish to use the Python installation bundled with Visual Studio, yo
Download and install the latest version of CMake 3.9.
Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.9 Version page](https://cmake.org/files/v3.9/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted.
Download the file named win64-x64 Installer from the [CMake Website](https://cmake.org/download/). You can access the installer on this [3.14 Version page](https://cmake.org/files/v3.14/). During installation, make sure to check "Add CMake to system PATH for all users" when prompted.
### Step 3. Create VCPKG environment variable
In the next step, you will use CMake to build High Fidelity. By default, the CMake process builds dependency files in Windows' `%TEMP%` directory, which is periodically cleared by the operating system. To prevent you from having to re-build the dependencies in the event that Windows clears that directory, we recommend that you create a `HIFI_VCPKG_BASE` environment variable linked to a directory somewhere on your machine. That directory will contain all dependency files until you manually remove them.

View file

@ -139,6 +139,7 @@ option(BUILD_MANUAL_TESTS "Build manual tests" ${BUILD_MANUAL_TESTS_OPTION})
option(BUILD_TOOLS "Build tools" ${BUILD_TOOLS_OPTION})
option(BUILD_INSTALLER "Build installer" ${BUILD_INSTALLER_OPTION})
option(USE_GLES "Use OpenGL ES" ${GLES_OPTION})
option(USE_KHR_ROBUSTNESS "Use KHR_robustness" OFF)
option(DISABLE_QML "Disable QML" ${DISABLE_QML_OPTION})
option(DISABLE_KTX_CACHE "Disable KTX Cache" OFF)
option(
@ -149,6 +150,10 @@ option(
set(PLATFORM_QT_GL OpenGL)
if (USE_KHR_ROBUSTNESS)
add_definitions(-DUSE_KHR_ROBUSTNESS)
endif()
if (USE_GLES)
add_definitions(-DUSE_GLES)
add_definitions(-DGPU_POINTER_STORAGE_SHARED)

View file

@ -127,7 +127,8 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
<< "and machine fingerprint" << nodeConnection.machineFingerprint
<< "user" << username
<< "reason" << QString(nodeConnection.connectReason ? "SilentDomainDisconnect" : "Connect")
<< "previous connection uptime" << nodeConnection.previousConnectionUpTime/USECS_PER_MSEC << "msec";
<< "previous connection uptime" << nodeConnection.previousConnectionUpTime/USECS_PER_MSEC << "msec"
<< "sysinfo" << nodeConnection.SystemInfo;
// signal that we just connected a node so the DomainServer can get it a list
// and broadcast its presence right away

View file

@ -739,6 +739,10 @@ void DomainServer::setupNodeListAndAssignments() {
connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded);
connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled);
connect(nodeList.data(), &LimitedNodeList::localSockAddrChanged, this,
[this](const HifiSockAddr& localSockAddr) {
DependencyManager::get<LimitedNodeList>()->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this, localSockAddr.getPort());
});
// register as the packet receiver for the types we want
PacketReceiver& packetReceiver = nodeList->getPacketReceiver();

View file

@ -36,6 +36,9 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c
// now the machine fingerprint
dataStream >> newHeader.machineFingerprint;
// and the operating system type
dataStream >> newHeader.SystemInfo;
dataStream >> newHeader.connectReason;
dataStream >> newHeader.previousConnectionUpTime;

View file

@ -31,9 +31,9 @@ public:
QString placeName;
QString hardwareAddress;
QUuid machineFingerprint;
QString SystemInfo;
quint32 connectReason;
quint64 previousConnectionUpTime;
QByteArray protocolVersion;
};

View file

@ -53,6 +53,9 @@ Item {
StatText {
text: root.recenterText
}
StatText {
text: root.overrideJointText
}
StatText {
text: "Anim Vars:--------------------------------------------------------------------------------"
}
@ -98,6 +101,9 @@ Item {
StatText {
text: root.sittingText
}
StatText {
text: root.flowText
}
StatText {
text: "State Machines:---------------------------------------------------------------------------"
}
@ -131,6 +137,9 @@ Item {
StatText {
text: root.walkingText
}
StatText {
text: root.networkGraphText
}
StatText {
text: "Alpha Values:--------------------------------------------------------------------------"
}

View file

@ -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

View file

@ -0,0 +1,25 @@
module controls
Button 1.0 Button.qml
ButtonAwesome 1.0 ButtonAwesome.qml
CheckBox 1.0 CheckBox.qml
ComboBox 1.0 ComboBox.qml
FlickableWebViewCore 1.0 FlickableWebViewCore.qml
FontAwesome 1.0 FontAwesome.qml
Player 1.0 Player.qml
RadioButton 1.0 RadioButton.qml
Slider 1.0 Slider.qml
Spacer 1.0 Spacer.qml
SpinBox 1.0 SpinBox.qml
TabletWebButton 1.0 TabletWebButton.qml
TabletWebScreen 1.0 TabletWebScreen.qml
TabletWebView 1.0 TabletWebView.qml
Text 1.0 Text.qml
TextAndSlider 1.0 TextAndSlider.qml
TextAndSpinBox 1.0 TextAndSpinBox.qml
TextArea 1.0 TextArea.qml
TextEdit 1.0 TextEdit.qml
TextField 1.0 TextField.qml
TextHeader 1.0 TextHeader.qml
TextInput 1.0 TextInput.qml
TextInputAndButton 1.0 TextInputAndButton.qml
WebView 1.0 WebView.qml

View file

@ -0,0 +1,18 @@
module dialogs
AboutDialog 1.0 AboutDialog.qml
AdvancedPreferencesDialog 1.0 AdvancedPreferencesDialog.qml
AudioBuffers 1.0 AudioBuffers.qml
AvatarPreferencesDialog 1.0 AvatarPreferencesDialog.qml
GeneralPreferencesDialog 1.0 GeneralPreferencesDialog.qml
LodPreferencesDialog 1.0 LodPreferencesDialog.qml
ModelBrowserDialog 1.0 ModelBrowserDialog.qml
NetworkingPreferencesDialog 1.0 NetworkingPreferencesDialog.qml
RunningScripts 1.0 RunningScripts.qml
TabletAboutDialog 1.0 TabletAboutDialog.qml
TabletAssetServer 1.0 TabletAssetServer.qml
TabletDCDialog 1.0 TabletDCDialog.qml
TabletDebugWindow 1.0 TabletDebugWindow.qml
TabletEntityStatistics 1.0 TabletEntityStatistics.qml
TabletEntityStatisticsItem 1.0 TabletEntityStatisticsItem.qml
TabletLODTools 1.0 TabletLODTools.qml
TabletRunningScripts 1.0 TabletRunningScripts.qml

View file

@ -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);
}

View file

@ -0,0 +1,3 @@
module hifiModels
PSFListModel 1.0 PSFListModel.qml
S3Model 1.0 S3Model.qml

View file

@ -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
}
}

View file

@ -94,6 +94,7 @@ Item {
text: MyAvatar.sessionDisplayName === "" ? MyAvatar.displayName : MyAvatar.sessionDisplayName
maximumLength: 256
clip: true
selectByMouse: true
anchors.fill: parent
onEditingFinished: {
if (MyAvatar.displayName !== text) {

View file

@ -9,12 +9,15 @@
//
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
import "./vr" as VrSettings
import "./dev" as DevSettings
import "./about" as AboutSettings
Rectangle {
property string activeTabView: "generalTabView"
@ -74,6 +77,10 @@ Rectangle {
tabTitle: "VR"
tabViewName: "vrTabView"
}
ListElement {
tabTitle: "About"
tabViewName: "aboutTabView"
}
ListElement {
tabTitle: "Dev"
tabViewName: "devTabView"
@ -101,7 +108,7 @@ Rectangle {
delegate: Item {
visible: model.tabTitle !== "Dev" || (model.tabTitle === "Dev" && root.developerModeEnabled)
width: tabTitleText.paintedWidth + 64
width: tabTitleText.paintedWidth + 32
height: parent.height
HifiStylesUit.GraphikRegular {
@ -129,9 +136,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 +167,28 @@ 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"
AboutSettings.About {
id: aboutTabViewContainer
visible: activeTabView === "aboutTabView"
anchors.fill: parent
}
SimplifiedControls.VerticalScrollBar {
parent: {
if (activeTabView === "generalTabView") {
generalTabViewContainer
} else if (activeTabView === "audioTabView") {
audioTabViewContainer
} else if (activeTabView === "vrTabView") {
vrTabViewContainer
} else if (activeTabView === "devTabView") {
devTabViewContainer
} else if (activeTabView === "aboutTabView") {
aboutTabViewContainer
}
}
}
anchors.right: parent.right
anchors.top: tabContainer.bottom
width: 106
height: 200
}

View file

@ -0,0 +1,218 @@
//
// About.qml
//
// Created by Zach Fox on 2019-06-18
// 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
import "../../simplifiedControls" as SimplifiedControls
import stylesUit 1.0 as HifiStylesUit
import QtQuick.Layouts 1.3
Flickable {
id: root
contentWidth: parent.width
contentHeight: aboutColumnLayout.height
clip: true
onVisibleChanged: {
if (visible) {
root.contentX = 0;
root.contentY = 0;
}
}
SimplifiedConstants.SimplifiedConstants {
id: simplifiedUI
}
ColumnLayout {
id: aboutColumnLayout
anchors.left: parent.left
anchors.leftMargin: 26
anchors.right: parent.right
anchors.rightMargin: 26
anchors.top: parent.top
spacing: 0
Image {
source: "images/logo.png"
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: 16
Layout.preferredWidth: 200
Layout.preferredHeight: 150
fillMode: Image.PreserveAspectFit
mipmap: true
}
ColumnLayout {
id: platformInfoContainer
Layout.preferredWidth: parent.width
Layout.bottomMargin: 24
spacing: 0
HifiStylesUit.GraphikSemiBold {
text: "Version " + Window.checkVersion()
Layout.alignment: Qt.AlignHCenter
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikSemiBold {
text: "Platform Info"
Layout.maximumWidth: parent.width
Layout.topMargin: 8
Layout.bottomMargin: 8
height: paintedHeight
size: 22
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>Computer Vendor/Model:</b>"
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
Component.onCompleted: {
var computer = JSON.parse(PlatformInfo.getComputer());
var computerVendor = computer.vendor;
if (computerVendor.length === 0) {
computerVendor = "Unknown";
}
var computerModel = computer.model;
if (computerModel.length === 0) {
computerModel = "Unknown";
}
text = "<b>Computer Vendor/Model:</b> " + computerVendor + "/" + computerModel;
}
}
HifiStylesUit.GraphikRegular {
text: "<b>Profiled Platform Tier:</b> " + PlatformInfo.getTierProfiled()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>OS Type:</b> " + PlatformInfo.getOperatingSystemType()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>CPU:</b> " + PlatformInfo.getCPUBrand()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b># CPUs:</b> " + PlatformInfo.getNumCPUs()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b># CPU Cores:</b> " + PlatformInfo.getNumLogicalCores()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>RAM:</b> " + PlatformInfo.getTotalSystemMemoryMB() + " MB"
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>GPU:</b> " + PlatformInfo.getGraphicsCardType()
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
HifiStylesUit.GraphikRegular {
text: "<b>VR Hand Controllers:</b> " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None"))
Layout.maximumWidth: parent.width
height: paintedHeight
size: 16
color: simplifiedUI.colors.text.white
wrapMode: Text.Wrap
}
SimplifiedControls.Button {
Layout.topMargin: 8
width: 200
height: 32
text: "Copy to Clipboard"
onClicked: {
Window.copyToClipboard(root.buildPlatformInfoTextToCopy());
}
}
}
}
function buildPlatformInfoTextToCopy() {
var textToCopy = "**About Interface**\n";
textToCopy += "Interface Version: " + Window.checkVersion() + "\n";
textToCopy += "\n**Platform Info**\n";
var computer = JSON.parse(PlatformInfo.getComputer());
var computerVendor = computer.vendor;
if (computerVendor.length === 0) {
computerVendor = "Unknown";
}
var computerModel = computer.model;
if (computerModel.length === 0) {
computerModel = "Unknown";
}
textToCopy += "Computer Vendor/Model: " + computerVendor + "/" + computerModel + "\n";
textToCopy += "Profiled Platform Tier: " + PlatformInfo.getTierProfiled() + "\n";
textToCopy += "OS Type: " + PlatformInfo.getOperatingSystemType() + "\n";
textToCopy += "CPU: " + PlatformInfo.getCPUBrand() + "\n";
textToCopy += "# CPUs: " + PlatformInfo.getNumCPUs() + "\n";
textToCopy += "# CPU Cores: " + PlatformInfo.getNumLogicalCores() + "\n";
textToCopy += "RAM: " + PlatformInfo.getTotalSystemMemoryMB() + " MB\n";
textToCopy += "GPU: " + PlatformInfo.getGraphicsCardType() + "\n";
textToCopy += "VR Hand Controllers: " + (PlatformInfo.hasRiftControllers() ? "Rift" : (PlatformInfo.hasViveControllers() ? "Vive" : "None"));
return textToCopy;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -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 {

View file

@ -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 {

View file

@ -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();
}
}
}
}

View file

@ -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 {

View file

@ -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
}
}
}

View file

@ -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;
}
}
}

View file

@ -0,0 +1,4 @@
module toolbars
StateImage 1.0 StateImage.qml
Toolbar 1.0 Toolbar.qml
ToolbarButton 1.0 ToolbarButton.qml

View file

@ -2775,7 +2775,6 @@ void Application::cleanupBeforeQuit() {
// destroy Audio so it and its threads have a chance to go down safely
// this must happen after QML, as there are unexplained audio crashes originating in qtwebengine
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "stop");
DependencyManager::destroy<AudioClient>();
DependencyManager::destroy<AudioScriptingInterface>();
@ -2935,8 +2934,10 @@ void Application::initializeGL() {
#if !defined(DISABLE_QML)
QStringList chromiumFlags;
// HACK: re-expose mic and camera to prevent crash on domain-change in chromium's media::FakeAudioInputStream::ReadAudioFromSource()
// Bug 21993: disable microphone and camera input
chromiumFlags << "--use-fake-device-for-media-stream";
//chromiumFlags << "--use-fake-device-for-media-stream";
// Disable signed distance field font rendering on ATI/AMD GPUs, due to
// https://highfidelity.manuscript.com/f/cases/13677/Text-showing-up-white-on-Marketplace-app
std::string vendor{ (const char*)glGetString(GL_VENDOR) };

View file

@ -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();

View file

@ -274,7 +274,9 @@ public slots:
protected:
AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& 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);

View file

@ -1416,6 +1416,10 @@ void MyAvatar::setEnableDebugDrawAnimPose(bool isEnabled) {
}
}
void MyAvatar::setDebugDrawAnimPoseName(QString poseName) {
_debugDrawAnimPoseName.set(poseName);
}
void MyAvatar::setEnableDebugDrawPosition(bool isEnabled) {
if (isEnabled) {
const glm::vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
@ -3086,15 +3090,26 @@ void MyAvatar::postUpdate(float deltaTime, const render::ScenePointer& scene) {
}
if (_enableDebugDrawAnimPose && animSkeleton) {
// build absolute AnimPoseVec from rig
AnimPoseVec absPoses;
const Rig& rig = _skeletonModel->getRig();
absPoses.reserve(rig.getJointStateCount());
for (int i = 0; i < rig.getJointStateCount(); i++) {
absPoses.push_back(AnimPose(rig.getJointTransform(i)));
const glm::vec4 CYAN(0.1f, 0.6f, 0.6f, 1.0f);
QString name = _debugDrawAnimPoseName.get();
if (name.isEmpty()) {
// build absolute AnimPoseVec from rig transforms. i.e. the same that are used for rendering.
absPoses.reserve(rig.getJointStateCount());
for (int i = 0; i < rig.getJointStateCount(); i++) {
absPoses.push_back(AnimPose(rig.getJointTransform(i)));
}
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, CYAN);
} else {
AnimNode::ConstPointer node = rig.findAnimNodeByName(name);
if (node) {
rig.buildAbsoluteRigPoses(node->getPoses(), absPoses);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, CYAN);
}
}
glm::vec4 cyan(0.1f, 0.6f, 0.6f, 1.0f);
AnimDebugDraw::getInstance().addAbsolutePoses("myAvatarAnimPoses", animSkeleton, absPoses, xform, cyan);
}
}
@ -6085,6 +6100,30 @@ QVariantList MyAvatar::getCollidingFlowJoints() {
return result;
}
int MyAvatar::getOverrideJointCount() const {
if (_skeletonModel) {
return _skeletonModel->getRig().getOverrideJointCount();
} else {
return 0;
}
}
bool MyAvatar::getFlowActive() const {
if (_skeletonModel) {
return _skeletonModel->getRig().getFlowActive();
} else {
return false;
}
}
bool MyAvatar::getNetworkGraphActive() const {
if (_skeletonModel) {
return _skeletonModel->getRig().getNetworkGraphActive();
} else {
return false;
}
}
void MyAvatar::initFlowFromFST() {
if (_skeletonModel->isLoaded()) {
auto &flowData = _skeletonModel->getHFMModel().flowData;

View file

@ -267,7 +267,7 @@ class MyAvatar : public Avatar {
* @property {number} analogPlusWalkSpeed - The walk speed of your avatar for the "AnalogPlus" control scheme.
* <p><strong>Warning:</strong> Setting this value also sets the value of <code>analogPlusSprintSpeed</code> to twice
* the value.</p>
* @property {number} analogPlusSprintSpeed - The sprint speed of your avatar for the "AnalogPlus" control scheme.
* @property {number} analogPlusSprintSpeed - The sprint (run) speed of your avatar for the "AnalogPlus" control scheme.
* @property {MyAvatar.SitStandModelType} userRecenterModel - Controls avatar leaning and recentering behavior.
* @property {number} isInSittingState - <code>true</code> if your avatar is sitting (avatar leaning is disabled,
* recenntering is enabled), <code>false</code> if it is standing (avatar leaning is enabled, and avatar recenters if it
@ -1835,6 +1835,10 @@ public:
*/
Q_INVOKABLE QVariantList getCollidingFlowJoints();
int getOverrideJointCount() const;
bool getFlowActive() const;
bool getNetworkGraphActive() const;
public slots:
/**jsdoc
@ -2018,12 +2022,20 @@ public slots:
void setEnableDebugDrawDefaultPose(bool isEnabled);
/**jsdoc
* Displays animation debug graphics.
* Displays animation debug graphics. By default it shows the animation poses used for rendering.
* However, the property MyAvatar.setDebugDrawAnimPoseName can be used to draw a specific animation node.
* @function MyAvatar.setEnableDebugDrawAnimPose
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
*/
void setEnableDebugDrawAnimPose(bool isEnabled);
/**jsdoc
* If set it determines which animation debug graphics to draw, when MyAvatar.setEnableDebugDrawAnimPose is set to true.
* @function MyAvatar.setDebugDrawAnimPoseName
* @param {boolean} enabled - <code>true</code> to show the debug graphics, <code>false</code> to hide.
*/
void setDebugDrawAnimPoseName(QString poseName);
/**jsdoc
* Displays position debug graphics.
* @function MyAvatar.setEnableDebugDrawPosition
@ -2190,33 +2202,35 @@ signals:
void audioListenerModeChanged();
/**jsdoc
* Notifies when the analogPlusWalkSpeed value is changed.
* Triggered when the walk speed set for the "AnalogPlus" control scheme changes.
* @function MyAvatar.analogPlusWalkSpeedChanged
* @param {float} value - the new avatar walk speed
* @param {number} speed - The new walk speed set for the "AnalogPlus" control scheme.
* @returns {Signal}
*/
void analogPlusWalkSpeedChanged(float value);
/**jsdoc
* Notifies when the analogPlusSprintSpeed value is changed.
* Triggered when the sprint (run) speed set for the "AnalogPlus" control scheme changes.
* @function MyAvatar.analogPlusSprintSpeedChanged
* @param {float} value - the new avatar sprint speed
* @param {number} speed - The new sprint speed set for the "AnalogPlus" control scheme.
* @returns {Signal}
*/
void analogPlusSprintSpeedChanged(float value);
/**jsdoc
* Notifies when the sprintSpeed value is changed.
* Triggered when the sprint (run) speed set for the current control scheme (see
* {@link MyAvatar.getControlScheme|getControlScheme}) changes.
* @function MyAvatar.sprintSpeedChanged
* @param {float} value - the new avatar sprint speed
* @param {number} speed -The new sprint speed set for the current control scheme.
* @returns {Signal}
*/
void sprintSpeedChanged(float value);
/**jsdoc
* Notifies when the walkBackwardSpeed value is changed.
* Triggered when the walk backward speed set for the current control scheme (see
* {@link MyAvatar.getControlScheme|getControlScheme}) changes.
* @function MyAvatar.walkBackwardSpeedChanged
* @param {float} value - the new avatar walk backward speed
* @param {number} speed - The new walk backward speed set for the current control scheme.
* @returns {Signal}
*/
void walkBackwardSpeedChanged(float value);
@ -2666,6 +2680,8 @@ private:
bool _enableDebugDrawIKChains { false };
bool _enableDebugDrawDetailedCollision { false };
ThreadSafeValueCache<QString> _debugDrawAnimPoseName;
mutable bool _cauterizationNeedsUpdate { false }; // do we need to scan children and update their "cauterized" state?
AudioListenerMode _audioListenerMode;

View file

@ -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) {

View file

@ -48,7 +48,6 @@ public:
DetailedMotionState* createDetailedMotionStateForJoint(int32_t jointIndex);
std::vector<DetailedMotionState*>& getDetailedMotionStates() { return _detailedMotionStates; }
void clearDetailedMotionStates();
void resetDetailedMotionStates();
void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction);

View file

@ -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;
}
}

View file

@ -54,7 +54,7 @@ public:
const btCollisionShape* createCollisionShape(int32_t jointIndex, bool& isBound, std::vector<int32_t>& boundJoints);
std::vector<DetailedMotionState*>& 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<OtherAvatar>;

View file

@ -192,7 +192,7 @@ QString PlatformInfoScriptingInterface::getDisplay(int index) {
}
QString PlatformInfoScriptingInterface::getMemory() {
auto desc = platform::getMemory(0);
auto desc = platform::getMemory();
return QString(desc.dump().c_str());
}
@ -201,6 +201,10 @@ QString PlatformInfoScriptingInterface::getComputer() {
return QString(desc.dump().c_str());
}
QString PlatformInfoScriptingInterface::getPlatform() {
auto desc = platform::getAll();
return QString(desc.dump().c_str());
}
PlatformInfoScriptingInterface::PlatformTier PlatformInfoScriptingInterface::getTierProfiled() {
return (PlatformInfoScriptingInterface::PlatformTier) platform::Profiler::profilePlatform();

View file

@ -51,6 +51,8 @@ public slots:
* Gets the operating system type.
* @function PlatformInfo.getOperatingSystemType
* @returns {string} <code>"WINDOWS"</code>, <code>"MACOS"</code>, or <code>"UNKNOWN"</code>.
* @deprecated This function is deprecated and will be removed.
* use getComputer()["OS"] instead
*/
QString getOperatingSystemType();
@ -61,6 +63,10 @@ public slots:
* @example <caption>Report the CPU being used.</caption>
* print("CPU: " + PlatformInfo.getCPUBrand());
* // Example: Intel(R) Core(TM) i7-7820HK CPU @ 2.90GHz
* @deprecated This function is deprecated and will be removed.
* use getNumCPUs() to know the number of CPUs in the hardware, at least one is expected
* use getCPU(0)["vendor"] to get the brand of the vendor
* use getCPU(0)["model"] to get the model name of the cpu
*/
QString getCPUBrand();
@ -68,6 +74,8 @@ public slots:
* Gets the number of logical CPU cores.
* @function PlatformInfo.getNumLogicalCores
* @returns {number} The number of logical CPU cores.
* @deprecated This function is deprecated and will be removed.
* use getCPU(0)["numCores"] instead
*/
unsigned int getNumLogicalCores();
@ -75,6 +83,8 @@ public slots:
* Returns the total system memory in megabytes.
* @function PlatformInfo.getTotalSystemMemoryMB
* @returns {number} The total system memory in megabytes.
* @deprecated This function is deprecated and will be removed.
* use getMemory()["memTotal"] instead
*/
int getTotalSystemMemoryMB();
@ -82,6 +92,10 @@ public slots:
* Gets the graphics card type.
* @function PlatformInfo.getGraphicsCardType
* @returns {string} The graphics card type.
* @deprecated This function is deprecated and will be removed.
* use getNumGPUs() to know the number of GPUs in the hardware, at least one is expected
* use getGPU(0)["vendor"] to get the brand of the vendor
* use getGPU(0)["model"] to get the model name of the gpu
*/
QString getGraphicsCardType();
@ -141,7 +155,7 @@ public slots:
/**jsdoc
* Get the description of the GPU at the index parameter
* expected fields are:
* - gpuVendor...
* - vendor, model...
* @param index The index of the GPU of the platform
* @function PlatformInfo.getGPU
* @returns {string} The GPU description json field
@ -183,6 +197,14 @@ public slots:
*/
QString getComputer();
/**jsdoc
* Get the complete description of the Platform as an aggregated Json
* The expected object description is:
* { "computer": {...}, "memory": {...}, "cpus": [{...}, ...], "gpus": [{...}, ...], "displays": [{...}, ...] }
* @function PlatformInfo.getPlatform
* @returns {string} The Platform description json field
*/
QString getPlatform();
/**jsdoc
* Get the Platform TIer profiled on startup of the Computer

View file

@ -94,6 +94,21 @@ void AnimStats::updateStats(bool force) {
}
emit walkingTextChanged();
// print current overrideJointText
int overrideJointCount = myAvatar->getOverrideJointCount();
_overrideJointText = QString("Override Joint Count: %1").arg(overrideJointCount);
emit overrideJointTextChanged();
// print current flowText
bool flowActive = myAvatar->getFlowActive();
_flowText = QString("Flow: %1").arg(flowActive ? "enabled" : "disabled");
emit flowTextChanged();
// print current networkGraphText
bool networkGraphActive = myAvatar->getNetworkGraphActive();
_networkGraphText = QString("Network Graph: %1").arg(networkGraphActive ? "enabled" : "disabled");
emit networkGraphTextChanged();
// update animation debug alpha values
QStringList newAnimAlphaValues;
qint64 now = usecTimestampNow();

View file

@ -25,6 +25,9 @@ class AnimStats : public QQuickItem {
Q_PROPERTY(QString recenterText READ recenterText NOTIFY recenterTextChanged)
Q_PROPERTY(QString sittingText READ sittingText NOTIFY sittingTextChanged)
Q_PROPERTY(QString walkingText READ walkingText NOTIFY walkingTextChanged)
Q_PROPERTY(QString overrideJointText READ overrideJointText NOTIFY overrideJointTextChanged)
Q_PROPERTY(QString flowText READ flowText NOTIFY flowTextChanged)
Q_PROPERTY(QString networkGraphText READ networkGraphText NOTIFY networkGraphTextChanged)
public:
static AnimStats* getInstance();
@ -43,6 +46,9 @@ public:
QString recenterText() const { return _recenterText; }
QString sittingText() const { return _sittingText; }
QString walkingText() const { return _walkingText; }
QString overrideJointText() const { return _overrideJointText; }
QString flowText() const { return _flowText; }
QString networkGraphText() const { return _networkGraphText; }
public slots:
void forceUpdateStats() { updateStats(true); }
@ -58,6 +64,9 @@ signals:
void recenterTextChanged();
void sittingTextChanged();
void walkingTextChanged();
void overrideJointTextChanged();
void flowTextChanged();
void networkGraphTextChanged();
private:
QStringList _animAlphaValues;
@ -76,6 +85,9 @@ private:
QString _recenterText;
QString _sittingText;
QString _walkingText;
QString _overrideJointText;
QString _flowText;
QString _networkGraphText;
};
#endif // hifi_AnimStats_h

View file

@ -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")

View file

@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<string>${APP_NAME}</string>
<key>CFBundleIconFile</key>
<string>${MACOSX_BUNDLE_ICON_FILE}</string>
<key>CFBundleIdentifier</key>
@ -29,7 +29,9 @@
<string>Window</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleName</key>
<string>${MACOSX_BUNDLE_BUNDLE_NAME}</string>
<key>CFBundleDisplayName</key>
<string>HQ Launcher</string>
<string>CFBundleName</string>
</dict>
</plist>

View file

@ -14,16 +14,26 @@
NSURLSession* session = [NSURLSession sharedSession];
NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"Latest Build Request error: %@", error);
NSLog(@"Latest Build Request Data: %@", data);
NSHTTPURLResponse *ne = (NSHTTPURLResponse *)response;
NSLog(@"Latest Build Request Response: %ld", [ne statusCode]);
Launcher* sharedLauncher = [Launcher sharedLauncher];
NSLog(@"credentials request finished");
NSMutableData* webData = [NSMutableData data];
[webData appendData:data];
NSString* jsonString = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[data length] encoding:NSUTF8StringEncoding];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
NSLog(@"Latest Build Request -> json string: %@", jsonString);
NSError *jsonError = nil;
id json = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&jsonError];
if (jsonError) {
NSLog(@"Latest Build request: Failed to convert Json to data");
}
NSFileManager* fileManager = [NSFileManager defaultManager];
NSArray *values = [json valueForKey:@"results"];
NSArray *values = [json valueForKey:@"results"];
NSDictionary *value = [values objectAtIndex:0];
@ -37,10 +47,15 @@
dispatch_async(dispatch_get_main_queue(), ^{
Settings* settings = [Settings sharedSettings];
NSInteger currentVersion = [settings latestBuildVersion];
NSLog(@"Latest Build Request -> does build directory exist: %@", appDirectoryExist ? @"TRUE" : @"FALSE");
NSLog(@"Latest Build Request -> current version: %ld", currentVersion);
NSLog(@"Latest Build Request -> latest version: %ld", buildNumber.integerValue);
NSLog(@"Latest Build Request -> mac url: %@", macInstallerUrl);
BOOL latestVersionAvailable = (currentVersion != buildNumber.integerValue);
[[Settings sharedSettings] buildVersion:buildNumber.integerValue];
BOOL shouldDownloadInterface = (latestVersionAvailable || !appDirectoryExist);
NSLog(@"Latest Build Request -> SHOULD DOWNLOAD: %@", shouldDownloadInterface ? @"TRUE" : @"FALSE");
[sharedLauncher shouldDownloadLatestBuild:shouldDownloadInterface :macInstallerUrl];
});
}];

View file

@ -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!"];

View file

@ -213,6 +213,9 @@ BOOL CLauncherDlg::getHQInfo(const CString& orgname) {
CString lowerOrgName = orgname;
lowerOrgName.MakeLower();
LauncherUtils::hMac256(lowerOrgName, LAUNCHER_HMAC_SECRET, hash);
CString msg;
msg.Format(_T("Calculated hash: \"%s\" => \"%s\""), lowerOrgName, hash);
theApp._manager.addToLog(msg);
return theApp._manager.readOrganizationJSON(hash) == LauncherUtils::ResponseError::NoError;
}

View file

@ -427,6 +427,11 @@ BOOL LauncherManager::extractApplication() {
LauncherUtils::cStringToStd(installPath), [&](int type, int size) {
onZipExtracted((ZipType)type, size);
});
if (success) {
addToLog(_T("Created thread for unzipping application."));
} else {
addToLog(_T("Failed to create thread for unzipping application."));
}
return success;
}
@ -449,6 +454,11 @@ BOOL LauncherManager::installContent() {
LauncherUtils::cStringToStd(contentPath), [&](int type, int size) {
onZipExtracted((ZipType)type, size);
});
if (success) {
addToLog(_T("Created thread for unzipping content."));
} else {
addToLog(_T("Failed to create thread for unzipping content."));
}
return success;
}

View file

@ -16,6 +16,7 @@
#pragma comment(lib, "winhttp")
#include "LauncherApp.h"
#include "LauncherUtils.h"
CString LauncherUtils::urlEncodeString(const CString& url) {
@ -183,6 +184,17 @@ LauncherUtils::ResponseError LauncherUtils::makeHTTPCall(const CString& callerNa
BOOL haveContentLength = WinHttpQueryHeaders(hrequest, WINHTTP_QUERY_CONTENT_LENGTH, NULL,
&szContentLength, &bufferBytes, &dwHeaderIndex);
DWORD statusCode;
DWORD statusCodeSize = sizeof(statusCode);
WinHttpQueryHeaders(hrequest,
WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
NULL,
&statusCode, &statusCodeSize, WINHTTP_NO_HEADER_INDEX);
CString msg;
msg.Format(_T("Status code response (%s%s): %lu"), mainUrl, dirUrl, statusCode);
theApp._manager.addToLog(msg);
DWORD dwContentLength;
if (haveContentLength) {
dwContentLength = _wtoi(szContentLength);
@ -225,19 +237,37 @@ BOOL LauncherUtils::getFont(const CString& fontName, int fontSize, bool isBold,
}
uint64_t LauncherUtils::extractZip(const std::string& zipFile, const std::string& path, std::vector<std::string>& files) {
{
CString msg;
msg.Format(_T("Reading zip file %s, extracting to %s"), CString(zipFile.c_str()), CString(path.c_str()));
theApp._manager.addToLog(msg);
}
mz_zip_archive zip_archive;
memset(&zip_archive, 0, sizeof(zip_archive));
auto status = mz_zip_reader_init_file(&zip_archive, zipFile.c_str(), 0);
if (!status) return 0;
if (!status) {
auto zip_error = mz_zip_get_last_error(&zip_archive);
auto zip_error_msg = mz_zip_get_error_string(zip_error);
CString msg;
msg.Format(_T("Failed to initialize miniz: %d %s"), zip_error, CString(zip_error_msg));
theApp._manager.addToLog(msg);
return 0;
}
int fileCount = (int)mz_zip_reader_get_num_files(&zip_archive);
if (fileCount == 0) {
theApp._manager.addToLog(_T("Zip archive has a file count of 0"));
mz_zip_reader_end(&zip_archive);
return 0;
}
mz_zip_archive_file_stat file_stat;
if (!mz_zip_reader_file_stat(&zip_archive, 0, &file_stat)) {
theApp._manager.addToLog(_T("Zip archive cannot be stat'd"));
mz_zip_reader_end(&zip_archive);
return 0;
}
@ -263,6 +293,12 @@ uint64_t LauncherUtils::extractZip(const std::string& zipFile, const std::string
}
}
{
CString msg;
msg.Format(_T("Done unzipping archive, total size: %llu"), totalSize);
theApp._manager.addToLog(msg);
}
// Close the archive, freeing any resources it was using
mz_zip_reader_end(&zip_archive);
return totalSize;

View file

@ -10,10 +10,13 @@
#include "AnimClip.h"
#include <assert.h>
#include "GLMHelpers.h"
#include "AnimationLogging.h"
#include "AnimUtil.h"
AnimClip::AnimClip(const QString& id, const QString& url, float startFrame, float endFrame, float timeScale, bool loopFlag, bool mirrorFlag) :
AnimNode(AnimNode::Type::Clip, id),
_startFrame(startFrame),
@ -107,6 +110,19 @@ static std::vector<int> buildJointIndexMap(const AnimSkeleton& dstSkeleton, cons
return jointIndexMap;
}
#ifdef USE_CUSTOM_ASSERT
#undef ASSERT
#define ASSERT(x) \
do { \
if (!(x)) { \
int* bad_ptr = 0; \
*bad_ptr = 0x0badf00d; \
} \
} while (0)
#else
#define ASSERT assert
#endif
void AnimClip::copyFromNetworkAnim() {
assert(_networkAnim && _networkAnim->isLoaded() && _skeleton);
_anim.clear();
@ -165,11 +181,14 @@ void AnimClip::copyFromNetworkAnim() {
for (int frame = 0; frame < animFrameCount; frame++) {
const HFMAnimationFrame& animFrame = animModel.animationFrames[frame];
ASSERT(frame >= 0 && frame < (int)animModel.animationFrames.size());
// extract the full rotations from the animFrame (including pre and post rotations from the animModel).
std::vector<glm::quat> animRotations;
animRotations.reserve(animJointCount);
for (int i = 0; i < animJointCount; i++) {
ASSERT(i >= 0 && i < (int)animModel.joints.size());
ASSERT(i >= 0 && i < (int)animFrame.rotations.size());
animRotations.push_back(animModel.joints[i].preRotation * animFrame.rotations[i] * animModel.joints[i].postRotation);
}
@ -180,10 +199,12 @@ void AnimClip::copyFromNetworkAnim() {
std::vector<glm::quat> avatarRotations;
avatarRotations.reserve(avatarJointCount);
for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) {
ASSERT(avatarJointIndex >= 0 && avatarJointIndex < (int)avatarToAnimJointIndexMap.size());
int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex];
if (animJointIndex >= 0) {
// This joint is in both animation and avatar.
// Set the absolute rotation directly
ASSERT(animJointIndex >= 0 && animJointIndex < (int)animRotations.size());
avatarRotations.push_back(animRotations[animJointIndex]);
} else {
// This joint is NOT in the animation at all.
@ -192,6 +213,7 @@ void AnimClip::copyFromNetworkAnim() {
glm::quat avatarParentAbsoluteRot;
int avatarParentJointIndex = avatarSkeleton->getParentIndex(avatarJointIndex);
if (avatarParentJointIndex >= 0) {
ASSERT(avatarParentJointIndex >= 0 && avatarParentJointIndex < (int)avatarRotations.size());
avatarParentAbsoluteRot = avatarRotations[avatarParentJointIndex];
}
avatarRotations.push_back(avatarParentAbsoluteRot * avatarRelativeDefaultRot);
@ -201,6 +223,7 @@ void AnimClip::copyFromNetworkAnim() {
// convert avatar rotations into relative frame
avatarSkeleton->convertAbsoluteRotationsToRelative(avatarRotations);
ASSERT(frame >= 0 && frame < (int)_anim.size());
_anim[frame].reserve(avatarJointCount);
for (int avatarJointIndex = 0; avatarJointIndex < avatarJointCount; avatarJointIndex++) {
const AnimPose& avatarDefaultPose = avatarSkeleton->getRelativeDefaultPose(avatarJointIndex);
@ -209,12 +232,15 @@ void AnimClip::copyFromNetworkAnim() {
glm::vec3 relativeScale = avatarDefaultPose.scale();
glm::vec3 relativeTranslation;
ASSERT(avatarJointIndex >= 0 && avatarJointIndex < (int)avatarToAnimJointIndexMap.size());
int animJointIndex = avatarToAnimJointIndexMap[avatarJointIndex];
if (animJointIndex >= 0) {
// This joint is in both animation and avatar.
ASSERT(animJointIndex >= 0 && animJointIndex < (int)animFrame.translations.size());
const glm::vec3& animTrans = animFrame.translations[animJointIndex];
// retarget translation from animation to avatar
ASSERT(animJointIndex >= 0 && animJointIndex < (int)animModel.animationFrames[0].translations.size());
const glm::vec3& animZeroTrans = animModel.animationFrames[0].translations[animJointIndex];
relativeTranslation = avatarDefaultPose.trans() + boneLengthScale * (animTrans - animZeroTrans);
} else {
@ -224,6 +250,7 @@ void AnimClip::copyFromNetworkAnim() {
}
// build the final pose
ASSERT(avatarJointIndex >= 0 && avatarJointIndex < (int)avatarRotations.size());
_anim[frame].push_back(AnimPose(relativeScale, avatarRotations[avatarJointIndex], relativeTranslation));
}
}

View file

@ -98,6 +98,8 @@ public:
return result;
}
const AnimPoseVec& getPoses() const { return getPosesInternal(); }
protected:
virtual void setCurrentFrameInternal(float frame) {}

View file

@ -2025,6 +2025,9 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
if (params.isTalking) {
if (_talkIdleInterpTime < 1.0f) {
_talkIdleInterpTime += dt / TOTAL_EASE_IN_TIME;
if (_talkIdleInterpTime > 1.0f) {
_talkIdleInterpTime = 1.0f;
}
float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f;
_animVars.set("idleOverlayAlpha", easeOutInValue);
} else {
@ -2033,6 +2036,9 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo
} else {
if (_talkIdleInterpTime < 1.0f) {
_talkIdleInterpTime += dt / TOTAL_EASE_OUT_TIME;
if (_talkIdleInterpTime > 1.0f) {
_talkIdleInterpTime = 1.0f;
}
float easeOutInValue = _talkIdleInterpTime < 0.5f ? 4.0f * powf(_talkIdleInterpTime, 3.0f) : 4.0f * powf((_talkIdleInterpTime - 1.0f), 3.0f) + 1.0f;
float talkAlpha = 1.0f - easeOutInValue;
_animVars.set("idleOverlayAlpha", talkAlpha);
@ -2232,6 +2238,14 @@ void Rig::initAnimGraph(const QUrl& url) {
}
}
AnimNode::ConstPointer Rig::findAnimNodeByName(const QString& name) const {
if (_animNode) {
return _animNode->findByName(name);
} else {
return nullptr;
}
}
bool Rig::getModelRegistrationPoint(glm::vec3& modelRegistrationPointOut) const {
if (_animSkeleton && _rootJointIndex >= 0) {
modelRegistrationPointOut = _geometryOffset * -_animSkeleton->getAbsoluteDefaultPose(_rootJointIndex).trans();
@ -2258,7 +2272,7 @@ void Rig::applyOverridePoses() {
}
}
void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) {
void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) const {
DETAILED_PERFORMANCE_TIMER("buildAbsolute");
if (!_animSkeleton) {
return;
@ -2279,6 +2293,24 @@ void Rig::buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& a
}
}
int Rig::getOverrideJointCount() const {
int count = 0;
for (size_t i = 0; i < _internalPoseSet._overrideFlags.size(); i++) {
if (_internalPoseSet._overrideFlags[i]) {
count++;
}
}
return count;
}
bool Rig::getFlowActive() const {
return _internalFlow.getActive();
}
bool Rig::getNetworkGraphActive() const {
return _sendNetworkNode;
}
glm::mat4 Rig::getJointTransform(int jointIndex) const {
static const glm::mat4 IDENTITY;
if (isIndexValid(jointIndex)) {

View file

@ -196,6 +196,7 @@ public:
void initAnimGraph(const QUrl& url);
AnimNode::ConstPointer getAnimNode() const { return _animNode; }
AnimNode::ConstPointer findAnimNodeByName(const QString& name) const;
AnimSkeleton::ConstPointer getAnimSkeleton() const { return _animSkeleton; }
QScriptValue addAnimationStateHandler(QScriptValue handler, QScriptValue propertiesList);
void removeAnimationStateHandler(QScriptValue handler);
@ -243,7 +244,11 @@ public:
Flow& getFlow() { return _internalFlow; }
float getUnscaledEyeHeight() const;
void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut) const;
int getOverrideJointCount() const;
bool getFlowActive() const;
bool getNetworkGraphActive() const;
signals:
void onLoadComplete();
@ -252,7 +257,6 @@ protected:
bool isIndexValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); }
void updateAnimationStateHandlers();
void applyOverridePoses();
void buildAbsoluteRigPoses(const AnimPoseVec& relativePoses, AnimPoseVec& absolutePosesOut);
void updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headMatrix);
void updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnabled, bool hipsEstimated,

View file

@ -375,6 +375,9 @@ AudioClient::AudioClient() :
}
AudioClient::~AudioClient() {
stop();
if (_codec && _encoder) {
_codec->releaseEncoder(_encoder);
_encoder = nullptr;

View file

@ -35,16 +35,6 @@ static const double SQRT2 = 1.41421356237309504880;
static const double FIXQ31 = 2147483648.0;
static const double FIXQ32 = 4294967296.0;
// Round an integer to the next power-of-two, at compile time.
// VS2013 does not support constexpr so macros are used instead.
#define SETBITS0(x) (x)
#define SETBITS1(x) (SETBITS0(x) | (SETBITS0(x) >> 1))
#define SETBITS2(x) (SETBITS1(x) | (SETBITS1(x) >> 2))
#define SETBITS3(x) (SETBITS2(x) | (SETBITS2(x) >> 4))
#define SETBITS4(x) (SETBITS3(x) | (SETBITS3(x) >> 8))
#define SETBITS5(x) (SETBITS4(x) | (SETBITS4(x) >> 16))
#define NEXTPOW2(x) (SETBITS5((x) - 1) + 1)
//
// Allpass delay modulation
//
@ -111,6 +101,18 @@ static const int M_AP19 = 113;
static const int M_AP20 = 107;
static const int M_AP21 = 127;
// Round an integer to the next power-of-two, at compile time
constexpr uint32_t NEXTPOW2(uint32_t n) {
n -= 1;
n |= (n >> 1);
n |= (n >> 2);
n |= (n >> 4);
n |= (n >> 8);
n |= (n >> 16);
n += 1;
return n;
}
//
// Filter design tools using analog-matched response.
// All filter types approximate the s-plane response, including cutoff > Nyquist.
@ -1796,6 +1798,18 @@ void AudioReverb::render(float** inputs, float** outputs, int numFrames) {
#include <emmintrin.h>
// unaligned load/store without undefined behavior
static inline __m128i mm_loadu_si32(void const* mem_addr) {
int32_t temp;
memcpy(&temp, mem_addr, sizeof(int32_t));
return _mm_cvtsi32_si128(temp);
}
static inline void mm_storeu_si32(void* mem_addr, __m128i a) {
int32_t temp = _mm_cvtsi128_si32(a);
memcpy(mem_addr, &temp, sizeof(int32_t));
}
// convert int16_t to float, deinterleave stereo
void AudioReverb::convertInput(const int16_t* input, float** outputs, int numFrames) {
__m128 scale = _mm_set1_ps(1/32768.0f);
@ -1816,7 +1830,7 @@ void AudioReverb::convertInput(const int16_t* input, float** outputs, int numFra
_mm_storeu_ps(&outputs[1][i], f1);
}
for (; i < numFrames; i++) {
__m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[2*i]);
__m128i a0 = mm_loadu_si32((__m128i*)&input[2*i]);
__m128i a1 = a0;
// deinterleave and sign-extend
@ -1887,7 +1901,7 @@ void AudioReverb::convertOutput(float** inputs, int16_t* output, int numFrames)
// interleave
a0 = _mm_unpacklo_epi16(a0, a1);
*(int32_t*)&output[2*i] = _mm_cvtsi128_si32(a0);
mm_storeu_si32((__m128i*)&output[2*i], a0);
}
}

View file

@ -793,6 +793,18 @@ int AudioSRC::multirateFilter4(const float* input0, const float* input1, const f
#include <emmintrin.h> // SSE2
// unaligned load/store without undefined behavior
static inline __m128i mm_loadu_si32(void const* mem_addr) {
int32_t temp;
memcpy(&temp, mem_addr, sizeof(int32_t));
return _mm_cvtsi32_si128(temp);
}
static inline void mm_storeu_si32(void* mem_addr, __m128i a) {
int32_t temp = _mm_cvtsi128_si32(a);
memcpy(mem_addr, &temp, sizeof(int32_t));
}
// convert int16_t to float, deinterleave stereo
void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames) {
__m128 scale = _mm_set1_ps(1/32768.0f);
@ -839,7 +851,7 @@ void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames
_mm_storeu_ps(&outputs[1][i], f1);
}
for (; i < numFrames; i++) {
__m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[2*i]);
__m128i a0 = mm_loadu_si32((__m128i*)&input[2*i]);
__m128i a1 = a0;
// deinterleave and sign-extend
@ -878,9 +890,9 @@ void AudioSRC::convertInput(const int16_t* input, float** outputs, int numFrames
_mm_storeu_ps(&outputs[3][i], _mm_shuffle_ps(f1, f3, _MM_SHUFFLE(3,1,3,1)));
}
for (; i < numFrames; i++) {
__m128i a0 = _mm_cvtsi32_si128(*(int32_t*)&input[4*i+0]);
__m128i a0 = mm_loadu_si32((__m128i*)&input[4*i+0]);
__m128i a1 = a0;
__m128i a2 = _mm_cvtsi32_si128(*(int32_t*)&input[4*i+2]);
__m128i a2 = mm_loadu_si32((__m128i*)&input[4*i+2]);
__m128i a3 = a2;
// deinterleave and sign-extend
@ -986,7 +998,7 @@ void AudioSRC::convertOutput(float** inputs, int16_t* output, int numFrames) {
// interleave
a0 = _mm_unpacklo_epi16(a0, a1);
*(int32_t*)&output[2*i] = _mm_cvtsi128_si32(a0);
mm_storeu_si32((__m128i*)&output[2*i], a0);
}
} else if (_numChannels == 4) {

View file

@ -109,6 +109,23 @@ bool Basic2DWindowOpenGLDisplayPlugin::internalActivate() {
return Parent::internalActivate();
}
gpu::PipelinePointer Basic2DWindowOpenGLDisplayPlugin::getCompositeScenePipeline() {
#if defined(Q_OS_ANDROID)
return _linearToSRGBPipeline;
#else
return _SRGBToLinearPipeline;
#endif
}
gpu::Element Basic2DWindowOpenGLDisplayPlugin::getCompositeFBColorSpace() {
#if defined(Q_OS_ANDROID)
return gpu::Element::COLOR_SRGBA_32;
#else
return gpu::Element::COLOR_RGBA_32;
#endif
}
void Basic2DWindowOpenGLDisplayPlugin::compositeExtra() {
#if defined(Q_OS_ANDROID)
auto& virtualPadManager = VirtualPad::Manager::instance();

View file

@ -37,6 +37,9 @@ public:
virtual void pluginUpdate() override {};
virtual gpu::PipelinePointer getCompositeScenePipeline() override;
virtual gpu::Element getCompositeFBColorSpace() override;
protected:
mutable bool _isThrottled = false;

View file

@ -48,12 +48,16 @@
#include "CompositorHelper.h"
#include "Logging.h"
#include "RefreshRateController.h"
using namespace shader::gpu::program;
extern QThread* RENDER_THREAD;
class PresentThread : public QThread, public Dependency {
using Mutex = std::mutex;
using Condition = std::condition_variable;
using Lock = std::unique_lock<Mutex>;
public:
PresentThread() {
@ -380,57 +384,45 @@ void OpenGLDisplayPlugin::customizeContext() {
}
}
if (!_presentPipeline) {
if (!_drawTexturePipeline) {
gpu::StatePointer blendState = gpu::StatePointer(new gpu::State());
blendState->setDepthTest(gpu::State::DepthTest(false));
blendState->setBlendFunction(true,
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD,
gpu::State::INV_SRC_ALPHA,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD,
gpu::State::ONE);
gpu::StatePointer scissorState = gpu::StatePointer(new gpu::State());
scissorState->setDepthTest(gpu::State::DepthTest(false));
scissorState->setScissorEnable(true);
{
#ifdef Q_OS_ANDROID
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaLinearToSRGB);
#else
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture);
#endif
_simplePipeline = gpu::Pipeline::create(program, scissorState);
}
{
#ifdef Q_OS_ANDROID
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaLinearToSRGB);
#else
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaSRGBToLinear);
#endif
_presentPipeline = gpu::Pipeline::create(program, scissorState);
}
_drawTexturePipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), scissorState);
{
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture);
_hudPipeline = gpu::Pipeline::create(program, blendState);
}
{
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureMirroredX);
_mirrorHUDPipeline = gpu::Pipeline::create(program, blendState);
}
_linearToSRGBPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaLinearToSRGB), scissorState);
{
gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTransformedTexture);
_cursorPipeline = gpu::Pipeline::create(program, blendState);
}
_SRGBToLinearPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureGammaSRGBToLinear), scissorState);
_hudPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTexture), blendState);
_mirrorHUDPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTextureMirroredX), blendState);
_cursorPipeline = gpu::Pipeline::create(gpu::Shader::createProgram(DrawTransformedTexture), blendState);
}
updateCompositeFramebuffer();
}
void OpenGLDisplayPlugin::uncustomizeContext() {
_presentPipeline.reset();
_cursorPipeline.reset();
_drawTexturePipeline.reset();
_linearToSRGBPipeline.reset();
_SRGBToLinearPipeline.reset();
_hudPipeline.reset();
_mirrorHUDPipeline.reset();
_cursorPipeline.reset();
_compositeFramebuffer.reset();
withPresentThreadLock([&] {
_currentFrame.reset();
_lastFrame = nullptr;
@ -535,11 +527,9 @@ void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::Textur
batch.setStateScissorRect(scissor);
batch.setViewportTransform(viewport);
batch.setResourceTexture(0, texture);
#ifndef USE_GLES
batch.setPipeline(_presentPipeline);
#else
batch.setPipeline(_simplePipeline);
#endif
batch.setPipeline(_drawTexturePipeline);
batch.draw(gpu::TRIANGLE_STRIP, 4);
if (copyFbo) {
gpu::Vec4i copyFboRect(0, 0, copyFbo->getWidth(), copyFbo->getHeight());
@ -603,9 +593,10 @@ std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> OpenGL
hudEyeViewports[eye] = eyeViewport(eye);
});
return [=](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) {
if (hudPipeline && hudTexture) {
auto pipeline = mirror ? hudMirrorPipeline : hudPipeline;
if (pipeline && hudTexture) {
batch.enableStereo(false);
batch.setPipeline(mirror ? hudMirrorPipeline : hudPipeline);
batch.setPipeline(pipeline);
batch.setResourceTexture(0, hudTexture);
if (hudStereo) {
for_each_eye([&](Eye eye) {
@ -644,6 +635,11 @@ void OpenGLDisplayPlugin::compositePointer() {
});
}
// Overridden by Basic2DWindowDisplayPlugin and OculusDisplayPlugin
gpu::PipelinePointer OpenGLDisplayPlugin::getCompositeScenePipeline() {
return _drawTexturePipeline;
}
void OpenGLDisplayPlugin::compositeScene() {
render([&](gpu::Batch& batch) {
batch.enableStereo(false);
@ -652,7 +648,7 @@ void OpenGLDisplayPlugin::compositeScene() {
batch.setStateScissorRect(ivec4(uvec2(), _compositeFramebuffer->getSize()));
batch.resetViewTransform();
batch.setProjectionTransform(mat4());
batch.setPipeline(_simplePipeline);
batch.setPipeline(getCompositeScenePipeline());
batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0));
batch.draw(gpu::TRIANGLE_STRIP, 4);
});
@ -666,17 +662,6 @@ void OpenGLDisplayPlugin::compositeLayers() {
compositeScene();
}
#ifdef HIFI_ENABLE_NSIGHT_DEBUG
if (false) // do not draw the HUD if running nsight debug
#endif
{
PROFILE_RANGE_EX(render_detail, "handleHUDBatch", 0xff0077ff, (uint64_t)presentCount())
auto hudOperator = getHUDOperator();
withPresentThreadLock([&] {
_hudOperator = hudOperator;
});
}
{
PROFILE_RANGE_EX(render_detail, "compositeExtra", 0xff0077ff, (uint64_t)presentCount())
compositeExtra();
@ -924,11 +909,17 @@ void OpenGLDisplayPlugin::render(std::function<void(gpu::Batch& batch)> f) {
OpenGLDisplayPlugin::~OpenGLDisplayPlugin() {
}
// Added this to allow desktop composite framebuffer to be RGBA while mobile is SRGBA
// Overridden by Basic2DWindowDisplayPlugin
// FIXME: Eventually it would be ideal to have both framebuffers be of the same type
gpu::Element OpenGLDisplayPlugin::getCompositeFBColorSpace() {
return gpu::Element::COLOR_RGBA_32;
}
void OpenGLDisplayPlugin::updateCompositeFramebuffer() {
auto renderSize = glm::uvec2(getRecommendedRenderSize());
if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) {
_compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y));
// _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_SRGBA_32, renderSize.x, renderSize.y));
_compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", getCompositeFBColorSpace(), renderSize.x, renderSize.y));
}
}

View file

@ -86,6 +86,8 @@ public:
void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override;
virtual std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator() override;
protected:
friend class PresentThread;
@ -102,10 +104,12 @@ protected:
virtual QThread::Priority getPresentPriority() { return QThread::HighPriority; }
virtual void compositeLayers();
virtual void compositeScene();
virtual std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator();
virtual void compositePointer();
virtual void compositeExtra() {};
virtual gpu::PipelinePointer getCompositeScenePipeline();
virtual gpu::Element getCompositeFBColorSpace();
// These functions must only be called on the presentation thread
virtual void customizeContext();
virtual void uncustomizeContext();
@ -149,9 +153,11 @@ protected:
gpu::PipelinePointer _hudPipeline;
gpu::PipelinePointer _mirrorHUDPipeline;
gpu::ShaderPointer _mirrorHUDPS;
gpu::PipelinePointer _simplePipeline;
gpu::PipelinePointer _presentPipeline;
gpu::PipelinePointer _drawTexturePipeline;
gpu::PipelinePointer _linearToSRGBPipeline;
gpu::PipelinePointer _SRGBToLinearPipeline;
gpu::PipelinePointer _cursorPipeline;
gpu::TexturePointer _displayTexture{};
float _compositeHUDAlpha { 1.0f };

View file

@ -1,4 +1,4 @@
//
//
// Created by Bradley Austin Davis on 2016/02/15
// Copyright 2016 High Fidelity, Inc.
//
@ -402,25 +402,18 @@ void HmdDisplayPlugin::HUDRenderer::build() {
format->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, gpu::Element(gpu::VEC3, gpu::FLOAT, gpu::XYZ), 0);
format->setAttribute(gpu::Stream::TEXCOORD, gpu::Stream::TEXCOORD, gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::UV));
uniformsBuffer = std::make_shared<gpu::Buffer>(sizeof(Uniforms), nullptr);
updatePipeline();
auto program = gpu::Shader::createProgram(shader::render_utils::program::hmd_ui);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(true, true, gpu::LESS_EQUAL));
state->setBlendFunction(true,
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
pipeline = gpu::Pipeline::create(program, state);
}
void HmdDisplayPlugin::HUDRenderer::updatePipeline() {
if (!pipeline) {
auto program = gpu::Shader::createProgram(shader::render_utils::program::hmd_ui);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
state->setDepthTest(gpu::State::DepthTest(true, true, gpu::LESS_EQUAL));
state->setBlendFunction(true,
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
pipeline = gpu::Pipeline::create(program, state);
}
}
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) {
updatePipeline();
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> HmdDisplayPlugin::HUDRenderer::render() {
auto hudPipeline = pipeline;
auto hudFormat = format;
auto hudVertices = vertices;
@ -479,7 +472,7 @@ void HmdDisplayPlugin::compositePointer() {
}
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> HmdDisplayPlugin::getHUDOperator() {
return _hudRenderer.render(*this);
return _hudRenderer.render();
}
HmdDisplayPlugin::~HmdDisplayPlugin() {

View file

@ -48,6 +48,7 @@ public:
void pluginUpdate() override {};
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator() override;
virtual StencilMaskMode getStencilMaskMode() const override { return StencilMaskMode::PAINT; }
signals:
@ -62,7 +63,6 @@ protected:
bool internalActivate() override;
void internalDeactivate() override;
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator() override;
void compositePointer() override;
void internalPresent() override;
void customizeContext() override;
@ -105,7 +105,7 @@ private:
gpu::BufferPointer vertices;
gpu::BufferPointer indices;
uint32_t indexCount { 0 };
gpu::PipelinePointer pipeline;
gpu::PipelinePointer pipeline { nullptr };
gpu::BufferPointer uniformsBuffer;
@ -123,7 +123,6 @@ private:
static const int VERTEX_STRIDE { sizeof(Vertex) };
void build();
void updatePipeline();
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> render(HmdDisplayPlugin& plugin);
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> render();
} _hudRenderer;
};

View file

@ -256,18 +256,28 @@ void EntityTreeRenderer::clear() {
}
// reset the engine
if (_wantScripts && !_shuttingDown) {
resetEntitiesScriptEngine();
}
// remove all entities from the scene
auto scene = _viewState->getMain3DScene();
if (scene) {
for (const auto& entry : _entitiesInScene) {
const auto& renderer = entry.second;
fadeOutRenderable(renderer);
if (_shuttingDown) {
if (scene) {
render::Transaction transaction;
for (const auto& entry : _entitiesInScene) {
const auto& renderer = entry.second;
renderer->removeFromScene(scene, transaction);
}
scene->enqueueTransaction(transaction);
}
} else {
qCWarning(entitiesrenderer) << "EntitityTreeRenderer::clear(), Unexpected null scene, possibly during application shutdown";
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";
}
}
_entitiesInScene.clear();
_renderablesToUpdate.clear();
@ -1056,10 +1066,14 @@ void EntityTreeRenderer::fadeOutRenderable(const EntityRendererPointer& renderab
render::Transaction transaction;
auto scene = _viewState->getMain3DScene();
transaction.setTransitionFinishedOperator(renderable->getRenderItemID(), [scene, renderable]() {
render::Transaction transaction;
renderable->removeFromScene(scene, transaction);
scene->enqueueTransaction(transaction);
EntityRendererWeakPointer weakRenderable = renderable;
transaction.setTransitionFinishedOperator(renderable->getRenderItemID(), [scene, weakRenderable]() {
auto renderable = weakRenderable.lock();
if (renderable) {
render::Transaction transaction;
renderable->removeFromScene(scene, transaction);
scene->enqueueTransaction(transaction);
}
});
scene->enqueueTransaction(transaction);

View file

@ -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

View file

@ -70,7 +70,7 @@ bool ShapeEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin
return true;
}
if (_color != entity->getColor()) {
if (_color != toGlm(entity->getColor())) {
return true;
}
if (_alpha != entity->getAlpha()) {
@ -130,12 +130,12 @@ void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPoint
}
});
glm::u8vec3 color = entity->getColor();
glm::vec3 color = toGlm(entity->getColor());
float alpha = entity->getAlpha();
if (_color != color || _alpha != alpha) {
_color = color;
_alpha = alpha;
_material->setAlbedo(toGlm(_color));
_material->setAlbedo(color);
_material->setOpacity(_alpha);
auto materials = _materials.find("0");

View file

@ -43,7 +43,7 @@ private:
PulsePropertyGroup _pulseProperties;
std::shared_ptr<graphics::Material> _material { std::make_shared<graphics::Material>() };
glm::u8vec3 _color;
glm::vec3 _color { NAN };
float _alpha;
glm::vec3 _position;

View file

@ -7,6 +7,7 @@
//
#include "RenderableWebEntityItem.h"
#include <atomic>
#include <QtCore/QTimer>
#include <QtGui/QOpenGLContext>
@ -46,7 +47,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 uint32_t _currentWebCount { 0 };
static std::atomic<uint32_t> _currentWebCount(0);
static const uint32_t MAX_CONCURRENT_WEB_VIEWS = 20;
static QTouchDevice _touchDevice;
@ -356,16 +357,15 @@ void WebEntityRenderer::buildWebSurface(const EntityItemPointer& entity, const Q
void WebEntityRenderer::destroyWebSurface() {
QSharedPointer<OffscreenQmlSurface> webSurface;
ContentType contentType = ContentType::NoContent;
withWriteLock([&] {
webSurface.swap(_webSurface);
_contentType = contentType;
});
_contentType = ContentType::NoContent;
if (webSurface) {
--_currentWebCount;
WebEntityRenderer::releaseWebSurface(webSurface, _cachedWebSurface, _connections);
}
if (webSurface) {
--_currentWebCount;
WebEntityRenderer::releaseWebSurface(webSurface, _cachedWebSurface, _connections);
}
});
}
glm::vec2 WebEntityRenderer::getWindowSize(const TypedEntityPointer& entity) const {

View file

@ -27,6 +27,10 @@
#include "GLHelpers.h"
#include "QOpenGLContextWrapper.h"
#if defined(GL_CUSTOM_CONTEXT)
#include <QtPlatformHeaders/QWGLNativeContext>
#endif
using namespace gl;
#if defined(GL_CUSTOM_CONTEXT)
@ -42,7 +46,10 @@ std::atomic<size_t> Context::_totalSwapchainMemoryUsage { 0 };
size_t Context::getSwapchainMemoryUsage() { return _totalSwapchainMemoryUsage.load(); }
size_t Context::evalSurfaceMemoryUsage(uint32_t width, uint32_t height, uint32_t pixelSize) {
return width * height * pixelSize;
size_t result = width;
result *= height;
result *= pixelSize;
return result;
}
void Context::updateSwapchainMemoryUsage(size_t prevSize, size_t newSize) {
@ -126,7 +133,7 @@ void Context::clear() {
#if defined(GL_CUSTOM_CONTEXT)
static void setupPixelFormatSimple(HDC hdc) {
// FIXME build the PFD based on the
// FIXME build the PFD based on the
static const PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
{
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
@ -176,6 +183,7 @@ static void setupPixelFormatSimple(HDC hdc) {
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
// Context create flag bits
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
@ -196,17 +204,17 @@ GLAPI PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
Q_GUI_EXPORT QOpenGLContext *qt_gl_global_share_context();
#if defined(GL_CUSTOM_CONTEXT)
bool Context::makeCurrent() {
BOOL result = wglMakeCurrent(_hdc, _hglrc);
assert(result);
updateSwapchainMemoryCounter();
return result;
}
void Context::swapBuffers() {
SwapBuffers(_hdc);
}
void Context::doneCurrent() {
wglMakeCurrent(0, 0);
bool Context::makeCurrent() {
BOOL result = wglMakeCurrent(_hdc, _hglrc);
assert(result);
updateSwapchainMemoryCounter();
return result;
}
void Context::swapBuffers() {
SwapBuffers(_hdc);
}
void Context::doneCurrent() {
wglMakeCurrent(0, 0);
}
#endif
@ -305,11 +313,18 @@ void Context::create(QOpenGLContext* shareContext) {
#else
contextAttribs.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB);
#endif
contextAttribs.push_back(WGL_CONTEXT_FLAGS_ARB);
if (enableDebugLogger()) {
contextAttribs.push_back(WGL_CONTEXT_DEBUG_BIT_ARB);
} else {
contextAttribs.push_back(0);
{
int contextFlags = 0;
if (enableDebugLogger()) {
contextFlags |= WGL_CONTEXT_DEBUG_BIT_ARB;
}
#ifdef USE_KHR_ROBUSTNESS
contextFlags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
#endif
if (contextFlags != 0) {
contextAttribs.push_back(WGL_CONTEXT_FLAGS_ARB);
contextAttribs.push_back(contextFlags);
}
}
contextAttribs.push_back(0);
HGLRC shareHglrc = nullptr;
@ -323,8 +338,8 @@ void Context::create(QOpenGLContext* shareContext) {
if (_hglrc != 0) {
createWrapperContext();
}
}
}
if (_hglrc == 0) {
// fallback, if the context creation failed, or USE_CUSTOM_CONTEXT is false
qtCreate(shareContext);

View file

@ -23,7 +23,7 @@ class QOpenGLContext;
class QThread;
class QOpenGLDebugMessage;
#if defined(Q_OS_WIN) && defined(USE_GLES)
#if defined(Q_OS_WIN) && (defined(USE_GLES) || defined(USE_KHR_ROBUSTNESS))
//#if defined(Q_OS_WIN)
#define GL_CUSTOM_CONTEXT
#endif

View file

@ -450,13 +450,16 @@ qint64 LimitedNodeList::sendPacket(std::unique_ptr<NLPacket> packet, const HifiS
auto size = sendUnreliablePacket(*packet, sockAddr, hmacAuth);
if (size < 0) {
auto now = usecTimestampNow();
eachNode([now](const SharedNodePointer & node) {
qCDebug(networking) << "Stats for " << node->getPublicSocket() << "\n"
<< " Last Heard Microstamp: " << node->getLastHeardMicrostamp() << " (" << (now - node->getLastHeardMicrostamp()) << "usec ago)\n"
<< " Outbound Kbps: " << node->getOutboundKbps() << "\n"
<< " Inbound Kbps: " << node->getInboundKbps() << "\n"
<< " Ping: " << node->getPingMs();
});
if (now - _sendErrorStatsTime > ERROR_STATS_PERIOD_US) {
_sendErrorStatsTime = now;
eachNode([now](const SharedNodePointer& node) {
qCDebug(networking) << "Stats for " << node->getPublicSocket() << "\n"
<< " Last Heard Microstamp: " << node->getLastHeardMicrostamp() << " (" << (now - node->getLastHeardMicrostamp()) << "usec ago)\n"
<< " Outbound Kbps: " << node->getOutboundKbps() << "\n"
<< " Inbound Kbps: " << node->getInboundKbps() << "\n"
<< " Ping: " << node->getPingMs();
});
}
}
return size;
}
@ -996,7 +999,7 @@ void LimitedNodeList::sendSTUNRequest() {
const int NUM_INITIAL_STUN_REQUESTS_BEFORE_FAIL = 10;
if (!_hasCompletedInitialSTUN) {
qCDebug(networking) << "Sending intial stun request to" << STUN_SERVER_HOSTNAME;
qCDebug(networking) << "Sending initial stun request to" << STUN_SERVER_HOSTNAME;
if (_numInitialSTUNRequests > NUM_INITIAL_STUN_REQUESTS_BEFORE_FAIL) {
// we're still trying to do our initial STUN we're over the fail threshold
@ -1185,7 +1188,7 @@ void LimitedNodeList::stopInitialSTUNUpdate(bool success) {
// We now setup a timer here to fire every so often to check that our IP address has not changed.
// Or, if we failed - if will check if we can eventually get a public socket
const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 30 * 1000;
const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 10 * 1000;
QTimer* stunOccasionalTimer = new QTimer { this };
connect(stunOccasionalTimer, &QTimer::timeout, this, &LimitedNodeList::sendSTUNRequest);
@ -1243,15 +1246,22 @@ void LimitedNodeList::errorTestingLocalSocket() {
}
void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) {
if (sockAddr != _localSockAddr) {
if (sockAddr.getAddress() != _localSockAddr.getAddress()) {
if (_localSockAddr.isNull()) {
qCInfo(networking) << "Local socket is" << sockAddr;
_localSockAddr = sockAddr;
} else {
qCInfo(networking) << "Local socket has changed from" << _localSockAddr << "to" << sockAddr;
_localSockAddr = sockAddr;
if (_hasTCPCheckedLocalSocket) { // Force a port change for NAT:
reset();
_nodeSocket.rebind(0);
_localSockAddr.setPort(_nodeSocket.localPort());
qCInfo(networking) << "Local port changed to" << _localSockAddr.getPort();
}
}
_localSockAddr = sockAddr;
emit localSockAddrChanged(_localSockAddr);
}
}

View file

@ -497,6 +497,9 @@ private:
float _outboundKbps { 0.0f };
bool _dropOutgoingNodeTraffic { false };
quint64 _sendErrorStatsTime { (quint64)0 };
static const quint64 ERROR_STATS_PERIOD_US { 1 * USECS_PER_SECOND };
};
#endif // hifi_LimitedNodeList_h

View file

@ -418,6 +418,20 @@ void NodeList::sendDomainServerCheckIn() {
auto accountManager = DependencyManager::get<AccountManager>();
packetStream << FingerprintUtils::getMachineFingerprint();
QString systemInfo;
#if defined Q_OS_WIN
systemInfo = "OS:Windows";
#elif defined Q_OS_OSX
systemInfo = "OS:OSX";
#elif defined Q_OS_LINUX
systemInfo = "OS:Linux";
#elif defined Q_OS_ANDROID
systemInfo = "OS:Android";
#else
systemInfo = "OS:Unknown";
#endif
packetStream << systemInfo;
packetStream << _connectReason;
if (_nodeDisconnectTimestamp < _nodeConnectTimestamp) {

View file

@ -72,7 +72,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
return static_cast<PacketVersion>(DomainConnectionDeniedVersion::IncludesExtraInfo);
case PacketType::DomainConnectRequest:
return static_cast<PacketVersion>(DomainConnectRequestVersion::HasReason);
return static_cast<PacketVersion>(DomainConnectRequestVersion::HasSystemInfo);
case PacketType::DomainServerAddedNode:
return static_cast<PacketVersion>(DomainServerAddedNodeVersion::PermissionsGrid);

View file

@ -346,7 +346,8 @@ enum class DomainConnectRequestVersion : PacketVersion {
HasMachineFingerprint,
AlwaysHasMachineFingerprint,
HasTimestamp,
HasReason
HasReason,
HasSystemInfo
};
enum class DomainConnectionDeniedVersion : PacketVersion {

View file

@ -33,6 +33,7 @@ using namespace udt;
Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) :
QObject(parent),
_udpSocket(parent),
_readyReadBackupTimer(new QTimer(this)),
_shouldChangeSocketOptions(shouldChangeSocketOptions)
{
@ -50,6 +51,7 @@ Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) :
}
void Socket::bind(const QHostAddress& address, quint16 port) {
_udpSocket.bind(address, port);
if (_shouldChangeSocketOptions) {
@ -75,7 +77,7 @@ void Socket::rebind() {
}
void Socket::rebind(quint16 localPort) {
_udpSocket.close();
_udpSocket.abort();
bind(QHostAddress::AnyIPv4, localPort);
}

View file

@ -46,6 +46,7 @@ bool OctreeEditPacketSender::serversExist() const {
void OctreeEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, std::unique_ptr<NLPacket> packet) {
bool wantDebug = false;
QMutexLocker lock(&_packetsQueueLock);
DependencyManager::get<NodeList>()->eachNode([&](const SharedNodePointer& node){
// only send to the NodeTypes that are getMyNodeType()
if (node->getType() == getMyNodeType()
@ -324,6 +325,8 @@ bool OctreeEditPacketSender::process() {
void OctreeEditPacketSender::processNackPacket(ReceivedMessage& message, SharedNodePointer sendingNode) {
// parse sending node from packet, retrieve packet history for that node
QMutexLocker lock(&_packetsQueueLock);
// if packet history doesn't exist for the sender node (somehow), bail
if (_sentPacketHistories.count(sendingNode->getUUID()) == 0) {
return;
@ -345,7 +348,7 @@ void OctreeEditPacketSender::processNackPacket(ReceivedMessage& message, SharedN
}
void OctreeEditPacketSender::nodeKilled(SharedNodePointer node) {
// TODO: add locks
QMutexLocker lock(&_packetsQueueLock);
QUuid nodeUUID = node->getUUID();
_pendingEditPackets.erase(nodeUUID);
_outgoingSequenceNumbers.erase(nodeUUID);

View file

@ -86,19 +86,20 @@ protected:
void processPreServerExistsPackets();
// These are packets which are destined from know servers but haven't been released because they're still too small
// protected by _packetsQueueLock
std::unordered_map<QUuid, PacketOrPacketList> _pendingEditPackets;
// These are packets that are waiting to be processed because we don't yet know if there are servers
int _maxPendingMessages;
bool _releaseQueuedMessagesPending;
QMutex _pendingPacketsLock;
QMutex _packetsQueueLock; // don't let different threads release the queue while another thread is writing to it
QMutex _packetsQueueLock{ QMutex::Recursive }; // don't let different threads release the queue while another thread is writing to it
std::list<EditMessagePair> _preServerEdits; // these will get packed into other larger packets
std::list<std::unique_ptr<NLPacket>> _preServerSingleMessagePackets; // these will go out as is
QMutex _releaseQueuedPacketMutex;
// TODO: add locks for this and _pendingEditPackets
// protected by _packetsQueueLock
std::unordered_map<QUuid, SentPacketHistory> _sentPacketHistories;
std::unordered_map<QUuid, quint16> _outgoingSequenceNumbers;
};

View file

@ -309,20 +309,28 @@ void PhysicalEntitySimulation::buildMotionStatesForEntitiesThatNeedThem() {
SetOfEntities::iterator entityItr = _entitiesToAddToPhysics.begin();
while (entityItr != _entitiesToAddToPhysics.end()) {
EntityItemPointer entity = (*entityItr);
assert(!entity->getPhysicsInfo());
if (entity->isDead()) {
prepareEntityForDelete(entity);
entityItr = _entitiesToAddToPhysics.erase(entityItr);
} else if (!entity->shouldBePhysical()) {
// this entity should no longer be on _entitiesToAddToPhysics
continue;
}
if (entity->getPhysicsInfo()) {
entityItr = _entitiesToAddToPhysics.erase(entityItr);
continue;
}
if (!entity->shouldBePhysical()) {
// this entity should no longer be on _entitiesToAddToPhysics
if (entity->isMovingRelativeToParent()) {
SetOfEntities::iterator itr = _simpleKinematicEntities.find(entity);
if (itr == _simpleKinematicEntities.end()) {
_simpleKinematicEntities.insert(entity);
}
}
} else if (entity->isReadyToComputeShape()) {
entityItr = _entitiesToAddToPhysics.erase(entityItr);
continue;
}
if (entity->isReadyToComputeShape()) {
ShapeRequest shapeRequest(entity);
ShapeRequests::iterator requestItr = _shapeRequests.find(shapeRequest);
if (requestItr == _shapeRequests.end()) {
@ -332,18 +340,7 @@ void PhysicalEntitySimulation::buildMotionStatesForEntitiesThatNeedThem() {
uint32_t requestCount = ObjectMotionState::getShapeManager()->getWorkRequestCount();
btCollisionShape* shape = const_cast<btCollisionShape*>(ObjectMotionState::getShapeManager()->getShape(shapeInfo));
if (shape) {
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
if (!motionState) {
buildMotionState(shape, entity);
} else {
// Is it possible to fall in here?
// entity shouldn't be on _entitiesToAddToPhysics list if it already has a motionState.
// but just in case...
motionState->setShape(shape);
motionState->setRegion(_space->getRegion(entity->getSpaceIndex()));
_physicalObjects.insert(motionState);
_incomingChanges.insert(motionState);
}
buildMotionState(shape, entity);
} else if (requestCount != ObjectMotionState::getShapeManager()->getWorkRequestCount()) {
// shape doesn't exist but a new worker has been spawned to build it --> add to shapeRequests and wait
shapeRequest.shapeHash = shapeInfo.getHash();
@ -354,6 +351,7 @@ void PhysicalEntitySimulation::buildMotionStatesForEntitiesThatNeedThem() {
}
entityItr = _entitiesToAddToPhysics.erase(entityItr);
} else {
// skip for later
++entityItr;
}
}

View file

@ -181,7 +181,7 @@ void ThreadSafeDynamicsWorld::drawConnectedSpheres(btIDebugDraw* drawer, btScala
btVector3 xAxis = direction.cross(btVector3(0.0f, 1.0f, 0.0f));
xAxis = xAxis.length() < EPSILON ? btVector3(1.0f, 0.0f, 0.0f) : xAxis.normalize();
btVector3 zAxis = xAxis.cross(btVector3(0.0f, 1.0f, 0.0f));
zAxis = (direction.normalize().getY() < EPSILON) ? btVector3(0.0f, 1.0f, 0.0f) : zAxis.normalize();
zAxis = (direction.length2() < EPSILON || direction.normalize().getY() < EPSILON) ? btVector3(0.0f, 1.0f, 0.0f) : zAxis.normalize();
float fullCircle = 2.0f * PI;
for (float i = 0; i < fullCircle; i += stepRadians) {
float x1 = btSin(btScalar(i)) * radius1;

View file

@ -27,12 +27,13 @@ json getGPU(int index);
int getNumDisplays();
json getDisplay(int index);
int getNumMemories();
json getMemory(int index);
json getMemory();
json getComputer();
json getAll();
} // namespace platform
#endif // hifi_platform_h

View file

@ -9,6 +9,9 @@
#define hifi_platform_PlatformKeys_h
namespace platform { namespace keys{
// "UNKNOWN"
extern const char* UNKNOWN;
namespace cpu {
extern const char* vendor;
extern const char* vendor_Intel;
@ -36,8 +39,9 @@ namespace platform { namespace keys{
extern const char* coordsTop;
extern const char* coordsBottom;
}
namespace memory {
extern const char* memTotal;
}
namespace computer {
extern const char* OS;
extern const char* OS_WINDOWS;
@ -45,6 +49,8 @@ namespace platform { namespace keys{
extern const char* OS_LINUX;
extern const char* OS_ANDROID;
extern const char* OSVersion;
extern const char* vendor;
extern const char* vendor_Apple;
@ -52,6 +58,14 @@ namespace platform { namespace keys{
extern const char* profileTier;
}
} } // namespace plaform::keys
// Keys for categories used in json returned by getAll()
extern const char* CPUS;
extern const char* GPUS;
extern const char* DISPLAYS;
extern const char* MEMORY;
extern const char* COMPUTER;
} } // namespace plaform::keys
#endif

View file

@ -9,39 +9,45 @@
#include "AndroidPlatform.h"
#include "../PlatformKeys.h"
#include <GPUIdent.h>
#include <QSysInfo>
using namespace platform;
void AndroidInstance::enumerateCpu() {
void AndroidInstance::enumerateCpus() {
json cpu;
cpu[keys::cpu::vendor] = "";
cpu[keys::cpu::model] = "";
cpu[keys::cpu::clockSpeed] = "";
cpu[keys::cpu::numCores] = 0;
_cpu.push_back(cpu);
_cpus.push_back(cpu);
}
void AndroidInstance::enumerateGpu() {
void AndroidInstance::enumerateGpus() {
GPUIdent* ident = GPUIdent::getInstance();
json gpu = {};
gpu[keys::gpu::vendor] = ident->getName().toUtf8().constData();
gpu[keys::gpu::model] = ident->getName().toUtf8().constData();
gpu[keys::gpu::vendor] = findGPUVendorInDescription(gpu[keys::gpu::model].get<std::string>());
gpu[keys::gpu::videoMemory] = ident->getMemory();
gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData();
_gpu.push_back(gpu);
_display = ident->getOutput();
_gpus.push_back(gpu);
_displays = ident->getOutput();
}
void AndroidInstance::enumerateMemory() {
json ram = {};
ram[keys::memTotal]=0;
_memory.push_back(ram);
ram[keys::memory::memTotal]=0;
_memory = ram;
}
void AndroidInstance::enumerateComputer(){
_computer[keys::computer::OS] = keys::computer::OS_ANDROID;
_computer[keys::computer::vendor] = "";
_computer[keys::computer::model] = "";
auto sysInfo = QSysInfo();
_computer[keys::computer::OSVersion] = sysInfo.kernelVersion().toStdString();
}

View file

@ -15,10 +15,10 @@ namespace platform {
class AndroidInstance : public Instance {
public:
void enumerateCpu() override;
void enumerateCpus() override;
void enumerateGpus() override;
void enumerateMemory() override;
void enumerateGpu() override;
void enumerateComputer () override;
void enumerateComputer() override;
};
} // namespace platform

View file

@ -13,36 +13,37 @@
#include <string>
#include <CPUIdent.h>
#include <GPUIdent.h>
#include <QSysInfo>
using namespace platform;
void LinuxInstance::enumerateCpu() {
void LinuxInstance::enumerateCpus() {
json cpu = {};
cpu[keys::cpu::vendor] = CPUIdent::Vendor();
cpu[keys::cpu::model] = CPUIdent::Brand();
cpu[keys::cpu::numCores] = std::thread::hardware_concurrency();
_cpu.push_back(cpu);
_cpus.push_back(cpu);
}
void LinuxInstance::enumerateGpu() {
void LinuxInstance::enumerateGpus() {
GPUIdent* ident = GPUIdent::getInstance();
json gpu = {};
gpu[keys::gpu::vendor] = ident->getName().toUtf8().constData();
gpu[keys::gpu::model] = ident->getName().toUtf8().constData();
gpu[keys::gpu::vendor] = findGPUVendorInDescription(gpu[keys::gpu::model].get<std::string>());
gpu[keys::gpu::videoMemory] = ident->getMemory();
gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData();
_gpu.push_back(gpu);
_display = ident->getOutput();
_gpus.push_back(gpu);
_displays = ident->getOutput();
}
void LinuxInstance::enumerateMemory() {
json ram = {};
ram[keys::memTotal]=0;
ram[keys::memory::memTotal]=0;
_memory.push_back(ram);
_memory = ram;
}
void LinuxInstance::enumerateComputer(){
@ -50,5 +51,9 @@ void LinuxInstance::enumerateComputer(){
_computer[keys::computer::OS] = keys::computer::OS_LINUX;
_computer[keys::computer::vendor] = "";
_computer[keys::computer::model] = "";
auto sysInfo = QSysInfo();
_computer[keys::computer::OSVersion] = sysInfo.kernelVersion().toStdString();
}

View file

@ -15,10 +15,10 @@ namespace platform {
class LinuxInstance : public Instance {
public:
void enumerateCpu() override;
void enumerateCpus() override;
void enumerateGpus() override;
void enumerateMemory() override;
void enumerateGpu() override;
void enumerateComputer () override;
void enumerateComputer() override;
};
} // namespace platform

View file

@ -21,32 +21,33 @@
#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
#include <QSysInfo>
#endif
using namespace platform;
void MACOSInstance::enumerateCpu() {
void MACOSInstance::enumerateCpus() {
json cpu = {};
cpu[keys::cpu::vendor] = CPUIdent::Vendor();
cpu[keys::cpu::model] = CPUIdent::Brand();
cpu[keys::cpu::numCores] = std::thread::hardware_concurrency();
_cpu.push_back(cpu);
_cpus.push_back(cpu);
}
void MACOSInstance::enumerateGpu() {
void MACOSInstance::enumerateGpus() {
#ifdef Q_OS_MAC
GPUIdent* ident = GPUIdent::getInstance();
json gpu = {};
gpu[keys::gpu::vendor] = ident->getName().toUtf8().constData();
gpu[keys::gpu::model] = ident->getName().toUtf8().constData();
gpu[keys::gpu::vendor] = findGPUVendorInDescription(gpu[keys::gpu::model].get<std::string>());
gpu[keys::gpu::videoMemory] = ident->getMemory();
gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData();
_gpu.push_back(gpu);
_gpus.push_back(gpu);
#endif
@ -101,7 +102,7 @@ void MACOSInstance::enumerateDisplays() {
display["modeWidth"] = displayModeWidth;
display["modeHeight"] = displayModeHeight;
_display.push_back(display);
_displays.push_back(display);
#endif
}
@ -111,9 +112,9 @@ void MACOSInstance::enumerateMemory() {
#ifdef Q_OS_MAC
long pages = sysconf(_SC_PHYS_PAGES);
long page_size = sysconf(_SC_PAGE_SIZE);
ram[keys::memTotal] = pages * page_size;
ram[keys::memory::memTotal] = pages * page_size;
#endif
_memory.push_back(ram);
_memory = ram;
}
void MACOSInstance::enumerateComputer(){
@ -133,5 +134,9 @@ void MACOSInstance::enumerateComputer(){
free(model);
#endif
auto sysInfo = QSysInfo();
_computer[keys::computer::OSVersion] = sysInfo.kernelVersion().toStdString();
}

View file

@ -15,11 +15,11 @@ namespace platform {
class MACOSInstance : public Instance {
public:
void enumerateCpu() override;
void enumerateMemory() override;
void enumerateGpu() override;
void enumerateCpus() override;
void enumerateGpus() override;
void enumerateDisplays() override;
void enumerateComputer () override;
void enumerateMemory() override;
void enumerateComputer() override;
};
} // namespace platform

View file

@ -11,6 +11,8 @@
#include "../PlatformKeys.h"
namespace platform { namespace keys {
const char* UNKNOWN = "UNKNOWN";
namespace cpu {
const char* vendor = "vendor";
const char* vendor_Intel = "Intel";
@ -38,8 +40,9 @@ namespace platform { namespace keys {
const char* coordsTop = "coordinatestop";
const char* coordsBottom = "coordinatesbottom";
}
const char* memTotal = "memTotal";
namespace memory {
const char* memTotal = "memTotal";
}
namespace computer {
const char* OS = "OS";
const char* OS_WINDOWS = "WINDOWS";
@ -47,6 +50,8 @@ namespace platform { namespace keys {
const char* OS_LINUX = "LINUX";
const char* OS_ANDROID = "ANDROID";
const char* OSVersion = "OSVersion";
const char* vendor = "vendor";
const char* vendor_Apple = "Apple";
@ -54,6 +59,12 @@ namespace platform { namespace keys {
const char* profileTier = "profileTier";
}
const char* CPUS = "cpus";
const char* GPUS = "gpus";
const char* DISPLAYS = "displays";
const char* MEMORY = "memory";
const char* COMPUTER = "computer";
}}
#include <qglobal.h>
@ -117,14 +128,14 @@ json platform::getDisplay(int index) {
return _instance->getDisplay(index);
}
int platform::getNumMemories() {
return _instance->getNumMemories();
json platform::getMemory() {
return _instance->getMemory();
}
json platform::getMemory(int index) {
return _instance->getMemory(index);
}
json platform::getComputer(){
json platform::getComputer() {
return _instance->getComputer();
}
json platform::getAll() {
return _instance->getAll();
}

View file

@ -16,10 +16,10 @@ using namespace platform;
bool Instance::enumeratePlatform() {
enumerateComputer();
enumerateCpu();
enumerateGpu();
enumerateDisplays();
enumerateMemory();
enumerateCpus();
enumerateGpus();
enumerateDisplays();
// And profile the platform and put the tier in "computer"
_computer[keys::computer::profileTier] = Profiler::TierNames[Profiler::profilePlatform()];
@ -28,55 +28,42 @@ bool Instance::enumeratePlatform() {
}
json Instance::getCPU(int index) {
assert(index <(int) _cpu.size());
if (index >= (int)_cpu.size())
assert(index <(int) _cpus.size());
if (index >= (int)_cpus.size())
return json();
return _cpu.at(index);
}
//These are ripe for template.. will work on that next
json Instance::getMemory(int index) {
assert(index <(int) _memory.size());
if(index >= (int)_memory.size())
return json();
return _memory.at(index);
return _cpus.at(index);
}
json Instance::getGPU(int index) {
assert(index <(int) _gpu.size());
assert(index <(int) _gpus.size());
if (index >=(int) _gpu.size())
if (index >=(int) _gpus.size())
return json();
return _gpu.at(index);
return _gpus.at(index);
}
json Instance::getDisplay(int index) {
assert(index <(int) _display.size());
assert(index <(int) _displays.size());
if (index >=(int) _display.size())
if (index >=(int) _displays.size())
return json();
return _display.at(index);
return _displays.at(index);
}
Instance::~Instance() {
if (_cpu.size() > 0) {
_cpu.clear();
if (_cpus.size() > 0) {
_cpus.clear();
}
if (_memory.size() > 0) {
_memory.clear();
if (_gpus.size() > 0) {
_gpus.clear();
}
if (_gpu.size() > 0) {
_gpu.clear();
}
if (_display.size() > 0) {
_display.clear();
if (_displays.size() > 0) {
_displays.clear();
}
}
@ -106,17 +93,53 @@ json Instance::listAllKeys() {
keys::display::coordsTop,
keys::display::coordsBottom,
keys::memTotal,
keys::memory::memTotal,
keys::computer::OS,
keys::computer::OS_WINDOWS,
keys::computer::OS_MACOS,
keys::computer::OS_LINUX,
keys::computer::OS_ANDROID,
keys::computer::OSVersion,
keys::computer::vendor,
keys::computer::vendor_Apple,
keys::computer::model,
keys::computer::profileTier
keys::computer::profileTier,
keys::CPUS,
keys::GPUS,
keys::DISPLAYS,
keys::MEMORY,
keys::COMPUTER,
}});
return allKeys;
}
const char* Instance::findGPUVendorInDescription(const std::string& description) {
// intel integrated graphics
if (description.find(keys::gpu::vendor_Intel) != std::string::npos) {
return keys::gpu::vendor_Intel;
}
// AMD gpu
else if ((description.find(keys::gpu::vendor_AMD) != std::string::npos) || (description.find("Radeon") != std::string::npos)) {
return keys::gpu::vendor_AMD;
}
// NVIDIA gpu
else if (description.find(keys::gpu::vendor_NVIDIA) != std::string::npos) {
return keys::gpu::vendor_NVIDIA;
} else {
return keys::UNKNOWN;
}
}
json Instance::getAll() {
json all = {};
all[keys::COMPUTER] = _computer;
all[keys::MEMORY] = _memory;
all[keys::CPUS] = _cpus;
all[keys::GPUS] = _gpus;
all[keys::DISPLAYS] = _displays;
return all;
}

View file

@ -19,36 +19,39 @@ class Instance {
public:
bool virtual enumeratePlatform();
int getNumCPUs() { return (int)_cpu.size(); }
int getNumCPUs() { return (int)_cpus.size(); }
json getCPU(int index);
int getNumGPUs() { return (int)_gpu.size(); }
int getNumGPUs() { return (int)_gpus.size(); }
json getGPU(int index);
int getNumMemories() { return (int)_memory.size(); }
json getMemory(int index);
int getNumDisplays() { return (int)_display.size(); }
int getNumDisplays() { return (int)_displays.size(); }
json getDisplay(int index);
json getMemory() { return _memory; }
json getComputer() { return _computer; }
json getComputer() {return _computer;}
void virtual enumerateCpu()=0;
void virtual enumerateMemory()=0;
void virtual enumerateGpu()=0;
json getAll();
void virtual enumerateCpus()=0;
void virtual enumerateGpus()=0;
void virtual enumerateDisplays() {}
void virtual enumerateMemory() = 0;
void virtual enumerateComputer()=0;
virtual ~Instance();
static json listAllKeys();
// Helper function to filter the vendor name out of the description of a GPU
static const char* findGPUVendorInDescription(const std::string& description);
protected:
std::vector<json> _cpu;
std::vector<json> _memory;
std::vector<json> _gpu;
std::vector<json> _display;
std::vector<json> _cpus;
std::vector<json> _gpus;
std::vector<json> _displays;
json _memory;
json _computer;
};

View file

@ -16,32 +16,33 @@
#ifdef Q_OS_WIN
#include <Windows.h>
#include <QSysInfo>
#endif
using namespace platform;
void WINInstance::enumerateCpu() {
void WINInstance::enumerateCpus() {
json cpu = {};
cpu[keys::cpu::vendor] = CPUIdent::Vendor();
cpu[keys::cpu::model] = CPUIdent::Brand();
cpu[keys::cpu::numCores] = std::thread::hardware_concurrency();
_cpu.push_back(cpu);
_cpus.push_back(cpu);
}
void WINInstance::enumerateGpu() {
void WINInstance::enumerateGpus() {
GPUIdent* ident = GPUIdent::getInstance();
json gpu = {};
gpu[keys::gpu::vendor] = ident->getName().toUtf8().constData();
gpu[keys::gpu::model] = ident->getName().toUtf8().constData();
gpu[keys::gpu::vendor] = findGPUVendorInDescription(gpu[keys::gpu::model].get<std::string>());
gpu[keys::gpu::videoMemory] = ident->getMemory();
gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData();
_gpu.push_back(gpu);
_display = ident->getOutput();
_gpus.push_back(gpu);
_displays = ident->getOutput();
}
void WINInstance::enumerateMemory() {
@ -52,9 +53,9 @@ void WINInstance::enumerateMemory() {
statex.dwLength = sizeof(statex);
GlobalMemoryStatusEx(&statex);
int totalRam = statex.ullTotalPhys / 1024 / 1024;
ram[platform::keys::memTotal] = totalRam;
ram[platform::keys::memory::memTotal] = totalRam;
#endif
_memory.push_back(ram);
_memory = ram;
}
void WINInstance::enumerateComputer(){
@ -62,5 +63,8 @@ void WINInstance::enumerateComputer(){
_computer[keys::computer::vendor] = "";
_computer[keys::computer::model] = "";
auto sysInfo = QSysInfo();
_computer[keys::computer::OSVersion] = sysInfo.kernelVersion().toStdString();
}

View file

@ -15,9 +15,9 @@ namespace platform {
class WINInstance : public Instance {
public:
void enumerateCpu() override;
void enumerateCpus() override;
void enumerateGpus() override;
void enumerateMemory() override;
void enumerateGpu() override;
void enumerateComputer () override;
};
} // namespace platform

View file

@ -35,15 +35,6 @@ void DisplayPlugin::waitForPresent() {
}
}
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> DisplayPlugin::getHUDOperator() {
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> hudOperator;
{
QMutexLocker locker(&_presentMutex);
hudOperator = _hudOperator;
}
return hudOperator;
}
glm::mat4 HmdDisplay::getEyeToHeadTransform(Eye eye) const {
static const glm::mat4 xform;
return xform;

View file

@ -213,13 +213,12 @@ public:
void waitForPresent();
float getAveragePresentTime() { return _movingAveragePresent.average / (float)USECS_PER_MSEC; } // in msec
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator();
static const QString& MENU_PATH();
// for updating plugin-related commands. Mimics the input plugin.
virtual void pluginUpdate() = 0;
virtual std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> getHUDOperator() { return nullptr; }
virtual StencilMaskMode getStencilMaskMode() const { return StencilMaskMode::NONE; }
using StencilMaskMeshOperator = std::function<void(gpu::Batch&)>;
virtual StencilMaskMeshOperator getStencilMaskMeshOperator() { return nullptr; }
@ -234,8 +233,6 @@ protected:
gpu::ContextPointer _gpuContext;
std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)> _hudOperator { std::function<void(gpu::Batch&, const gpu::TexturePointer&, bool mirror)>() };
MovingAverage<float, 10> _movingAveragePresent;
float _renderResolutionScale { 1.0f };

View file

@ -122,22 +122,22 @@ void PickManager::update() {
// FIXME: give each type its own expiry
// Each type will update at least one pick, regardless of the expiry
{
PROFILE_RANGE(picks, "StylusPicks");
PROFILE_RANGE_EX(picks, "StylusPicks", 0xffff0000, (uint64_t)_totalPickCounts[PickQuery::Stylus]);
PerformanceTimer perfTimer("StylusPicks");
_updatedPickCounts[PickQuery::Stylus] = _stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false);
}
{
PROFILE_RANGE(picks, "RayPicks");
PROFILE_RANGE_EX(picks, "RayPicks", 0xffff0000, (uint64_t)_totalPickCounts[PickQuery::Ray]);
PerformanceTimer perfTimer("RayPicks");
_updatedPickCounts[PickQuery::Ray] = _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD);
}
{
PROFILE_RANGE(picks, "ParabolaPick");
PerformanceTimer perfTimer("ParabolaPick");
PROFILE_RANGE_EX(picks, "ParabolaPicks", 0xffff0000, (uint64_t)_totalPickCounts[PickQuery::Parabola]);
PerformanceTimer perfTimer("ParabolaPicks");
_updatedPickCounts[PickQuery::Parabola] = _parabolaPickCacheOptimizer.update(cachedPicks[PickQuery::Parabola], _nextPickToUpdate[PickQuery::Parabola], expiry, shouldPickHUD);
}
{
PROFILE_RANGE(picks, "CollisoinPicks");
PROFILE_RANGE_EX(picks, "CollisionPicks", 0xffff0000, (uint64_t)_totalPickCounts[PickQuery::Collision]);
PerformanceTimer perfTimer("CollisionPicks");
_updatedPickCounts[PickQuery::Collision] = _collisionPickCacheOptimizer.update(cachedPicks[PickQuery::Collision], _nextPickToUpdate[PickQuery::Collision], expiry, false);
}

View file

@ -49,8 +49,8 @@ bool RenderEventHandler::event(QEvent* e) {
return QObject::event(e);
}
RenderEventHandler::RenderEventHandler(SharedObject* shared, QThread* targetThread)
: _shared(shared) {
RenderEventHandler::RenderEventHandler(SharedObject* shared, QThread* targetThread) :
_shared(shared) {
// Create the GL canvas in the same thread as the share canvas
if (!_canvas.create(SharedObject::getSharedContext())) {
qFatal("Unable to create new offscreen GL context");
@ -136,7 +136,8 @@ void RenderEventHandler::qmlRender(bool sceneGraphSync) {
resize();
{
if (_currentSize != QSize()) {
PROFILE_RANGE(render_qml_gl, "render");
GLuint texture = SharedObject::getTextureCache().acquireTexture(_currentSize);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo);
@ -146,7 +147,7 @@ void RenderEventHandler::qmlRender(bool sceneGraphSync) {
glClear(GL_COLOR_BUFFER_BIT);
} else {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
_shared->_quickWindow->setRenderTarget(_fbo, _currentSize);
_shared->setRenderTarget(_fbo, _currentSize);
_shared->_renderControl->render();
}
_shared->_lastRenderTime = usecTimestampNow();
@ -179,7 +180,7 @@ void RenderEventHandler::onQuit() {
_fbo = 0;
}
_shared->shutdownRendering(_canvas, _currentSize);
_shared->shutdownRendering(_currentSize);
_canvas.doneCurrent();
}
_canvas.moveToThreadWithContext(qApp->thread());

View file

@ -78,7 +78,6 @@ SharedObject::SharedObject() {
QObject::connect(qApp, &QCoreApplication::aboutToQuit, this, &SharedObject::onAboutToQuit);
}
SharedObject::~SharedObject() {
// After destroy returns, the rendering thread should be gone
destroy();
@ -173,7 +172,6 @@ void SharedObject::setRootItem(QQuickItem* rootItem) {
QObject::connect(_renderControl, &QQuickRenderControl::renderRequested, this, &SharedObject::requestRender);
QObject::connect(_renderControl, &QQuickRenderControl::sceneChanged, this, &SharedObject::requestRenderSync);
#endif
}
void SharedObject::destroy() {
@ -210,7 +208,7 @@ void SharedObject::destroy() {
}
// Block until the rendering thread has stopped
// FIXME this is undesirable because this is blocking the main thread,
// but I haven't found a reliable way to do this only at application
// but I haven't found a reliable way to do this only at application
// shutdown
if (_renderThread) {
_renderThread->wait();
@ -220,10 +218,8 @@ void SharedObject::destroy() {
#endif
}
#define SINGLE_QML_ENGINE 0
#if SINGLE_QML_ENGINE
static QQmlEngine* globalEngine{ nullptr };
static size_t globalEngineRefCount{ 0 };
@ -344,6 +340,11 @@ void SharedObject::setSize(const QSize& size) {
#endif
}
void SharedObject::setMaxFps(uint8_t maxFps) {
QMutexLocker locker(&_mutex);
_maxFps = maxFps;
}
bool SharedObject::preRender(bool sceneGraphSync) {
#ifndef DISABLE_QML
QMutexLocker lock(&_mutex);
@ -370,9 +371,9 @@ bool SharedObject::preRender(bool sceneGraphSync) {
return true;
}
void SharedObject::shutdownRendering(OffscreenGLCanvas& canvas, const QSize& size) {
void SharedObject::shutdownRendering(const QSize& size) {
QMutexLocker locker(&_mutex);
if (size != QSize(0, 0)) {
if (size != QSize()) {
getTextureCache().releaseSize(size);
if (_latestTextureAndFence.first) {
getTextureCache().releaseTexture(_latestTextureAndFence);
@ -380,19 +381,17 @@ void SharedObject::shutdownRendering(OffscreenGLCanvas& canvas, const QSize& siz
}
#ifndef DISABLE_QML
_renderControl->invalidate();
canvas.doneCurrent();
#endif
wake();
}
bool SharedObject::isQuit() {
bool SharedObject::isQuit() const {
QMutexLocker locker(&_mutex);
return _quit;
}
void SharedObject::requestRender() {
// Don't queue multiple renders
if (_renderRequested) {
if (_quit) {
return;
}
_renderRequested = true;
@ -402,18 +401,13 @@ void SharedObject::requestRenderSync() {
if (_quit) {
return;
}
{
QMutexLocker lock(&_mutex);
_syncRequested = true;
}
requestRender();
_renderRequested = true;
_syncRequested = true;
}
bool SharedObject::fetchTexture(TextureAndFence& textureAndFence) {
QMutexLocker locker(&_mutex);
if (0 == _latestTextureAndFence.first) {
if (!_latestTextureAndFence.first) {
return false;
}
textureAndFence = { 0, 0 };
@ -421,8 +415,7 @@ bool SharedObject::fetchTexture(TextureAndFence& textureAndFence) {
return true;
}
void hifi::qml::impl::SharedObject::addToDeletionList(QObject * object)
{
void SharedObject::addToDeletionList(QObject* object) {
_deletionList.append(QPointer<QObject>(object));
}
@ -469,11 +462,9 @@ void SharedObject::onRender() {
return;
}
QMutexLocker lock(&_mutex);
if (_syncRequested) {
lock.unlock();
_renderControl->polishItems();
lock.relock();
QMutexLocker lock(&_mutex);
QCoreApplication::postEvent(_renderObject, new OffscreenEvent(OffscreenEvent::RenderSync));
// sync and render request, main and render threads must be synchronized
wait();
@ -494,13 +485,11 @@ void SharedObject::onTimer() {
{
QMutexLocker locker(&_mutex);
// Don't queue more than one frame at a time
if (0 != _latestTextureAndFence.first) {
if (_latestTextureAndFence.first) {
return;
}
}
{
if (_maxFps == 0) {
if (!_maxFps) {
return;
}
auto minRenderInterval = USECS_PER_SECOND / _maxFps;

View file

@ -16,7 +16,6 @@
#include "TextureCache.h"
class QWindow;
class QTimer;
class QQuickWindow;
@ -24,7 +23,6 @@ class QQuickItem;
class QOpenGLContext;
class QQmlEngine;
class QQmlContext;
class OffscreenGLCanvas;
namespace hifi { namespace qml {
@ -51,11 +49,11 @@ public:
void create(OffscreenSurface* surface);
void setRootItem(QQuickItem* rootItem);
void destroy();
bool isQuit();
bool isQuit() const;
QSize getSize() const;
void setSize(const QSize& size);
void setMaxFps(uint8_t maxFps) { _maxFps = maxFps; }
void setMaxFps(uint8_t maxFps);
QQuickWindow* getWindow() { return _quickWindow; }
QQuickItem* getRootItem() { return _rootItem; }
@ -72,7 +70,7 @@ private:
bool event(QEvent* e) override;
bool preRender(bool sceneGraphSync);
void shutdownRendering(OffscreenGLCanvas& canvas, const QSize& size);
void shutdownRendering(const QSize& size);
// Called by the render event handler, from the render thread
void initializeRenderControl(QOpenGLContext* context);
void releaseTextureAndFence();
@ -94,31 +92,30 @@ private:
QList<QPointer<QObject>> _deletionList;
// Texture management
TextureAndFence _latestTextureAndFence{ 0, 0 };
QQuickItem* _item{ nullptr };
QQuickItem* _rootItem{ nullptr };
QQuickWindow* _quickWindow{ nullptr };
QQmlContext* _qmlContext{ nullptr };
TextureAndFence _latestTextureAndFence { 0, 0 };
QQuickItem* _rootItem { nullptr };
QQuickWindow* _quickWindow { nullptr };
QQmlContext* _qmlContext { nullptr };
mutable QMutex _mutex;
QWaitCondition _cond;
#ifndef DISABLE_QML
QWindow* _proxyWindow{ nullptr };
RenderControl* _renderControl{ nullptr };
RenderEventHandler* _renderObject{ nullptr };
QWindow* _proxyWindow { nullptr };
RenderControl* _renderControl { nullptr };
RenderEventHandler* _renderObject { nullptr };
QTimer* _renderTimer{ nullptr };
QThread* _renderThread{ nullptr };
QTimer* _renderTimer { nullptr };
QThread* _renderThread { nullptr };
#endif
uint64_t _lastRenderTime{ 0 };
QSize _size{ 100, 100 };
uint8_t _maxFps{ 60 };
uint64_t _lastRenderTime { 0 };
QSize _size { 100, 100 };
uint8_t _maxFps { 60 };
bool _renderRequested{ false };
bool _syncRequested{ false };
bool _quit{ false };
bool _paused{ false };
bool _renderRequested { false };
bool _syncRequested { false };
bool _quit { false };
bool _paused { false };
};
} // namespace impl

View file

@ -35,9 +35,8 @@ public:
using Size = uint64_t;
struct TextureSet {
Size textureSize;
// The number of surfaces with this size
size_t clientCount{ 0 };
size_t clientCount { 0 };
ValueList returnedTextures;
};
@ -66,7 +65,7 @@ private:
std::unordered_map<uint32_t, QSize> _textureSizes;
Mutex _mutex;
std::list<Value> _returnedTextures;
size_t _totalTextureUsage{ 0 };
size_t _totalTextureUsage { 0 };
};
}}} // namespace hifi::qml::impl

View file

@ -18,7 +18,13 @@
using namespace recording;
NetworkClipLoader::NetworkClipLoader(const QUrl& url) :
Resource(url),
_clip(std::make_shared<NetworkClip>(url)) {}
_clip(std::make_shared<NetworkClip>(url)) {
if (url.isEmpty()) {
_loaded = false;
_startedLoading = false;
_failedToLoad = true;
}
}
void NetworkClip::init(const QByteArray& clipData) {
_clipData = clipData;

View file

@ -37,7 +37,6 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 albedo, float roughness
_fragColor0 = vec4(albedo, mix(packShadedMetallic(metallic), packScatteringMetallic(metallic), check));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(mix(emissive, vec3(scattering), check), occlusion);
_fragColor3 = vec4(isEmissiveEnabled() * emissive, 1.0);
}
@ -49,7 +48,6 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 albedo, float r
_fragColor0 = vec4(albedo, packLightmappedMetallic(metallic));
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(isLightmapEnabled() * lightmap, 1.0);
_fragColor3 = vec4(isLightmapEnabled() * lightmap * albedo, 1.0);
}
@ -59,7 +57,7 @@ void packDeferredFragmentUnlit(vec3 normal, float alpha, vec3 color) {
}
_fragColor0 = vec4(color, packUnlit());
_fragColor1 = vec4(packNormal(normal), 1.0);
// _fragColor2 = vec4(vec3(0.0), 1.0);
_fragColor2 = vec4(vec3(0.0), 1.0);
_fragColor3 = vec4(color, 1.0);
}
@ -69,7 +67,8 @@ void packDeferredFragmentTranslucent(vec3 normal, float alpha, vec3 albedo, floa
}
_fragColor0 = vec4(albedo.rgb, alpha);
_fragColor1 = vec4(packNormal(normal), clamp(roughness, 0.0, 1.0));
_fragColor2 = vec4(vec3(0.0), 1.0);
_fragColor3 = vec4(0.0);
}
<@endif@>

View file

@ -41,33 +41,17 @@ namespace gr {
using namespace render;
struct LightLocations {
bool shadowTransform{ false };
void initialize(const gpu::ShaderPointer& program) {
shadowTransform = program->getReflection().validUniformBuffer(ru::Buffer::ShadowParams);
}
};
static void loadLightProgram(int programId, bool lightVolume, gpu::PipelinePointer& program, LightLocationsPtr& locations);
static void loadLightProgram(int programId, bool lightVolume, gpu::PipelinePointer& program);
void DeferredLightingEffect::init() {
_directionalAmbientSphereLightLocations = std::make_shared<LightLocations>();
_directionalSkyboxLightLocations = std::make_shared<LightLocations>();
loadLightProgram(shader::render_utils::program::directional_ambient_light, false, _directionalAmbientSphereLight);
loadLightProgram(shader::render_utils::program::directional_skybox_light, false, _directionalSkyboxLight);
_directionalAmbientSphereLightShadowLocations = std::make_shared<LightLocations>();
_directionalSkyboxLightShadowLocations = std::make_shared<LightLocations>();
loadLightProgram(shader::render_utils::program::directional_ambient_light_shadow, false, _directionalAmbientSphereLightShadow);
loadLightProgram(shader::render_utils::program::directional_skybox_light_shadow, false, _directionalSkyboxLightShadow);
_localLightLocations = std::make_shared<LightLocations>();
_localLightOutlineLocations = std::make_shared<LightLocations>();
loadLightProgram(shader::render_utils::program::directional_ambient_light, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations);
loadLightProgram(shader::render_utils::program::directional_skybox_light, false, _directionalSkyboxLight, _directionalSkyboxLightLocations);
loadLightProgram(shader::render_utils::program::directional_ambient_light_shadow, false, _directionalAmbientSphereLightShadow, _directionalAmbientSphereLightShadowLocations);
loadLightProgram(shader::render_utils::program::directional_skybox_light_shadow, false, _directionalSkyboxLightShadow, _directionalSkyboxLightShadowLocations);
loadLightProgram(shader::render_utils::program::local_lights_shading, true, _localLight, _localLightLocations);
loadLightProgram(shader::render_utils::program::local_lights_drawOutline, true, _localLightOutline, _localLightOutlineLocations);
loadLightProgram(shader::render_utils::program::local_lights_shading, true, _localLight);
loadLightProgram(shader::render_utils::program::local_lights_drawOutline, true, _localLightOutline);
}
// FIXME: figure out how to move lightFrame into a varying in GeometryCache and RenderPipelines
@ -123,15 +107,9 @@ void DeferredLightingEffect::unsetLocalLightsBatch(gpu::Batch& batch) {
batch.setUniformBuffer(ru::Buffer::LightClusterFrustumGrid, nullptr);
}
static gpu::ShaderPointer makeLightProgram(int programId, LightLocationsPtr& locations) {
static void loadLightProgram(int programId, bool lightVolume, gpu::PipelinePointer& pipeline) {
gpu::ShaderPointer program = gpu::Shader::createProgram(programId);
locations->initialize(program);
return program;
}
static void loadLightProgram(int programId, bool lightVolume, gpu::PipelinePointer& pipeline, LightLocationsPtr& locations) {
gpu::ShaderPointer program = makeLightProgram(programId, locations);
auto state = std::make_shared<gpu::State>();
state->setColorWriteMask(true, true, true, false);
@ -456,7 +434,6 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
// Setup the global directional pass pipeline
auto program = deferredLightingEffect->_directionalSkyboxLight;
LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations;
{
if (keyLightCastShadows) {
@ -464,20 +441,16 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext,
// otherwise use the ambient sphere version
if (hasAmbientMap) {
program = deferredLightingEffect->_directionalSkyboxLightShadow;
locations = deferredLightingEffect->_directionalSkyboxLightShadowLocations;
} else {
program = deferredLightingEffect->_directionalAmbientSphereLightShadow;
locations = deferredLightingEffect->_directionalAmbientSphereLightShadowLocations;
}
} else {
// If the keylight has an ambient Map then use the Skybox version of the pass
// otherwise use the ambient sphere version
if (hasAmbientMap) {
program = deferredLightingEffect->_directionalSkyboxLight;
locations = deferredLightingEffect->_directionalSkyboxLightLocations;
} else {
program = deferredLightingEffect->_directionalAmbientSphereLight;
locations = deferredLightingEffect->_directionalAmbientSphereLightLocations;
}
}

View file

@ -37,10 +37,6 @@
#include "SubsurfaceScattering.h"
#include "AmbientOcclusionEffect.h"
struct LightLocations;
using LightLocationsPtr = std::shared_ptr<LightLocations>;
// THis is where we currently accumulate the local lights, let s change that sooner than later
class DeferredLightingEffect : public Dependency {
SINGLETON_DEPENDENCY
@ -72,15 +68,6 @@ private:
gpu::PipelinePointer _localLight;
gpu::PipelinePointer _localLightOutline;
LightLocationsPtr _directionalSkyboxLightLocations;
LightLocationsPtr _directionalAmbientSphereLightLocations;
LightLocationsPtr _directionalSkyboxLightShadowLocations;
LightLocationsPtr _directionalAmbientSphereLightShadowLocations;
LightLocationsPtr _localLightLocations;
LightLocationsPtr _localLightOutlineLocations;
friend class LightClusteringPass;
friend class RenderDeferredSetup;
friend class RenderDeferredLocals;

View file

@ -111,7 +111,7 @@ void CompositeHUD::run(const RenderContextPointer& renderContext, const gpu::Fra
assert(renderContext->args->_context);
// We do not want to render HUD elements in secondary camera
if (renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) {
if (nsightActive() || renderContext->args->_renderMode == RenderArgs::RenderMode::SECONDARY_CAMERA_RENDER_MODE) {
return;
}

View file

@ -18,7 +18,7 @@ layout(location=RENDER_UTILS_ATTR_TEXCOORD01) out vec4 _texCoord01;
void main(void) {
const float depth = 1.0;
const vec4 UNIT_QUAD[4] = vec4[4](
const mat4 UNIT_QUAD = mat4(
vec4(-1.0, -1.0, depth, 1.0),
vec4(1.0, -1.0, depth, 1.0),
vec4(-1.0, 1.0, depth, 1.0),
@ -26,7 +26,7 @@ void main(void) {
);
vec4 pos = UNIT_QUAD[gl_VertexID];
_texCoord01.xy = (pos.xy + 1.0) * 0.5;
_texCoord01 = vec4((pos.xy + 1.0) * 0.5, 0.0, 0.0);
gl_Position = pos;
}

Some files were not shown because too many files have changed in this diff Show more