mirror of
https://github.com/lubosz/overte.git
synced 2025-04-12 18:52:33 +02:00
Merge branch 'master' into proceduralMesh
This commit is contained in:
commit
16a56dc1ec
180 changed files with 13867 additions and 1251 deletions
108
BUILD_ANDROID.md
108
BUILD_ANDROID.md
|
@ -1,64 +1,118 @@
|
|||
Please read the [general build guide](BUILD.md) for information on building other platform. Only Android specific instructions are found in this file.
|
||||
Please read the [general build guide](BUILD.md) for information on building other platforms. Only Android specific instructions are found in this file. **Note that these instructions apply to building for Oculus Quest.**
|
||||
|
||||
# Dependencies
|
||||
|
||||
Building is currently supported on OSX, Windows and Linux platforms, but developers intending to do work on the library dependencies are strongly urged to use 64 bit Linux as a build platform
|
||||
Building is currently supported on Windows, OSX and Linux, but developers intending to do work on the library dependencies are strongly urged to use 64 bit Linux as a build platform.
|
||||
|
||||
You will need the following tools to build Android targets.
|
||||
### OS specific dependencies
|
||||
|
||||
* [Android Studio](https://developer.android.com/studio/index.html)
|
||||
Please install the dependencies for your OS using the [Windows](BUILD_WIN.md), [OSX](BUILD_OSX.md) or [Linux](BUILD_LINUX.md) build instructions before attempting to build for Android.
|
||||
|
||||
### Android Studio
|
||||
|
||||
Download the Android Studio installer and run it. Once installed, at the welcome screen, click configure in the lower right corner and select SDK manager
|
||||
Download the [Android Studio](https://developer.android.com/studio/index.html) installer and run it. Once installed, at the welcome screen, click _Configure_ in the lower right corner and select _SDK Manager_.
|
||||
|
||||
From the SDK Platforms tab, select API levels 24 and 26.
|
||||
From the _SDK Platforms_ tab, select API levels 26 and 28.
|
||||
|
||||
From the SDK Tools tab select the following
|
||||
From the _SDK Tools_ tab, select the following
|
||||
|
||||
* Android SDK Build-Tools
|
||||
* GPU Debugging Tools
|
||||
* CMake (even if you have a separate CMake installation)
|
||||
* LLDB
|
||||
* Android SDK Platform-Tools
|
||||
* Android SDK Tools
|
||||
* NDK (even if you have the NDK installed separately)
|
||||
|
||||
Make sure the NDK installed version is 18 (or higher)
|
||||
Still in the _SDK Tools_ tab, click _Show Package Details_. Select CMake 3.6.4. Do this even if you have a separate CMake installation.
|
||||
|
||||
# Environment
|
||||
Also, make sure the NDK installed version is 18 (or higher).
|
||||
|
||||
Setting up the environment for android builds requires some additional steps
|
||||
# Environment
|
||||
|
||||
#### Set up machine specific Gradle properties
|
||||
### Create a keystore in Android Studio
|
||||
Follow the directions [here](https://developer.android.com/studio/publish/app-signing#generate-key) to create a keystore file. You can save it anywhere (preferably not in the `hifi` folder).
|
||||
|
||||
Create a `gradle.properties` file in $HOME/.gradle. Edit the file to contain the following
|
||||
### Set up machine specific Gradle properties
|
||||
|
||||
Create a `gradle.properties` file in the `.gradle` folder (`$HOME/.gradle` on Unix, `Users/<yourname>/.gradle` on Windows). Edit the file to contain the following
|
||||
|
||||
HIFI_ANDROID_PRECOMPILED=<your_home_directory>/Android/hifi_externals
|
||||
HIFI_ANDROID_KEYSTORE=<key_store_directory>/<keystore_name>.jks
|
||||
HIFI_ANDROID_KEYSTORE_PASSWORD=<password>
|
||||
HIFI_ANDROID_KEY_ALIAS=<key_alias>
|
||||
HIFI_ANDROID_KEY_PASSWORD=<key_passwords>
|
||||
|
||||
Note, do not use `$HOME` for the path. It must be a fully qualified path name.
|
||||
Note, do not use $HOME for the path. It must be a fully qualified path name. Also, be sure to use forward slashes in your path.
|
||||
|
||||
### Setup the repository
|
||||
#### If you are building for an Android phone
|
||||
|
||||
Clone the repository
|
||||
Add these lines to `gradle.properties`
|
||||
|
||||
`git clone https://github.com/highfidelity/hifi.git`
|
||||
SUPPRESS_QUEST_INTERFACE
|
||||
SUPPRESS_QUEST_FRAME_PLAYER
|
||||
|
||||
Enter the repository `android` directory
|
||||
#### If you are building for an Oculus Quest
|
||||
|
||||
`cd hifi/android`
|
||||
Add these lines to `gradle.properties`
|
||||
|
||||
Execute two gradle pre-build steps. This steps should only need to be done once, unless you're working on the Android dependencies
|
||||
SUPPRESS_INTERFACE
|
||||
SUPPRESS_FRAME_PLAYER
|
||||
|
||||
`./gradlew extractDependencies`
|
||||
The above code to suppress modules is not necessary, but will speed up the build process.
|
||||
|
||||
`./gradlew setupDependencies`
|
||||
### Clone the repository
|
||||
|
||||
`git clone https://github.com/highfidelity/hifi.git `
|
||||
|
||||
# Building & Running
|
||||
|
||||
* Open Android Studio
|
||||
* Choose _Open Existing Android Studio Project_
|
||||
* Navigate to the `hifi` repository and choose the `android` folder and select _OK_
|
||||
* From the _Build_ menu select _Make Project_
|
||||
* Once the build completes, from the _Run_ menu select _Run App_
|
||||
### Building Modules
|
||||
|
||||
* Open Android Studio
|
||||
* Choose _Open an existing Android Studio project_
|
||||
* Navigate to the `hifi` repository and choose the `android` folder and select _OK_
|
||||
* Wait for Gradle to sync (this should take around 20 minutes the first time)
|
||||
* From the _Build_ menu select _Make Project_
|
||||
|
||||
### Running a Module
|
||||
|
||||
* In the toolbar at the top of Android Studio, next to the green hammer icon, you should see a dropdown menu.
|
||||
* You may already see a configuration for the module you are trying to build. If so, select it.
|
||||
* Otherwise, select _Edit Configurations_.
|
||||
|
||||
Your configuration should be as follows
|
||||
|
||||
* Type: Android App
|
||||
* Module: <your module> (you probably want `interface` or `questInterface`)
|
||||
|
||||
For the interface modules, you also need to select the activity to launch.
|
||||
|
||||
#### For the Android phone interface
|
||||
|
||||
* From the _Launch_ drop down menu, select _Specified Activity_
|
||||
* In the _Activity_ field directly below, put `io.highfidelity.hifiinterface.PermissionChecker`
|
||||
|
||||
#### For the Oculus Quest interface
|
||||
|
||||
* From the _Launch_ drop down menu, select _Specified Activity_
|
||||
* In the _Activity_ field directly below, put `io.highfidelity.questInterface.PermissionsChecker`
|
||||
|
||||
Note the 's' in Permission**s**Checker for the Quest.
|
||||
|
||||
Now you are able to run your module! Click the green play button in the top toolbar of Android Studio
|
||||
r
|
||||
# Troubleshooting
|
||||
|
||||
To view a more complete debug log,
|
||||
|
||||
* Click the icon with the two overlapping squares in the upper left corner of the tab where the sync is running (hover text says _Toggle view_)
|
||||
* To change verbosity, click _File > Settings_. Under _Build, Execution, Deployment > Compiler_ you can add command-line flags, as per Gradle documentation
|
||||
|
||||
Some things you can try if you want to do a clean build
|
||||
|
||||
* Delete the `build` and `.externalNativeBuild` folders from the folder for each module you're building (for example, `hifi/android/apps/interface`)
|
||||
* If you have set your `HIFI_VCPKG_ROOT` environment variable, delete the contents of that directory; otherwise, delete `AppData/Local/Temp/hifi`
|
||||
* In Android Studio, click _File > Invalidate Caches / Restart_ and select _Invalidate and Restart_
|
||||
|
||||
If you see lots of "couldn't acquire lock" errors,
|
||||
* Open Task Manager and close any running Clang / Gradle processes
|
|
@ -1,65 +0,0 @@
|
|||
Please read the [general build guide](BUILD.md) for information on building other platform. Only Quest specific instructions are found in this file.
|
||||
|
||||
# Dependencies
|
||||
|
||||
Building is currently supported on OSX, Windows and Linux platforms, but developers intending to do work on the library dependencies are strongly urged to use 64 bit Linux as a build platform
|
||||
|
||||
You will need the following tools to build Android targets.
|
||||
|
||||
* [Android Studio](https://developer.android.com/studio/index.html)
|
||||
|
||||
### Android Studio
|
||||
|
||||
Download the Android Studio installer and run it. Once installed, at the welcome screen, click configure in the lower right corner and select SDK manager
|
||||
|
||||
From the SDK Platforms tab, select API levels 24 and 26.
|
||||
|
||||
From the SDK Tools tab select the following
|
||||
|
||||
* Android SDK Build-Tools
|
||||
* GPU Debugging Tools
|
||||
* CMake (even if you have a separate CMake installation)
|
||||
* LLDB
|
||||
* Android SDK Platform-Tools
|
||||
* Android SDK Tools
|
||||
* NDK (even if you have the NDK installed separately)
|
||||
|
||||
Make sure the NDK installed version is 18 (or higher)
|
||||
|
||||
# Environment
|
||||
|
||||
Setting up the environment for android builds requires some additional steps
|
||||
|
||||
#### Set up machine specific Gradle properties
|
||||
|
||||
Create a `gradle.properties` file in $HOME/.gradle. Edit the file to contain the following
|
||||
|
||||
HIFI_ANDROID_PRECOMPILED=<your_home_directory>/Android/hifi_externals
|
||||
HIFI_ANDROID_KEYSTORE=<key_store_directory>/<keystore_name>.jks
|
||||
HIFI_ANDROID_KEYSTORE_PASSWORD=<password>
|
||||
HIFI_ANDROID_KEY_ALIAS=<key_alias>
|
||||
HIFI_ANDROID_KEY_PASSWORD=<key_password>
|
||||
|
||||
Note, do not use `$HOME` for the path. It must be a fully qualified path name.
|
||||
|
||||
### Setup the repository
|
||||
|
||||
Clone the repository
|
||||
|
||||
`git clone https://github.com/highfidelity/hifi.git`
|
||||
|
||||
Enter the repository `android` directory
|
||||
|
||||
`cd hifi/android`
|
||||
|
||||
# Building & Running
|
||||
|
||||
* Open Android Studio
|
||||
* Choose _Open Existing Android Studio Project_
|
||||
* Navigate to the `hifi` repository and choose the `android` folder and select _OK_
|
||||
* Open Gradle.settings and comment out any projects not necessary
|
||||
* From _File_ menu select _Sync with File System_ to resync Gradle settings
|
||||
* From the _Build_ menu select _Make Project_
|
||||
* From
|
||||
* Once the build completes, from the _Run_ menu select _Run App_
|
||||
|
30
BUILD_WIN.md
30
BUILD_WIN.md
|
@ -1,18 +1,29 @@
|
|||
This is a stand-alone guide for creating your first High Fidelity build for Windows 64-bit.
|
||||
## Building High Fidelity
|
||||
Note: We are now using Visual Studio 2017 and Qt 5.12.3.
|
||||
Note: We are now using Visual Studio 2017 or 2019 and Qt 5.12.3.
|
||||
If you are upgrading from previous versions, do a clean uninstall of those versions before going through this guide.
|
||||
|
||||
Note: The prerequisites will require about 10 GB of space on your drive. You will also need a system with at least 8GB of main memory.
|
||||
|
||||
### Step 1. Visual Studio 2017 & Python
|
||||
### Step 1. Visual Studio & Python
|
||||
|
||||
If you don’t have Community or Professional edition of Visual Studio 2017, download [Visual Studio Community 2017](https://www.visualstudio.com/downloads/).
|
||||
If you don’t have Community or Professional edition of Visual Studio, download [Visual Studio Community 2019](https://visualstudio.microsoft.com/vs/). If you have Visual Studio 2017, you are not required to download Visual Studio 2019.
|
||||
|
||||
Leave default components.
|
||||
If you do not already have a python development environment installed, also check "Python Development" in this screen.
|
||||
When selecting components, check "Desktop development with C++". On the right on the Summary toolbar, select the following components.
|
||||
|
||||
If you already have Visual Studio installed and need to add python, open the "Add or remove programs" control panel and find the "Microsoft Visual Studio Installer". Select it and click "Modify". In the installer, select "Modify" again, then check "Python Development" and allow the installer to apply the changes.
|
||||
#### If you're installing Visual Studio 2017,
|
||||
|
||||
* Windows 8.1 SDK and UCRT SDK
|
||||
* VC++ 2015.3 v14.00 (v140) toolset for desktop
|
||||
|
||||
#### If you're installing Visual Studio 2019,
|
||||
|
||||
* MSVC v141 - VS 2017 C++ x64/x86 build tools
|
||||
* MSVC v140 - VS 2015 C++ build tools (v14.00)
|
||||
|
||||
If you do not already have a Python development environment installed, also check "Python Development" in this screen.
|
||||
|
||||
If you already have Visual Studio installed and need to add Python, open the "Add or remove programs" control panel and find the "Microsoft Visual Studio Installer". Select it and click "Modify". In the installer, select "Modify" again, then check "Python Development" and allow the installer to apply the changes.
|
||||
|
||||
### Step 1a. Alternate Python
|
||||
|
||||
|
@ -29,7 +40,12 @@ Run Command Prompt from Start and run the following commands:
|
|||
`cd "%HIFI_DIR%"`
|
||||
`mkdir build`
|
||||
`cd build`
|
||||
`cmake .. -G "Visual Studio 15 Win64"`
|
||||
|
||||
#### If you're using Visual Studio 2017,
|
||||
Run `cmake .. -G "Visual Studio 15 Win64"`.
|
||||
|
||||
#### If you're using Visual Studio 2019,
|
||||
Run `cmake .. -G "Visual Studio 16 2019" -A x64`.
|
||||
|
||||
Where `%HIFI_DIR%` is the directory for the highfidelity repository.
|
||||
|
||||
|
|
|
@ -428,7 +428,7 @@ void AvatarMixerClientData::resetSentTraitData(Node::LocalID nodeLocalID) {
|
|||
_lastSentTraitsTimestamps[nodeLocalID] = TraitsCheckTimestamp();
|
||||
_perNodeSentTraitVersions[nodeLocalID].reset();
|
||||
_perNodeAckedTraitVersions[nodeLocalID].reset();
|
||||
for (auto && pendingTraitVersions : _perNodePendingTraitVersions) {
|
||||
for (auto&& pendingTraitVersions : _perNodePendingTraitVersions) {
|
||||
pendingTraitVersions.second[nodeLocalID].reset();
|
||||
}
|
||||
}
|
||||
|
@ -488,4 +488,8 @@ void AvatarMixerClientData::cleanupKilledNode(const QUuid&, Node::LocalID nodeLo
|
|||
removeLastBroadcastTime(nodeLocalID);
|
||||
_lastSentTraitsTimestamps.erase(nodeLocalID);
|
||||
_perNodeSentTraitVersions.erase(nodeLocalID);
|
||||
_perNodeAckedTraitVersions.erase(nodeLocalID);
|
||||
for (auto&& pendingTraitVersions : _perNodePendingTraitVersions) {
|
||||
pendingTraitVersions.second.erase(nodeLocalID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,13 +52,12 @@ macro(setup_qt)
|
|||
message(FATAL_ERROR "VCPKG_QT_CMAKE_PREFIX_PATH should have been set by hifi_vcpkg.py")
|
||||
endif()
|
||||
if (NOT DEV_BUILD)
|
||||
if (APPLE)
|
||||
# HACK: manually set the QT_CMAKE_PREFIX_PATH so that hard-coded paths find new QT libs where we'll put them
|
||||
set(QT_CMAKE_PREFIX_PATH "/var/tmp/qt5-install/lib/cmake")
|
||||
elseif (UNIX AND DEFINED ENV{QT_CMAKE_PREFIX_PATH})
|
||||
if (UNIX AND DEFINED ENV{QT_CMAKE_PREFIX_PATH} AND NOT APPLE)
|
||||
# HACK: obey QT_CMAKE_PREFIX_PATH to allow UNIX to use older QT libs
|
||||
message("HACK: obey QT_CMAKE_PREFIX_PATH on UNIX")
|
||||
set(QT_CMAKE_PREFIX_PATH $ENV{QT_CMAKE_PREFIX_PATH})
|
||||
else()
|
||||
message("override QT_CMAKE_PREFIX_PATH with VCPKG_QT_CMAKE_PREFIX_PATH")
|
||||
set(QT_CMAKE_PREFIX_PATH ${VCPKG_QT_CMAKE_PREFIX_PATH})
|
||||
endif()
|
||||
else()
|
||||
|
@ -70,6 +69,8 @@ macro(setup_qt)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
message("QT_CMAKE_PREFIX_PATH = " ${QT_CMAKE_PREFIX_PATH})
|
||||
|
||||
# figure out where the qt dir is
|
||||
get_filename_component(QT_DIR "${QT_CMAKE_PREFIX_PATH}/../../" ABSOLUTE)
|
||||
set(QT_VERSION "unknown")
|
||||
|
|
|
@ -53,5 +53,7 @@
|
|||
</array>
|
||||
<key>NSHighResolutionCapable</key>
|
||||
<true/>
|
||||
<key>NSMicrophoneUsageDescription</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
# VCPKG_ROOT_DIR = <C:\path\to\current\vcpkg>
|
||||
# VCPKG_TARGET_ARCHITECTURE = target architecture (x64, x86, arm)
|
||||
#
|
||||
#
|
||||
|
||||
include(vcpkg_common_functions)
|
||||
|
||||
if (VCPKG_LIBRARY_LINKAGE STREQUAL dynamic)
|
||||
|
@ -25,14 +27,13 @@ vcpkg_from_github(
|
|||
HEAD_REF master
|
||||
)
|
||||
|
||||
|
||||
vcpkg_configure_cmake(
|
||||
SOURCE_PATH ${SOURCE_PATH}
|
||||
OPTIONS
|
||||
-DCMAKE_WINDOWS_EXPORT_ALL_SYMBOLS=ON
|
||||
-DUSE_MSVC_RUNTIME_LIBRARY_DLL=ON
|
||||
-DUSE_GLUT=0
|
||||
-DUSE_DX11=0
|
||||
-DUSE_GLUT=0
|
||||
-DUSE_DX11=0
|
||||
-DBUILD_DEMOS=OFF
|
||||
-DBUILD_OPENGL3_DEMOS=OFF
|
||||
-DBUILD_BULLET3=OFF
|
||||
|
|
|
@ -128,7 +128,7 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
|
|||
|
||||
// signal that we just connected a node so the DomainServer can get it a list
|
||||
// and broadcast its presence right away
|
||||
emit connectedNode(node);
|
||||
emit connectedNode(node, message->getFirstPacketReceiveTime());
|
||||
} else {
|
||||
qDebug() << "Refusing connection from node at" << message->getSenderSockAddr()
|
||||
<< "with hardware address" << nodeConnection.hardwareAddress
|
||||
|
@ -358,6 +358,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo
|
|||
nodeData->setNodeVersion(it->second.getNodeVersion());
|
||||
nodeData->setHardwareAddress(nodeConnection.hardwareAddress);
|
||||
nodeData->setMachineFingerprint(nodeConnection.machineFingerprint);
|
||||
// client-side send time of last connect/domain list request
|
||||
nodeData->setLastDomainCheckinTimestamp(nodeConnection.lastPingTimestamp);
|
||||
nodeData->setWasAssigned(true);
|
||||
|
||||
|
@ -499,7 +500,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
|
|||
// set the machine fingerprint passed in the connect request
|
||||
nodeData->setMachineFingerprint(nodeConnection.machineFingerprint);
|
||||
|
||||
// set the last ping timestamp passed in the connect request
|
||||
// set client-side send time of last connect/domain list request
|
||||
nodeData->setLastDomainCheckinTimestamp(nodeConnection.lastPingTimestamp);
|
||||
|
||||
// also add an interpolation to DomainServerNodeData so that servers can get username in stats
|
||||
|
|
|
@ -64,7 +64,7 @@ public slots:
|
|||
|
||||
signals:
|
||||
void killNode(SharedNodePointer node);
|
||||
void connectedNode(SharedNodePointer node);
|
||||
void connectedNode(SharedNodePointer node, quint64 requestReceiveTime);
|
||||
|
||||
public slots:
|
||||
void updateNodePermissions();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include <memory>
|
||||
#include <random>
|
||||
#include <iostream>
|
||||
#include <chrono>
|
||||
|
||||
#include <QDir>
|
||||
#include <QJsonDocument>
|
||||
|
@ -57,6 +58,8 @@
|
|||
|
||||
#include <OctreeDataUtils.h>
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
Q_LOGGING_CATEGORY(domain_server, "hifi.domain_server")
|
||||
Q_LOGGING_CATEGORY(domain_server_ice, "hifi.domain_server.ice")
|
||||
|
||||
|
@ -1068,9 +1071,10 @@ void DomainServer::processListRequestPacket(QSharedPointer<ReceivedMessage> mess
|
|||
// update the connecting hostname in case it has changed
|
||||
nodeData->setPlaceName(nodeRequestData.placeName);
|
||||
|
||||
// client-side send time of last connect/domain list request
|
||||
nodeData->setLastDomainCheckinTimestamp(nodeRequestData.lastPingTimestamp);
|
||||
|
||||
sendDomainListToNode(sendingNode, message->getSenderSockAddr());
|
||||
sendDomainListToNode(sendingNode, message->getFirstPacketReceiveTime(), message->getSenderSockAddr());
|
||||
}
|
||||
|
||||
bool DomainServer::isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB) {
|
||||
|
@ -1132,11 +1136,11 @@ QUrl DomainServer::oauthAuthorizationURL(const QUuid& stateUUID) {
|
|||
return authorizationURL;
|
||||
}
|
||||
|
||||
void DomainServer::handleConnectedNode(SharedNodePointer newNode) {
|
||||
void DomainServer::handleConnectedNode(SharedNodePointer newNode, quint64 requestReceiveTime) {
|
||||
DomainServerNodeData* nodeData = static_cast<DomainServerNodeData*>(newNode->getLinkedData());
|
||||
|
||||
// reply back to the user with a PacketType::DomainList
|
||||
sendDomainListToNode(newNode, nodeData->getSendingSockAddr());
|
||||
sendDomainListToNode(newNode, requestReceiveTime, nodeData->getSendingSockAddr());
|
||||
|
||||
// if this node is a user (unassigned Agent), signal
|
||||
if (newNode->getType() == NodeType::Agent && !nodeData->wasAssigned()) {
|
||||
|
@ -1152,7 +1156,7 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode) {
|
|||
broadcastNewNode(newNode);
|
||||
}
|
||||
|
||||
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr) {
|
||||
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr &senderSockAddr) {
|
||||
const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID +
|
||||
NUM_BYTES_RFC4122_UUID + NLPacket::NUM_BYTES_LOCALID + 4;
|
||||
|
||||
|
@ -1160,7 +1164,7 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
// this data is at the beginning of each of the domain list packets
|
||||
QByteArray extendedHeader(NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES, 0);
|
||||
QDataStream extendedHeaderStream(&extendedHeader, QIODevice::WriteOnly);
|
||||
|
||||
DomainServerNodeData* nodeData = static_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||
auto limitedNodeList = DependencyManager::get<LimitedNodeList>();
|
||||
|
||||
extendedHeaderStream << limitedNodeList->getSessionUUID();
|
||||
|
@ -1169,17 +1173,14 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
|
|||
extendedHeaderStream << node->getLocalID();
|
||||
extendedHeaderStream << node->getPermissions();
|
||||
extendedHeaderStream << limitedNodeList->getAuthenticatePackets();
|
||||
extendedHeaderStream << nodeData->getLastDomainCheckinTimestamp();
|
||||
extendedHeaderStream << quint64(duration_cast<microseconds>(system_clock::now().time_since_epoch()).count());
|
||||
extendedHeaderStream << quint64(duration_cast<microseconds>(p_high_resolution_clock::now().time_since_epoch()).count()) - requestPacketReceiveTime;
|
||||
auto domainListPackets = NLPacketList::create(PacketType::DomainList, extendedHeader);
|
||||
|
||||
// always send the node their own UUID back
|
||||
QDataStream domainListStream(domainListPackets.get());
|
||||
|
||||
DomainServerNodeData* nodeData = static_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||
|
||||
domainListStream << nodeData->getLastDomainCheckinTimestamp();
|
||||
|
||||
domainListStream << usecTimestampNow();
|
||||
|
||||
// store the nodeInterestSet on this DomainServerNodeData, in case it has changed
|
||||
auto& nodeInterestSet = nodeData->getNodeInterestSet();
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ private slots:
|
|||
void sendHeartbeatToMetaverse() { sendHeartbeatToMetaverse(QString()); }
|
||||
void sendHeartbeatToIceServer();
|
||||
|
||||
void handleConnectedNode(SharedNodePointer newNode);
|
||||
void handleConnectedNode(SharedNodePointer newNode, quint64 requestReceiveTime);
|
||||
void handleTempDomainSuccess(QNetworkReply* requestReply);
|
||||
void handleTempDomainError(QNetworkReply* requestReply);
|
||||
|
||||
|
@ -172,7 +172,7 @@ private:
|
|||
void handleKillNode(SharedNodePointer nodeToKill);
|
||||
void broadcastNodeDisconnect(const SharedNodePointer& disconnnectedNode);
|
||||
|
||||
void sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr& senderSockAddr);
|
||||
void sendDomainListToNode(const SharedNodePointer& node, quint64 requestPacketReceiveTime, const HifiSockAddr& senderSockAddr);
|
||||
|
||||
bool isInInterestSet(const SharedNodePointer& nodeA, const SharedNodePointer& nodeB);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
bool isConnectRequest = true);
|
||||
|
||||
QUuid connectUUID;
|
||||
quint64 lastPingTimestamp{ 0 };
|
||||
quint64 lastPingTimestamp{ 0 }; // client-side send time of last connect/domain list request
|
||||
NodeType_t nodeType;
|
||||
HifiSockAddr publicSockAddr;
|
||||
HifiSockAddr localSockAddr;
|
||||
|
|
|
@ -214,12 +214,8 @@ endif()
|
|||
f.write(self.tagContents)
|
||||
|
||||
def getQt5InstallPath(self):
|
||||
qt5InstallPath = os.path.join(self.path, 'installed', 'qt5-install')
|
||||
if platform.system() == "Darwin" and self.args.release_type != "DEV":
|
||||
# HACK for MacOS Jenkins PRODUCTION and PR builds during Qt-5.12.3 transition
|
||||
# we always supply /var/tmp/qt5-install for QT_CMAKE_PREFIX_PATH
|
||||
qt5InstallPath = "/var/tmp/qt5-install"
|
||||
elif self.args.android:
|
||||
qt5InstallPath = os.path.join(self.path, 'installed', 'qt5-install')
|
||||
if self.args.android:
|
||||
precompiled = os.path.realpath(self.androidPackagePath)
|
||||
qt5InstallPath = os.path.realpath(os.path.join(precompiled, 'qt'))
|
||||
return qt5InstallPath
|
||||
|
@ -258,18 +254,13 @@ endif()
|
|||
|
||||
url = 'NOT DEFINED'
|
||||
if platform.system() == 'Windows':
|
||||
# TODO: figure out how to download with versionId
|
||||
#url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows.tar.gz?versionId=Etx8novAe0.IxQ7AosLFtop7fZur.cx9'
|
||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows.tar.gz'
|
||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-windows2.tar.gz'
|
||||
elif platform.system() == 'Darwin':
|
||||
#url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos.tar.gz?versionId=QrGxwssB.WwU_z3QCyG7ghP1_VjTkQeK'
|
||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos.tar.gz'
|
||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-macos2.tar.gz'
|
||||
elif platform.system() == 'Linux':
|
||||
if platform.linux_distribution()[1] == '16.04':
|
||||
#url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04.tar.gz?versionId=c9j7PW4uBDPLif7DKmgIhorh9WBMjZRB'
|
||||
if platform.linux_distribution()[1][:3] == '16.':
|
||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-16.04.tar.gz'
|
||||
elif platform.linux_distribution()[1] == '18.04':
|
||||
#url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz?versionId=Z3TojPFdb5pXdahF3oi85jjKocpL0xqw'
|
||||
elif platform.linux_distribution()[1][:3] == '18.':
|
||||
url = 'https://hifi-public.s3.amazonaws.com/dependencies/vcpkg/qt5-install-5.12.3-ubuntu-18.04.tar.gz'
|
||||
else:
|
||||
print('UNKNOWN LINUX VERSION!!!')
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 548 KiB |
Binary file not shown.
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"compressed": {
|
||||
"COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT": "Default-Sky-9-cubemap-ambient_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT.ktx",
|
||||
"COMPRESSED_SRGB8_ETC2": "Default-Sky-9-cubemap-ambient_COMPRESSED_SRGB8_ETC2.ktx"
|
||||
},
|
||||
"original": "Default-Sky-9-cubemap-ambient.jpg",
|
||||
"uncompressed": "Default-Sky-9-cubemap-ambient.ktx",
|
||||
"version": 1
|
||||
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -4,5 +4,6 @@
|
|||
"COMPRESSED_SRGB8_ETC2": "Default-Sky-9-cubemap_COMPRESSED_SRGB8_ETC2.ktx"
|
||||
},
|
||||
"original": "Default-Sky-9-cubemap.jpg",
|
||||
"uncompressed": "Default-Sky-9-cubemap.ktx"
|
||||
"uncompressed": "Default-Sky-9-cubemap.ktx",
|
||||
"version": 1
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -12,6 +12,7 @@ import QtQuick 2.10
|
|||
import "../simplifiedConstants" as SimplifiedConstants
|
||||
import "./components" as AvatarAppComponents
|
||||
import stylesUit 1.0 as HifiStylesUit
|
||||
import TabletScriptingInterface 1.0
|
||||
import "qrc:////qml//hifi//models" as HifiModels // Absolute path so the same code works everywhere.
|
||||
|
||||
Rectangle {
|
||||
|
@ -76,7 +77,7 @@ Rectangle {
|
|||
if (result.status !== "success") {
|
||||
errorText.text = "There was a problem while retrieving your inventory. " +
|
||||
"Please try closing and re-opening the Avatar app.\n\nInventory status: " + result.status + "\nMessage: " + result.message;
|
||||
} else if (result.data && result.data.assets && result.data.assets.length === 0) {
|
||||
} else if (result.data && result.data.assets && result.data.assets.length === 0 && avatarAppInventoryModel.count === 0) {
|
||||
errorText.text = "You have not created any avatars yet! Create an avatar with the Avatar Creator, then close and re-open the Avatar App."
|
||||
}
|
||||
|
||||
|
@ -99,6 +100,33 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: homeButton
|
||||
source: "images/homeIcon.svg"
|
||||
opacity: homeButtonMouseArea.containsMouse ? 1.0 : 0.7
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: 15
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 24
|
||||
width: 14
|
||||
height: 13
|
||||
|
||||
MouseArea {
|
||||
id: homeButtonMouseArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onEntered: {
|
||||
Tablet.playSound(TabletEnums.ButtonHover);
|
||||
}
|
||||
onClicked: {
|
||||
Tablet.playSound(TabletEnums.ButtonClick);
|
||||
// Can't use `Window.location` in QML, so just use what setting `Window.location` actually calls under the hood:
|
||||
// AddressManager.handleLookupString().
|
||||
AddressManager.handleLookupString(LocationBookmarks.getHomeLocationAddress());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AvatarAppComponents.DisplayNameHeader {
|
||||
id: displayNameHeader
|
||||
previewUrl: root.avatarPreviewUrl
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<svg width="14" height="13" viewBox="0 0 14 13" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0.546497 6.46222C0.68683 6.52762 0.841945 6.5522 0.994929 6.53328C1.08986 6.5539 1.18806 6.55265 1.28246 6.52963C1.37687 6.50661 1.46514 6.46239 1.54094 6.40015L3.30854 5.1924L7.13987 2.44404L12.4889 6.38113C12.5827 6.46758 12.6942 6.53129 12.8152 6.56759C12.9361 6.60388 13.0634 6.61183 13.1878 6.59084C13.3121 6.56985 13.4303 6.52046 13.5336 6.44631C13.6369 6.37216 13.7226 6.27514 13.7846 6.1624C13.8688 6.06517 13.9308 5.94985 13.9662 5.82485C14.0015 5.69986 14.0093 5.56833 13.9889 5.43987C13.9685 5.3114 13.9205 5.18923 13.8483 5.08225C13.7761 4.97528 13.6816 4.88619 13.5717 4.8215L7.13987 0L2.21652 3.5662L0.485918 4.75494C-0.0415861 5.04974 -0.143383 5.51573 0.199032 6.1624C0.285979 6.29313 0.406165 6.39683 0.546497 6.46222Z" fill="white"/>
|
||||
<path d="M6.99182 4.97367L10.3142 7.35113L11.9059 8.53987V13H2.15174V8.38771L3.7435 7.27505L6.99182 4.97367Z" fill="white"/>
|
||||
</svg>
|
After Width: | Height: | Size: 990 B |
|
@ -60,7 +60,7 @@ Flickable {
|
|||
HifiStylesUit.GraphikRegular {
|
||||
id: volumeControlsTitle
|
||||
text: "Volume Controls"
|
||||
Layout.maximumWidth: parent.width
|
||||
Layout.preferredWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 22
|
||||
color: simplifiedUI.colors.text.white
|
||||
|
@ -68,10 +68,9 @@ Flickable {
|
|||
|
||||
SimplifiedControls.Slider {
|
||||
id: peopleVolume
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: 30
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
height: 30
|
||||
labelText: "People Volume"
|
||||
from: simplifiedUI.numericConstants.mutedValue
|
||||
to: 20.0
|
||||
|
@ -96,10 +95,9 @@ Flickable {
|
|||
|
||||
SimplifiedControls.Slider {
|
||||
id: environmentVolume
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: 30
|
||||
Layout.topMargin: 2
|
||||
height: 30
|
||||
labelText: "Environment Volume"
|
||||
from: simplifiedUI.numericConstants.mutedValue
|
||||
to: 20.0
|
||||
|
@ -125,10 +123,9 @@ Flickable {
|
|||
|
||||
SimplifiedControls.Slider {
|
||||
id: systemSoundVolume
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: 30
|
||||
Layout.topMargin: 2
|
||||
height: 30
|
||||
labelText: "System Sound Volume"
|
||||
from: simplifiedUI.numericConstants.mutedValue
|
||||
to: 20.0
|
||||
|
@ -172,8 +169,8 @@ Flickable {
|
|||
|
||||
SimplifiedControls.Switch {
|
||||
id: muteMicrophoneSwitch
|
||||
width: parent.width
|
||||
height: 18
|
||||
Layout.preferredHeight: 18
|
||||
Layout.preferredWidth: parent.width
|
||||
labelTextOn: "Mute Microphone"
|
||||
checked: AudioScriptingInterface.mutedDesktop
|
||||
onClicked: {
|
||||
|
@ -183,8 +180,8 @@ Flickable {
|
|||
|
||||
SimplifiedControls.Switch {
|
||||
id: pushToTalkSwitch
|
||||
width: parent.width
|
||||
height: 18
|
||||
Layout.preferredHeight: 18
|
||||
Layout.preferredWidth: parent.width
|
||||
labelTextOn: "Push to Talk - Press and Hold \"T\" to Talk"
|
||||
checked: AudioScriptingInterface.pushToTalkDesktop
|
||||
onClicked: {
|
||||
|
@ -212,11 +209,10 @@ Flickable {
|
|||
|
||||
ListView {
|
||||
id: inputDeviceListView
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: contentItem.height
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
interactive: false
|
||||
height: contentItem.height
|
||||
spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons
|
||||
clip: true
|
||||
model: AudioScriptingInterface.devices.input
|
||||
|
@ -228,7 +224,7 @@ Flickable {
|
|||
id: inputDeviceCheckbox
|
||||
anchors.left: parent.left
|
||||
width: parent.width - inputLevel.width
|
||||
height: paintedHeight
|
||||
height: 16
|
||||
wrapLabel: false
|
||||
checked: selectedDesktop
|
||||
text: model.devicename
|
||||
|
@ -251,6 +247,7 @@ Flickable {
|
|||
}
|
||||
|
||||
SimplifiedControls.Button {
|
||||
id: audioLoopbackButton
|
||||
property bool audioLoopedBack: AudioScriptingInterface.getLocalEcho()
|
||||
|
||||
function startAudioLoopback() {
|
||||
|
@ -266,29 +263,23 @@ Flickable {
|
|||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: loopbackTimer
|
||||
interval: 8000
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
Component.onDestruction: stopAudioLoopback();
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
stopAudioLoopback();
|
||||
}
|
||||
}
|
||||
|
||||
id: testYourMicButton
|
||||
enabled: !HMD.active
|
||||
anchors.left: parent.left
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
width: 160
|
||||
height: 32
|
||||
text: audioLoopedBack ? "STOP TESTING" : "TEST YOUR MIC"
|
||||
onClicked: {
|
||||
if (audioLoopedBack) {
|
||||
loopbackTimer.stop();
|
||||
stopAudioLoopback();
|
||||
} else {
|
||||
loopbackTimer.restart();
|
||||
startAudioLoopback();
|
||||
}
|
||||
}
|
||||
|
@ -313,11 +304,10 @@ Flickable {
|
|||
|
||||
ListView {
|
||||
id: outputDeviceListView
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: contentItem.height
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
interactive: false
|
||||
height: contentItem.height
|
||||
spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons
|
||||
clip: true
|
||||
model: AudioScriptingInterface.devices.output
|
||||
|
@ -329,7 +319,7 @@ Flickable {
|
|||
id: outputDeviceCheckbox
|
||||
anchors.left: parent.left
|
||||
width: parent.width
|
||||
height: paintedHeight
|
||||
height: 16
|
||||
checked: selectedDesktop
|
||||
text: model.devicename
|
||||
wrapLabel: false
|
||||
|
@ -381,7 +371,6 @@ Flickable {
|
|||
|
||||
id: testYourSoundButton
|
||||
enabled: !HMD.active
|
||||
anchors.left: parent.left
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
width: 160
|
||||
height: 32
|
||||
|
|
|
@ -101,7 +101,7 @@ Flickable {
|
|||
|
||||
HifiStylesUit.GraphikRegular {
|
||||
id: performanceTitle
|
||||
text: "Performance"
|
||||
text: "Graphics Preset"
|
||||
Layout.maximumWidth: parent.width
|
||||
height: paintedHeight
|
||||
size: 22
|
||||
|
@ -115,28 +115,28 @@ Flickable {
|
|||
|
||||
SimplifiedControls.RadioButton {
|
||||
id: performanceLow
|
||||
text: "Eco"
|
||||
checked: Performance.getRefreshRateProfile() === RefreshRate.ECO
|
||||
text: "Low"
|
||||
checked: Performance.getPerformancePreset() === PerformanceEnums.LOW
|
||||
onClicked: {
|
||||
Performance.setRefreshRateProfile(RefreshRate.ECO);
|
||||
Performance.setPerformancePreset(PerformanceEnums.LOW);
|
||||
}
|
||||
}
|
||||
|
||||
SimplifiedControls.RadioButton {
|
||||
id: performanceMedium
|
||||
text: "Interactive"
|
||||
checked: Performance.getRefreshRateProfile() === RefreshRate.INTERACTIVE
|
||||
text: "Medium"
|
||||
checked: Performance.getPerformancePreset() === PerformanceEnums.MID
|
||||
onClicked: {
|
||||
Performance.setRefreshRateProfile(RefreshRate.INTERACTIVE);
|
||||
Performance.setPerformancePreset(PerformanceEnums.MID);
|
||||
}
|
||||
}
|
||||
|
||||
SimplifiedControls.RadioButton {
|
||||
id: performanceHigh
|
||||
text: "Realtime"
|
||||
checked: Performance.getRefreshRateProfile() === RefreshRate.REALTIME
|
||||
text: "High"
|
||||
checked: Performance.getPerformancePreset() === PerformanceEnums.HIGH
|
||||
onClicked: {
|
||||
Performance.setRefreshRateProfile(RefreshRate.REALTIME);
|
||||
Performance.setPerformancePreset(PerformanceEnums.HIGH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,11 +198,10 @@ Flickable {
|
|||
|
||||
ListView {
|
||||
id: inputDeviceListView
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: contentItem.height
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
interactive: false
|
||||
height: contentItem.height
|
||||
spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons
|
||||
clip: true
|
||||
model: AudioScriptingInterface.devices.input
|
||||
|
@ -214,8 +213,10 @@ Flickable {
|
|||
id: inputDeviceCheckbox
|
||||
anchors.left: parent.left
|
||||
width: parent.width - inputLevel.width
|
||||
height: 16
|
||||
checked: selectedHMD
|
||||
text: model.devicename
|
||||
wrapLabel: false
|
||||
ButtonGroup.group: inputDeviceButtonGroup
|
||||
onClicked: {
|
||||
AudioScriptingInterface.setStereoInput(false); // the next selected audio device might not support stereo
|
||||
|
@ -235,6 +236,7 @@ Flickable {
|
|||
}
|
||||
|
||||
SimplifiedControls.Button {
|
||||
id: audioLoopbackButton
|
||||
property bool audioLoopedBack: AudioScriptingInterface.getLocalEcho()
|
||||
|
||||
function startAudioLoopback() {
|
||||
|
@ -250,29 +252,23 @@ Flickable {
|
|||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: loopbackTimer
|
||||
interval: 8000
|
||||
running: false
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
Component.onDestruction: stopAudioLoopback();
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
stopAudioLoopback();
|
||||
}
|
||||
}
|
||||
|
||||
id: testYourMicButton
|
||||
enabled: HMD.active
|
||||
anchors.left: parent.left
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
width: 160
|
||||
height: 32
|
||||
text: audioLoopedBack ? "STOP TESTING" : "TEST YOUR MIC"
|
||||
onClicked: {
|
||||
if (audioLoopedBack) {
|
||||
loopbackTimer.stop();
|
||||
stopAudioLoopback();
|
||||
} else {
|
||||
loopbackTimer.restart();
|
||||
startAudioLoopback();
|
||||
}
|
||||
}
|
||||
|
@ -297,11 +293,10 @@ Flickable {
|
|||
|
||||
ListView {
|
||||
id: outputDeviceListView
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: contentItem.height
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
interactive: false
|
||||
height: contentItem.height
|
||||
spacing: simplifiedUI.margins.settings.spacingBetweenRadiobuttons
|
||||
clip: true
|
||||
model: AudioScriptingInterface.devices.output
|
||||
|
@ -313,11 +308,13 @@ Flickable {
|
|||
id: outputDeviceCheckbox
|
||||
anchors.left: parent.left
|
||||
width: parent.width
|
||||
checked: selectedDesktop
|
||||
height: 16
|
||||
checked: selectedHMD
|
||||
text: model.devicename
|
||||
wrapLabel: false
|
||||
ButtonGroup.group: outputDeviceButtonGroup
|
||||
onClicked: {
|
||||
AudioScriptingInterface.setOutputDevice(model.info, true); // `false` argument for Desktop mode setting
|
||||
AudioScriptingInterface.setOutputDevice(model.info, true); // `true` argument for VR mode setting
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -363,7 +360,6 @@ Flickable {
|
|||
|
||||
id: testYourSoundButton
|
||||
enabled: HMD.active
|
||||
anchors.left: parent.left
|
||||
Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin
|
||||
width: 160
|
||||
height: 32
|
||||
|
|
|
@ -70,8 +70,6 @@ Item {
|
|||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
root.checkedChanged();
|
||||
Tablet.playSound(TabletEnums.ButtonClick);
|
||||
originalSwitch.changeColor();
|
||||
}
|
||||
|
||||
|
|
|
@ -1312,8 +1312,16 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
accountManager->setAuthURL(NetworkingConstants::METAVERSE_SERVER_URL());
|
||||
|
||||
// use our MyAvatar position and quat for address manager path
|
||||
addressManager->setPositionGetter([this]{ return getMyAvatar()->getWorldFeetPosition(); });
|
||||
addressManager->setOrientationGetter([this]{ return getMyAvatar()->getWorldOrientation(); });
|
||||
addressManager->setPositionGetter([this] {
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr;
|
||||
return myAvatar ? myAvatar->getWorldFeetPosition() : Vectors::ZERO;
|
||||
});
|
||||
addressManager->setOrientationGetter([this] {
|
||||
auto avatarManager = DependencyManager::get<AvatarManager>();
|
||||
auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr;
|
||||
return myAvatar ? myAvatar->getWorldOrientation() : glm::quat();
|
||||
});
|
||||
|
||||
connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle);
|
||||
connect(this, &QCoreApplication::aboutToQuit, addressManager.data(), &AddressManager::storeCurrentAddress);
|
||||
|
@ -3325,6 +3333,7 @@ void Application::onDesktopRootContextCreated(QQmlContext* surfaceContext) {
|
|||
surfaceContext->setContextProperty("HMD", DependencyManager::get<HMDScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("Scene", DependencyManager::get<SceneScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("Render", RenderScriptingInterface::getInstance());
|
||||
surfaceContext->setContextProperty("PlatformInfo", PlatformInfoScriptingInterface::getInstance());
|
||||
surfaceContext->setContextProperty("Workload", _gameWorkload._engine->getConfiguration().get());
|
||||
surfaceContext->setContextProperty("Reticle", getApplicationCompositor().getReticleInterface());
|
||||
surfaceContext->setContextProperty("Snapshot", DependencyManager::get<Snapshot>().data());
|
||||
|
@ -3448,6 +3457,7 @@ void Application::setupQmlSurface(QQmlContext* surfaceContext, bool setAdditiona
|
|||
surfaceContext->setContextProperty("HiFiAbout", AboutUtil::getInstance());
|
||||
surfaceContext->setContextProperty("WalletScriptingInterface", DependencyManager::get<WalletScriptingInterface>().data());
|
||||
surfaceContext->setContextProperty("ResourceRequestObserver", DependencyManager::get<ResourceRequestObserver>().data());
|
||||
surfaceContext->setContextProperty("PlatformInfo", PlatformInfoScriptingInterface::getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3803,10 +3813,14 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
|
|||
|
||||
// If this is a first run we short-circuit the address passed in
|
||||
if (_firstRun.get()) {
|
||||
DependencyManager::get<AddressManager>()->goToEntry();
|
||||
sentTo = SENT_TO_ENTRY;
|
||||
_firstRun.set(false);
|
||||
|
||||
if (!_overrideEntry) {
|
||||
DependencyManager::get<AddressManager>()->goToEntry();
|
||||
sentTo = SENT_TO_ENTRY;
|
||||
} else {
|
||||
DependencyManager::get<AddressManager>()->loadSettings(addressLookupString);
|
||||
sentTo = SENT_TO_PREVIOUS_LOCATION;
|
||||
}
|
||||
_firstRun.set(false);
|
||||
} else {
|
||||
QString goingTo = "";
|
||||
if (addressLookupString.isEmpty()) {
|
||||
|
@ -3822,7 +3836,7 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
|
|||
DependencyManager::get<AddressManager>()->loadSettings(addressLookupString);
|
||||
sentTo = SENT_TO_PREVIOUS_LOCATION;
|
||||
}
|
||||
|
||||
|
||||
UserActivityLogger::getInstance().logAction("startup_sent_to", {
|
||||
{ "sent_to", sentTo },
|
||||
{ "sandbox_is_running", sandboxIsRunning },
|
||||
|
@ -4152,8 +4166,14 @@ bool Application::eventFilter(QObject* object, QEvent* event) {
|
|||
}
|
||||
|
||||
if (event->type() == QEvent::WindowStateChange) {
|
||||
if (getWindow()->windowState() == Qt::WindowMinimized) {
|
||||
if (getWindow()->windowState() & Qt::WindowMinimized) {
|
||||
getRefreshRateManager().setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::MINIMIZED);
|
||||
} else {
|
||||
auto* windowStateChangeEvent = static_cast<QWindowStateChangeEvent*>(event);
|
||||
if (windowStateChangeEvent->oldState() & Qt::WindowMinimized) {
|
||||
getRefreshRateManager().setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE);
|
||||
getRefreshRateManager().resetInactiveTimer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5358,6 +5378,26 @@ void Application::loadSettings() {
|
|||
}
|
||||
}
|
||||
|
||||
if (_firstRun.get()) {
|
||||
// If this is our first run, evalute the Platform Tier and assign the matching Performance profile by default.
|
||||
// A bunch of Performance, Simulation and Render settings will be set to a matching default value from this
|
||||
|
||||
// Here is the mapping between pelatformTIer and performance profile
|
||||
const std::array<PerformanceManager::PerformancePreset, platform::Profiler::NumTiers> platformToPerformancePresetMap = {{
|
||||
PerformanceManager::PerformancePreset::MID, // platform::Profiler::UNKNOWN
|
||||
PerformanceManager::PerformancePreset::LOW, // platform::Profiler::LOW
|
||||
PerformanceManager::PerformancePreset::MID, // platform::Profiler::MID
|
||||
PerformanceManager::PerformancePreset::HIGH // platform::Profiler::HIGH
|
||||
}};
|
||||
|
||||
// What is our profile?
|
||||
auto platformTier = platform::Profiler::profilePlatform();
|
||||
|
||||
// Then let's assign the performance preset setting from it
|
||||
getPerformanceManager().setPerformancePreset(platformToPerformancePresetMap[platformTier]);
|
||||
|
||||
}
|
||||
|
||||
// finish initializing the camera, based on everything we checked above. Third person camera will be used if no settings
|
||||
// dictated that we should be in first person
|
||||
Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, isFirstPerson);
|
||||
|
@ -6400,6 +6440,7 @@ void Application::update(float deltaTime) {
|
|||
PerformanceTimer perfTimer("simulation");
|
||||
|
||||
getEntities()->preUpdate();
|
||||
_entitySimulation->removeDeadEntities();
|
||||
|
||||
auto t0 = std::chrono::high_resolution_clock::now();
|
||||
auto t1 = t0;
|
||||
|
@ -9353,6 +9394,19 @@ void Application::showUrlHandler(const QUrl& url) {
|
|||
}
|
||||
});
|
||||
}
|
||||
void Application::overrideEntry(){
|
||||
_overrideEntry = true;
|
||||
}
|
||||
void Application::forceDisplayName(const QString& displayName) {
|
||||
getMyAvatar()->setDisplayName(displayName);
|
||||
}
|
||||
void Application::forceLoginWithTokens(const QString& tokens) {
|
||||
DependencyManager::get<AccountManager>()->setAccessTokens(tokens);
|
||||
Setting::Handle<bool>(KEEP_ME_LOGGED_IN_SETTING_NAME, true).set(true);
|
||||
}
|
||||
void Application::setConfigFileURL(const QString& fileUrl) {
|
||||
DependencyManager::get<AccountManager>()->setConfigFileURL(fileUrl);
|
||||
}
|
||||
|
||||
#if defined(Q_OS_ANDROID)
|
||||
void Application::beforeEnterBackground() {
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "gpu/Context.h"
|
||||
#include "LoginStateManager.h"
|
||||
#include "Menu.h"
|
||||
#include "PerformanceManager.h"
|
||||
#include "RefreshRateManager.h"
|
||||
#include "octree/OctreePacketProcessor.h"
|
||||
#include "render/Engine.h"
|
||||
|
@ -203,6 +204,8 @@ public:
|
|||
CompositorHelper& getApplicationCompositor() const;
|
||||
|
||||
Overlays& getOverlays() { return _overlays; }
|
||||
|
||||
PerformanceManager& getPerformanceManager() { return _performanceManager; }
|
||||
RefreshRateManager& getRefreshRateManager() { return _refreshRateManager; }
|
||||
|
||||
size_t getRenderFrameCount() const { return _graphicsEngine.getRenderFrameCount(); }
|
||||
|
@ -356,6 +359,11 @@ public:
|
|||
|
||||
void openDirectory(const QString& path);
|
||||
|
||||
void overrideEntry();
|
||||
void forceDisplayName(const QString& displayName);
|
||||
void forceLoginWithTokens(const QString& tokens);
|
||||
void setConfigFileURL(const QString& fileUrl);
|
||||
|
||||
signals:
|
||||
void svoImportRequested(const QString& url);
|
||||
|
||||
|
@ -729,6 +737,7 @@ private:
|
|||
QUuid _loginDialogID;
|
||||
QUuid _avatarInputsBarID;
|
||||
LoginStateManager _loginStateManager;
|
||||
PerformanceManager _performanceManager;
|
||||
RefreshRateManager _refreshRateManager;
|
||||
|
||||
quint64 _lastFaceTrackerUpdate;
|
||||
|
@ -828,5 +837,6 @@ private:
|
|||
bool _resumeAfterLoginDialogActionTaken_WasPostponed { false };
|
||||
bool _resumeAfterLoginDialogActionTaken_SafeToRun { false };
|
||||
bool _startUpFinished { false };
|
||||
bool _overrideEntry { false };
|
||||
};
|
||||
#endif // hifi_Application_h
|
||||
|
|
|
@ -59,7 +59,12 @@ void LocationBookmarks::setHomeLocation() {
|
|||
}
|
||||
|
||||
void LocationBookmarks::setHomeLocationToAddress(const QVariant& address) {
|
||||
Bookmarks::insert("Home", address);
|
||||
Bookmarks::insert(HOME_BOOKMARK, address);
|
||||
}
|
||||
|
||||
|
||||
QString LocationBookmarks::getHomeLocationAddress() {
|
||||
return addressForBookmark(HOME_BOOKMARK);
|
||||
}
|
||||
|
||||
void LocationBookmarks::teleportToBookmark() {
|
||||
|
|
|
@ -47,6 +47,12 @@ public slots:
|
|||
*/
|
||||
void setHomeLocationToAddress(const QVariant& address);
|
||||
|
||||
/**jsdoc
|
||||
* @function LocationBookmarksgetHomeLocationAddress
|
||||
* @returns {string} The url for the home location bookmark
|
||||
*/
|
||||
QString getHomeLocationAddress();
|
||||
|
||||
protected:
|
||||
void addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& address) override;
|
||||
|
||||
|
|
63
interface/src/PerformanceManager.cpp
Normal file
63
interface/src/PerformanceManager.cpp
Normal file
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// PerformanceManager.cpp
|
||||
// interface/src/
|
||||
//
|
||||
// Created by Sam Gateau on 2019-05-29.
|
||||
// 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
|
||||
//
|
||||
#include "PerformanceManager.h"
|
||||
|
||||
#include "scripting/RenderScriptingInterface.h"
|
||||
|
||||
PerformanceManager::PerformanceManager()
|
||||
{
|
||||
}
|
||||
|
||||
void PerformanceManager::setPerformancePreset(PerformanceManager::PerformancePreset preset) {
|
||||
if (getPerformancePreset() != preset) {
|
||||
_performancePresetSettingLock.withWriteLock([&] {
|
||||
_performancePresetSetting.set((int)preset);
|
||||
});
|
||||
|
||||
applyPerformancePreset(preset);
|
||||
}
|
||||
}
|
||||
|
||||
PerformanceManager::PerformancePreset PerformanceManager::getPerformancePreset() const {
|
||||
PerformancePreset preset = PerformancePreset::MID;
|
||||
|
||||
preset = (PerformancePreset) _performancePresetSettingLock.resultWithReadLock<int>([&] {
|
||||
return _performancePresetSetting.get();
|
||||
});
|
||||
|
||||
return preset;
|
||||
}
|
||||
|
||||
void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformancePreset preset) {
|
||||
|
||||
switch (preset) {
|
||||
case PerformancePreset::HIGH:
|
||||
RenderScriptingInterface::getInstance()->setRenderMethod(RenderScriptingInterface::RenderMethod::DEFERRED);
|
||||
RenderScriptingInterface::getInstance()->setShadowsEnabled(true);
|
||||
qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::INTERACTIVE);
|
||||
|
||||
break;
|
||||
case PerformancePreset::MID:
|
||||
RenderScriptingInterface::getInstance()->setRenderMethod(RenderScriptingInterface::RenderMethod::DEFERRED);
|
||||
RenderScriptingInterface::getInstance()->setShadowsEnabled(false);
|
||||
qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::INTERACTIVE);
|
||||
|
||||
break;
|
||||
case PerformancePreset::LOW:
|
||||
RenderScriptingInterface::getInstance()->setRenderMethod(RenderScriptingInterface::RenderMethod::FORWARD);
|
||||
RenderScriptingInterface::getInstance()->setShadowsEnabled(false);
|
||||
qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::ECO);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
43
interface/src/PerformanceManager.h
Normal file
43
interface/src/PerformanceManager.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// PerformanceManager.h
|
||||
// interface/src/
|
||||
//
|
||||
// Created by Sam Gateau on 2019-05-29.
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_PerformanceManager_h
|
||||
#define hifi_PerformanceManager_h
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <SettingHandle.h>
|
||||
#include <shared/ReadWriteLockable.h>
|
||||
|
||||
class PerformanceManager {
|
||||
public:
|
||||
enum PerformancePreset {
|
||||
LOW = 0,
|
||||
MID,
|
||||
HIGH,
|
||||
PROFILE_COUNT
|
||||
};
|
||||
|
||||
PerformanceManager();
|
||||
~PerformanceManager() = default;
|
||||
|
||||
void setPerformancePreset(PerformancePreset performancePreset);
|
||||
PerformancePreset getPerformancePreset() const;
|
||||
|
||||
private:
|
||||
mutable ReadWriteLockable _performancePresetSettingLock;
|
||||
Setting::Handle<int> _performancePresetSetting { "performancePreset", PerformanceManager::PerformancePreset::MID };
|
||||
|
||||
// The concrete performance preset changes
|
||||
void applyPerformancePreset(PerformanceManager::PerformancePreset performancePreset);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -521,6 +521,7 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact
|
|||
}
|
||||
}
|
||||
}
|
||||
_otherAvatarsToChangeInPhysics.clear();
|
||||
}
|
||||
|
||||
void AvatarManager::handleProcessedPhysicsTransaction(PhysicsEngine::Transaction& transaction) {
|
||||
|
@ -645,7 +646,7 @@ void AvatarManager::clearOtherAvatars() {
|
|||
}
|
||||
|
||||
void AvatarManager::deleteAllAvatars() {
|
||||
assert(_otherAvatarsToChangeInPhysics.empty());
|
||||
_otherAvatarsToChangeInPhysics.clear();
|
||||
QReadLocker locker(&_hashLock);
|
||||
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
||||
while (avatarIterator != _avatarHash.end()) {
|
||||
|
|
|
@ -325,8 +325,8 @@ MyAvatar::MyAvatar(QThread* thread) :
|
|||
|
||||
MyAvatar::~MyAvatar() {
|
||||
_lookAtTargetAvatar.reset();
|
||||
delete _myScriptEngine;
|
||||
_myScriptEngine = nullptr;
|
||||
delete _scriptEngine;
|
||||
_scriptEngine = nullptr;
|
||||
}
|
||||
|
||||
QString MyAvatar::getDominantHand() const {
|
||||
|
@ -1598,7 +1598,8 @@ void MyAvatar::handleChangedAvatarEntityData() {
|
|||
blobFailed = true; // blob doesn't exist
|
||||
return;
|
||||
}
|
||||
if (!EntityItemProperties::blobToProperties(*_myScriptEngine, itr.value(), properties)) {
|
||||
std::lock_guard<std::mutex> guard(_scriptEngineLock);
|
||||
if (!EntityItemProperties::blobToProperties(*_scriptEngine, itr.value(), properties)) {
|
||||
blobFailed = true; // blob is corrupt
|
||||
}
|
||||
});
|
||||
|
@ -1630,7 +1631,8 @@ void MyAvatar::handleChangedAvatarEntityData() {
|
|||
skip = true;
|
||||
return;
|
||||
}
|
||||
if (!EntityItemProperties::blobToProperties(*_myScriptEngine, itr.value(), properties)) {
|
||||
std::lock_guard<std::mutex> guard(_scriptEngineLock);
|
||||
if (!EntityItemProperties::blobToProperties(*_scriptEngine, itr.value(), properties)) {
|
||||
skip = true;
|
||||
}
|
||||
});
|
||||
|
@ -1737,7 +1739,10 @@ bool MyAvatar::updateStaleAvatarEntityBlobs() const {
|
|||
if (found) {
|
||||
++numFound;
|
||||
QByteArray blob;
|
||||
EntityItemProperties::propertiesToBlob(*_myScriptEngine, getID(), properties, blob);
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_scriptEngineLock);
|
||||
EntityItemProperties::propertiesToBlob(*_scriptEngine, getID(), properties, blob);
|
||||
}
|
||||
_avatarEntitiesLock.withWriteLock([&] {
|
||||
_cachedAvatarEntityBlobs[id] = blob;
|
||||
});
|
||||
|
@ -1883,8 +1888,8 @@ void MyAvatar::avatarEntityDataToJson(QJsonObject& root) const {
|
|||
}
|
||||
|
||||
void MyAvatar::loadData() {
|
||||
if (!_myScriptEngine) {
|
||||
_myScriptEngine = new QScriptEngine();
|
||||
if (!_scriptEngine) {
|
||||
_scriptEngine = new QScriptEngine();
|
||||
}
|
||||
getHead()->setBasePitch(_headPitchSetting.get());
|
||||
|
||||
|
@ -2476,14 +2481,18 @@ QVariantList MyAvatar::getAvatarEntitiesVariant() {
|
|||
if (!entity) {
|
||||
continue;
|
||||
}
|
||||
QVariantMap avatarEntityData;
|
||||
EncodeBitstreamParams params;
|
||||
auto desiredProperties = entity->getEntityProperties(params);
|
||||
desiredProperties += PROP_LOCAL_POSITION;
|
||||
desiredProperties += PROP_LOCAL_ROTATION;
|
||||
EntityItemProperties entityProperties = entity->getProperties(desiredProperties);
|
||||
QScriptValue scriptProperties = EntityItemPropertiesToScriptValue(_myScriptEngine, entityProperties);
|
||||
QVariantMap avatarEntityData;
|
||||
avatarEntityData["id"] = entityID;
|
||||
EntityItemProperties entityProperties = entity->getProperties(desiredProperties);
|
||||
QScriptValue scriptProperties;
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(_scriptEngineLock);
|
||||
scriptProperties = EntityItemPropertiesToScriptValue(_scriptEngine, entityProperties);
|
||||
}
|
||||
avatarEntityData["properties"] = scriptProperties.toVariant();
|
||||
avatarEntitiesData.append(QVariant(avatarEntityData));
|
||||
}
|
||||
|
|
|
@ -2741,7 +2741,8 @@ private:
|
|||
mutable std::set<QUuid> _staleCachedAvatarEntityBlobs;
|
||||
//
|
||||
// keep a ScriptEngine around so we don't have to instantiate on the fly (these are very slow to create/delete)
|
||||
QScriptEngine* _myScriptEngine { nullptr };
|
||||
mutable std::mutex _scriptEngineLock;
|
||||
QScriptEngine* _scriptEngine { nullptr };
|
||||
bool _needToSaveAvatarEntitySettings { false };
|
||||
};
|
||||
|
||||
|
|
|
@ -654,7 +654,7 @@ QString Wallet::signWithKey(const QByteArray& text, const QString& key) {
|
|||
EC_KEY* ecPrivateKey = NULL;
|
||||
|
||||
if ((ecPrivateKey = readPrivateKey(keyFilePath()))) {
|
||||
unsigned char* sig = new unsigned char[ECDSA_size(ecPrivateKey)];
|
||||
const auto sig = std::make_unique<unsigned char[]>(ECDSA_size(ecPrivateKey));
|
||||
|
||||
unsigned int signatureBytes = 0;
|
||||
|
||||
|
@ -663,10 +663,10 @@ QString Wallet::signWithKey(const QByteArray& text, const QString& key) {
|
|||
QByteArray hashedPlaintext = QCryptographicHash::hash(text, QCryptographicHash::Sha256);
|
||||
|
||||
int retrn = ECDSA_sign(0, reinterpret_cast<const unsigned char*>(hashedPlaintext.constData()), hashedPlaintext.size(),
|
||||
sig, &signatureBytes, ecPrivateKey);
|
||||
sig.get(), &signatureBytes, ecPrivateKey);
|
||||
|
||||
EC_KEY_free(ecPrivateKey);
|
||||
QByteArray signature(reinterpret_cast<const char*>(sig), signatureBytes);
|
||||
QByteArray signature(reinterpret_cast<const char*>(sig.get()), signatureBytes);
|
||||
if (retrn != -1) {
|
||||
return signature.toBase64();
|
||||
}
|
||||
|
|
|
@ -83,6 +83,8 @@ int main(int argc, const char* argv[]) {
|
|||
QCommandLineOption allowMultipleInstancesOption("allowMultipleInstances", "Allow multiple instances to run");
|
||||
QCommandLineOption overrideAppLocalDataPathOption("cache", "set test cache <dir>", "dir");
|
||||
QCommandLineOption overrideScriptsPathOption(SCRIPTS_SWITCH, "set scripts <path>", "path");
|
||||
QCommandLineOption responseTokensOption("tokens", "set response tokens <json>", "json");
|
||||
QCommandLineOption displayNameOption("displayName", "set user display name <string>", "string");
|
||||
|
||||
parser.addOption(urlOption);
|
||||
parser.addOption(noLauncherOption);
|
||||
|
@ -93,6 +95,8 @@ int main(int argc, const char* argv[]) {
|
|||
parser.addOption(overrideAppLocalDataPathOption);
|
||||
parser.addOption(overrideScriptsPathOption);
|
||||
parser.addOption(allowMultipleInstancesOption);
|
||||
parser.addOption(responseTokensOption);
|
||||
parser.addOption(displayNameOption);
|
||||
|
||||
if (!parser.parse(arguments)) {
|
||||
std::cout << parser.errorText().toStdString() << std::endl; // Avoid Qt log spam
|
||||
|
@ -120,8 +124,10 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
static const QString APPLICATION_CONFIG_FILENAME = "config.json";
|
||||
QDir applicationDir(applicationPath);
|
||||
QFile configFile(applicationDir.filePath(APPLICATION_CONFIG_FILENAME));
|
||||
|
||||
QString configFileName = applicationDir.filePath(APPLICATION_CONFIG_FILENAME);
|
||||
QFile configFile(configFileName);
|
||||
QString launcherPath;
|
||||
|
||||
if (configFile.exists()) {
|
||||
if (!configFile.open(QIODevice::ReadOnly)) {
|
||||
qWarning() << "Found application config, but could not open it";
|
||||
|
@ -134,7 +140,7 @@ int main(int argc, const char* argv[]) {
|
|||
qWarning() << "Found application config, but could not parse it: " << error.errorString();
|
||||
} else {
|
||||
static const QString LAUNCHER_PATH_KEY = "launcherPath";
|
||||
QString launcherPath = doc.object()[LAUNCHER_PATH_KEY].toString();
|
||||
launcherPath = doc.object()[LAUNCHER_PATH_KEY].toString();
|
||||
if (!launcherPath.isEmpty()) {
|
||||
if (!parser.isSet(noLauncherOption)) {
|
||||
qDebug() << "Found a launcherPath in application config. Starting launcher.";
|
||||
|
@ -146,6 +152,7 @@ int main(int argc, const char* argv[]) {
|
|||
qDebug() << "Found a launcherPath in application config, but the launcher"
|
||||
" has been suppressed. Continuing normal execution.";
|
||||
}
|
||||
configFile.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -398,6 +405,24 @@ int main(int argc, const char* argv[]) {
|
|||
|
||||
printSystemInformation();
|
||||
|
||||
auto appPointer = dynamic_cast<Application*>(&app);
|
||||
if (appPointer) {
|
||||
if (parser.isSet(urlOption)) {
|
||||
appPointer->overrideEntry();
|
||||
}
|
||||
if (parser.isSet(displayNameOption)) {
|
||||
QString displayName = QString(parser.value(displayNameOption));
|
||||
appPointer->forceDisplayName(displayName);
|
||||
}
|
||||
if (!launcherPath.isEmpty()) {
|
||||
appPointer->setConfigFileURL(configFileName);
|
||||
}
|
||||
if (parser.isSet(responseTokensOption)) {
|
||||
QString tokens = QString(parser.value(responseTokensOption));
|
||||
appPointer->forceLoginWithTokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
QTranslator translator;
|
||||
translator.load("i18n/interface_en");
|
||||
app.installTranslator(&translator);
|
||||
|
|
|
@ -15,10 +15,23 @@ std::once_flag PerformanceScriptingInterface::registry_flag;
|
|||
|
||||
PerformanceScriptingInterface::PerformanceScriptingInterface() {
|
||||
std::call_once(registry_flag, [] {
|
||||
qmlRegisterType<PerformanceScriptingInterface>("PerformanceEnums", 1, 0, "RefreshRate");
|
||||
qmlRegisterType<PerformanceScriptingInterface>("PerformanceEnums", 1, 0, "PerformanceEnums");
|
||||
});
|
||||
}
|
||||
|
||||
void PerformanceScriptingInterface::setPerformancePreset(PerformancePreset performancePreset) {
|
||||
qApp->getPerformanceManager().setPerformancePreset((PerformanceManager::PerformancePreset)performancePreset);
|
||||
}
|
||||
|
||||
PerformanceScriptingInterface::PerformancePreset PerformanceScriptingInterface::getPerformancePreset() const {
|
||||
return (PerformanceScriptingInterface::PerformancePreset)qApp->getPerformanceManager().getPerformancePreset();
|
||||
}
|
||||
|
||||
QStringList PerformanceScriptingInterface::getPerformancePresetNames() const {
|
||||
static const QStringList performancePresetNames = { "Low", "Mid", "High" };
|
||||
return performancePresetNames;
|
||||
}
|
||||
|
||||
void PerformanceScriptingInterface::setRefreshRateProfile(RefreshRateProfile refreshRateProfile) {
|
||||
qApp->getRefreshRateManager().setRefreshRateProfile((RefreshRateManager::RefreshRateProfile)refreshRateProfile);
|
||||
}
|
||||
|
@ -27,6 +40,11 @@ PerformanceScriptingInterface::RefreshRateProfile PerformanceScriptingInterface:
|
|||
return (PerformanceScriptingInterface::RefreshRateProfile)qApp->getRefreshRateManager().getRefreshRateProfile();
|
||||
}
|
||||
|
||||
QStringList PerformanceScriptingInterface::getRefreshRateProfileNames() const {
|
||||
static const QStringList refreshRateProfileNames = { "Eco", "Interactive", "Realtime" };
|
||||
return refreshRateProfileNames;
|
||||
}
|
||||
|
||||
int PerformanceScriptingInterface::getActiveRefreshRate() const {
|
||||
return qApp->getRefreshRateManager().getActiveRefreshRate();
|
||||
}
|
||||
|
|
|
@ -14,12 +14,22 @@
|
|||
|
||||
#include <QObject>
|
||||
|
||||
#include "../PerformanceManager.h"
|
||||
#include "../RefreshRateManager.h"
|
||||
|
||||
|
||||
class PerformanceScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
// PerformanceManager PerformancePreset tri state level enums
|
||||
enum PerformancePreset {
|
||||
LOW = PerformanceManager::PerformancePreset::LOW,
|
||||
MID = PerformanceManager::PerformancePreset::MID,
|
||||
HIGH = PerformanceManager::PerformancePreset::HIGH,
|
||||
};
|
||||
Q_ENUM(PerformancePreset)
|
||||
|
||||
// Must match RefreshRateManager enums
|
||||
enum RefreshRateProfile {
|
||||
ECO = RefreshRateManager::RefreshRateProfile::ECO,
|
||||
|
@ -28,19 +38,23 @@ public:
|
|||
};
|
||||
Q_ENUM(RefreshRateProfile)
|
||||
|
||||
|
||||
PerformanceScriptingInterface();
|
||||
~PerformanceScriptingInterface() = default;
|
||||
|
||||
public slots:
|
||||
|
||||
void setPerformancePreset(PerformancePreset performancePreset);
|
||||
PerformancePreset getPerformancePreset() const;
|
||||
QStringList getPerformancePresetNames() const;
|
||||
|
||||
void setRefreshRateProfile(RefreshRateProfile refreshRateProfile);
|
||||
RefreshRateProfile getRefreshRateProfile() const;
|
||||
QStringList getRefreshRateProfileNames() const;
|
||||
|
||||
int getActiveRefreshRate() const;
|
||||
RefreshRateManager::UXMode getUXMode() const;
|
||||
RefreshRateManager::RefreshRateRegime getRefreshRateRegime() const;
|
||||
|
||||
|
||||
private:
|
||||
static std::once_flag registry_flag;
|
||||
};
|
||||
|
|
|
@ -10,6 +10,9 @@
|
|||
#include <shared/GlobalAppProperties.h>
|
||||
#include <thread>
|
||||
|
||||
#include <platform/Platform.h>
|
||||
#include <platform/Profiler.h>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <Windows.h>
|
||||
#elif defined Q_OS_MAC
|
||||
|
@ -21,6 +24,17 @@ PlatformInfoScriptingInterface* PlatformInfoScriptingInterface::getInstance() {
|
|||
return &sharedInstance;
|
||||
}
|
||||
|
||||
|
||||
PlatformInfoScriptingInterface::PlatformInfoScriptingInterface() {
|
||||
platform::create();
|
||||
if (!platform::enumeratePlatform()) {
|
||||
}
|
||||
}
|
||||
|
||||
PlatformInfoScriptingInterface::~PlatformInfoScriptingInterface() {
|
||||
platform::destroy();
|
||||
}
|
||||
|
||||
QString PlatformInfoScriptingInterface::getOperatingSystemType() {
|
||||
#ifdef Q_OS_WIN
|
||||
return "WINDOWS";
|
||||
|
@ -149,3 +163,52 @@ bool PlatformInfoScriptingInterface::isStandalone() {
|
|||
return qApp->property(hifi::properties::STANDALONE).toBool();
|
||||
#endif
|
||||
}
|
||||
|
||||
int PlatformInfoScriptingInterface::getNumCPUs() {
|
||||
return platform::getNumCPUs();
|
||||
}
|
||||
|
||||
QString PlatformInfoScriptingInterface::getCPU(int index) {
|
||||
auto desc = platform::getCPU(index);
|
||||
return QString(desc.dump().c_str());
|
||||
}
|
||||
|
||||
int PlatformInfoScriptingInterface::getNumGPUs() {
|
||||
return platform::getNumGPUs();
|
||||
}
|
||||
|
||||
QString PlatformInfoScriptingInterface::getGPU(int index) {
|
||||
auto desc = platform::getGPU(index);
|
||||
return QString(desc.dump().c_str());
|
||||
}
|
||||
|
||||
int PlatformInfoScriptingInterface::getNumDisplays() {
|
||||
return platform::getNumDisplays();
|
||||
}
|
||||
|
||||
QString PlatformInfoScriptingInterface::getDisplay(int index) {
|
||||
auto desc = platform::getDisplay(index);
|
||||
return QString(desc.dump().c_str());
|
||||
}
|
||||
|
||||
QString PlatformInfoScriptingInterface::getMemory() {
|
||||
auto desc = platform::getMemory(0);
|
||||
return QString(desc.dump().c_str());
|
||||
}
|
||||
|
||||
QString PlatformInfoScriptingInterface::getComputer() {
|
||||
auto desc = platform::getComputer();
|
||||
return QString(desc.dump().c_str());
|
||||
}
|
||||
|
||||
|
||||
PlatformInfoScriptingInterface::PlatformTier PlatformInfoScriptingInterface::getTierProfiled() {
|
||||
return (PlatformInfoScriptingInterface::PlatformTier) platform::Profiler::profilePlatform();
|
||||
}
|
||||
|
||||
QStringList PlatformInfoScriptingInterface::getPlatformTierNames() {
|
||||
static const QStringList platformTierNames = { "UNKNWON", "LOW", "MID", "HIGH" };
|
||||
return platformTierNames;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#ifndef hifi_PlatformInfoScriptingInterface_h
|
||||
#define hifi_PlatformInfoScriptingInterface_h
|
||||
|
||||
#include <platform/Profiler.h>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class QScriptValue;
|
||||
|
@ -25,6 +26,20 @@ class QScriptValue;
|
|||
class PlatformInfoScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
public:
|
||||
PlatformInfoScriptingInterface();
|
||||
virtual ~PlatformInfoScriptingInterface();
|
||||
|
||||
// Platform tier enum type
|
||||
enum PlatformTier {
|
||||
UNKNOWN = platform::Profiler::Tier::UNKNOWN,
|
||||
LOW = platform::Profiler::Tier::LOW,
|
||||
MID = platform::Profiler::Tier::MID,
|
||||
HIGH = platform::Profiler::Tier::HIGH,
|
||||
};
|
||||
Q_ENUM(PlatformTier);
|
||||
|
||||
public slots:
|
||||
/**jsdoc
|
||||
* @function PlatformInfo.getInstance
|
||||
|
@ -98,6 +113,96 @@ public slots:
|
|||
* @returns {boolean} <code>true</code> if Interface is running on a stand-alone device, <code>false</code> if it isn't.
|
||||
*/
|
||||
bool isStandalone();
|
||||
|
||||
/**jsdoc
|
||||
* Get the number of CPUs.
|
||||
* @function PlatformInfo.getNumCPUs
|
||||
* @returns {number} The number of CPUs detected on the hardware platform.
|
||||
*/
|
||||
int getNumCPUs();
|
||||
|
||||
/**jsdoc
|
||||
* Get the description of the CPU at the index parameter
|
||||
* expected fields are:
|
||||
* - cpuVendor...
|
||||
* @param index The index of the CPU of the platform
|
||||
* @function PlatformInfo.getCPU
|
||||
* @returns {string} The CPU description json field
|
||||
*/
|
||||
QString getCPU(int index);
|
||||
|
||||
/**jsdoc
|
||||
* Get the number of GPUs.
|
||||
* @function PlatformInfo.getNumGPUs
|
||||
* @returns {number} The number of GPUs detected on the hardware platform.
|
||||
*/
|
||||
int getNumGPUs();
|
||||
|
||||
/**jsdoc
|
||||
* Get the description of the GPU at the index parameter
|
||||
* expected fields are:
|
||||
* - gpuVendor...
|
||||
* @param index The index of the GPU of the platform
|
||||
* @function PlatformInfo.getGPU
|
||||
* @returns {string} The GPU description json field
|
||||
*/
|
||||
QString getGPU(int index);
|
||||
|
||||
/**jsdoc
|
||||
* Get the number of Displays.
|
||||
* @function PlatformInfo.getNumDisplays
|
||||
* @returns {number} The number of Displays detected on the hardware platform.
|
||||
*/
|
||||
int getNumDisplays();
|
||||
|
||||
/**jsdoc
|
||||
* Get the description of the Display at the index parameter
|
||||
* expected fields are:
|
||||
* - DisplayVendor...
|
||||
* @param index The index of the Display of the platform
|
||||
* @function PlatformInfo.getDisplay
|
||||
* @returns {string} The Display description json field
|
||||
*/
|
||||
QString getDisplay(int index);
|
||||
|
||||
/**jsdoc
|
||||
* Get the description of the Memory
|
||||
* expected fields are:
|
||||
* - MemoryVendor...
|
||||
* @function PlatformInfo.getMemory
|
||||
* @returns {string} The Memory description json field
|
||||
*/
|
||||
QString getMemory();
|
||||
|
||||
/**jsdoc
|
||||
* Get the description of the Computer
|
||||
* expected fields are:
|
||||
* - ComputerVendor...
|
||||
* @function PlatformInfo.getComputer
|
||||
* @returns {string} The Computer description json field
|
||||
*/
|
||||
QString getComputer();
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Get the Platform TIer profiled on startup of the Computer
|
||||
* Platform Tier is an ineger/enum value:
|
||||
* LOW = 0, MID = 1, HIGH = 2
|
||||
* @function PlatformInfo.getTierProfiled
|
||||
* @returns {number} The Platform Tier profiled on startup.
|
||||
*/
|
||||
PlatformTier getTierProfiled();
|
||||
|
||||
/**jsdoc
|
||||
* Get the Platform Tier possible Names as an array of strings
|
||||
* Platform Tier is an ineger/enum value:
|
||||
* LOW = 0, MID = 1, HIGH = 2
|
||||
* @function PlatformInfo.getPlatformTierNames
|
||||
* @returns {string} The array of names matching the number returned from PlatformInfo.getTierProfiled
|
||||
*/
|
||||
QStringList getPlatformTierNames();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_PlatformInfoScriptingInterface_h
|
||||
|
|
|
@ -19,24 +19,24 @@ RenderScriptingInterface* RenderScriptingInterface::getInstance() {
|
|||
}
|
||||
|
||||
RenderScriptingInterface::RenderScriptingInterface() {
|
||||
setRenderMethod((render::Args::RenderMethod)_renderMethodSetting.get() == render::Args::RenderMethod::DEFERRED ? DEFERRED : FORWARD);
|
||||
setRenderMethod((RenderMethod)_renderMethodSetting.get() == RenderMethod::DEFERRED ? RenderMethod::DEFERRED : RenderMethod::FORWARD);
|
||||
setShadowsEnabled(_shadowsEnabledSetting.get());
|
||||
setAmbientOcclusionEnabled(_ambientOcclusionEnabledSetting.get());
|
||||
setAntialiasingEnabled(_antialiasingEnabledSetting.get());
|
||||
}
|
||||
|
||||
QString RenderScriptingInterface::getRenderMethod() {
|
||||
return (render::Args::RenderMethod)_renderMethodSetting.get() == render::Args::RenderMethod::DEFERRED ? DEFERRED : FORWARD;
|
||||
RenderScriptingInterface::RenderMethod RenderScriptingInterface::getRenderMethod() {
|
||||
return (RenderMethod)_renderMethodSetting.get() == RenderMethod::DEFERRED ? RenderMethod::DEFERRED : RenderMethod::FORWARD;
|
||||
}
|
||||
|
||||
void RenderScriptingInterface::setRenderMethod(const QString& renderMethod) {
|
||||
render::Args::RenderMethod newMethod = renderMethod == FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED;
|
||||
void RenderScriptingInterface::setRenderMethod(RenderScriptingInterface::RenderMethod renderMethod) {
|
||||
RenderMethod newMethod = renderMethod == RenderMethod::FORWARD ? RenderMethod::FORWARD : RenderMethod::DEFERRED;
|
||||
if (_renderMethodSetting.get() == newMethod) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setRenderMethod", Q_ARG(const QString&, renderMethod));
|
||||
QMetaObject::invokeMethod(this, "setRenderMethod", Q_ARG(RenderScriptingInterface::RenderMethod, renderMethod));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,11 @@ void RenderScriptingInterface::setRenderMethod(const QString& renderMethod) {
|
|||
}
|
||||
}
|
||||
|
||||
QStringList RenderScriptingInterface::getRenderMethodNames() const {
|
||||
static const QStringList refrenderMethodNames = { "Deferred", "Forward" };
|
||||
return refrenderMethodNames;
|
||||
}
|
||||
|
||||
bool RenderScriptingInterface::getShadowsEnabled() {
|
||||
return _shadowsEnabledSetting.get();
|
||||
}
|
||||
|
@ -119,4 +124,4 @@ void RenderScriptingInterface::setAntialiasingEnabled(bool enabled) {
|
|||
mainViewAntialiasingConfig->setDebugFXAA(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
class RenderScriptingInterface : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString renderMethod READ getRenderMethod WRITE setRenderMethod)
|
||||
Q_PROPERTY(RenderMethod renderMethod READ getRenderMethod WRITE setRenderMethod)
|
||||
Q_PROPERTY(bool shadowsEnabled READ getShadowsEnabled WRITE setShadowsEnabled)
|
||||
Q_PROPERTY(bool ambientOcclusionEnabled READ getAmbientOcclusionEnabled WRITE setAmbientOcclusionEnabled)
|
||||
Q_PROPERTY(bool antialiasingEnabled READ getAntialiasingEnabled WRITE setAntialiasingEnabled)
|
||||
|
@ -35,6 +35,13 @@ public:
|
|||
|
||||
static RenderScriptingInterface* getInstance();
|
||||
|
||||
// RenderMethod enum type
|
||||
enum RenderMethod {
|
||||
DEFERRED = render::Args::RenderMethod::DEFERRED,
|
||||
FORWARD = render::Args::RenderMethod::FORWARD,
|
||||
};
|
||||
Q_ENUM(RenderMethod);
|
||||
|
||||
public slots:
|
||||
/**jsdoc
|
||||
* Get a config for a job by name
|
||||
|
@ -50,16 +57,24 @@ public slots:
|
|||
/**jsdoc
|
||||
* Gets the current render method
|
||||
* @function Render.getRenderMethod
|
||||
* @returns {string} <code>"deferred"</code> or <code>"forward"</code>
|
||||
* @returns {number} <code>"DEFERRED"</code> or <code>"FORWARD"</code>
|
||||
*/
|
||||
QString getRenderMethod();
|
||||
RenderMethod getRenderMethod();
|
||||
|
||||
/**jsdoc
|
||||
* Sets the current render method
|
||||
* @function Render.setRenderMethod
|
||||
* @param {string} renderMethod - <code>"deferred"</code> or <code>"forward"</code>
|
||||
* @param {number} renderMethod - <code>"DEFERRED"</code> or <code>"FORWARD"</code>
|
||||
*/
|
||||
void setRenderMethod(const QString& renderMethod);
|
||||
void setRenderMethod(RenderMethod renderMethod);
|
||||
|
||||
/**jsdoc
|
||||
* Gets the possible enum names of the RenderMethod type
|
||||
* @function Render.getRenderMethodNames
|
||||
* @returns [string] [ <code>"DEFERRED"</code>, <code>"FORWARD"</code> ]
|
||||
*/
|
||||
QStringList getRenderMethodNames() const;
|
||||
|
||||
|
||||
/**jsdoc
|
||||
* Whether or not shadows are enabled
|
||||
|
@ -103,11 +118,26 @@ public slots:
|
|||
*/
|
||||
void setAntialiasingEnabled(bool enabled);
|
||||
|
||||
/**jsdoc
|
||||
* Gets the current viewport resolution scale
|
||||
* @function Render.getViewportResolutionScale
|
||||
* @returns {number}
|
||||
*/
|
||||
// float getViewportResolutionScale();
|
||||
|
||||
/**jsdoc
|
||||
* Sets the current viewport resolution scale
|
||||
* @function Render.setViewportResolutionScale
|
||||
* @param {number} resolutionScale - between epsilon and 1.0
|
||||
*/
|
||||
// void setViewportResolutionScale(float resolutionScale);
|
||||
|
||||
private:
|
||||
Setting::Handle<int> _renderMethodSetting { "renderMethod", RENDER_FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED };
|
||||
Setting::Handle<bool> _shadowsEnabledSetting { "shadowsEnabled", true };
|
||||
Setting::Handle<bool> _ambientOcclusionEnabledSetting { "ambientOcclusionEnabled", false };
|
||||
Setting::Handle<bool> _antialiasingEnabledSetting { "antialiasingEnabled", true };
|
||||
Setting::Handle<float> _viewportResolutionScaleSetting{ "viewportResolutionScale", 1.0f };
|
||||
};
|
||||
|
||||
#endif // hifi_RenderScriptingInterface_h
|
||||
|
|
|
@ -109,7 +109,11 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
|||
auto mainWindow = qApp->getWindow();
|
||||
_dockWidget = std::shared_ptr<DockWidget>(new DockWidget(title, mainWindow), dockWidgetDeleter);
|
||||
auto quickView = _dockWidget->getQuickView();
|
||||
Application::setupQmlSurface(quickView->rootContext(), true);
|
||||
|
||||
Application::setupQmlSurface(quickView->rootContext() , true);
|
||||
|
||||
//add any whitelisted callbacks
|
||||
OffscreenUi::applyWhiteList(sourceUrl, quickView->rootContext());
|
||||
|
||||
/**jsdoc
|
||||
* Configures how a <code>NATIVE</code> window is displayed.
|
||||
|
@ -150,6 +154,8 @@ InteractiveWindow::InteractiveWindow(const QString& sourceUrl, const QVariantMap
|
|||
}
|
||||
});
|
||||
_dockWidget->setSource(QUrl(sourceUrl));
|
||||
|
||||
|
||||
mainWindow->addDockWidget(dockArea, _dockWidget.get());
|
||||
} else {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
|
|
|
@ -180,11 +180,7 @@ private:
|
|||
mutable ReadWriteLockable _preferMalletsOverLasersSettingLock;
|
||||
mutable ReadWriteLockable _ignoreItemsLock;
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
Setting::Handle<bool> _use3DKeyboard { "use3DKeyboard", false };
|
||||
#else
|
||||
Setting::Handle<bool> _use3DKeyboard { "use3DKeyboard", true };
|
||||
#endif
|
||||
|
||||
QString _typedCharacters;
|
||||
TextDisplay _textDisplay;
|
||||
|
|
|
@ -291,6 +291,7 @@ AudioClient::AudioClient() :
|
|||
_inputToNetworkResampler(NULL),
|
||||
_networkToOutputResampler(NULL),
|
||||
_localToOutputResampler(NULL),
|
||||
_loopbackResampler(NULL),
|
||||
_audioLimiter(AudioConstants::SAMPLE_RATE, OUTPUT_CHANNEL_COUNT),
|
||||
_outgoingAvatarAudioSequenceNumber(0),
|
||||
_audioOutputIODevice(_localInjectorsStream, _receivedAudioStream, this),
|
||||
|
@ -656,11 +657,11 @@ bool adjustedFormatForAudioDevice(const QAudioDeviceInfo& audioDevice,
|
|||
return false; // a supported format could not be found
|
||||
}
|
||||
|
||||
bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationSamples, unsigned int numSourceSamples,
|
||||
bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationSamples, int numSourceSamples,
|
||||
const int sourceChannelCount, const int destinationChannelCount) {
|
||||
if (sourceChannelCount == 2 && destinationChannelCount == 1) {
|
||||
// loop through the stereo input audio samples and average every two samples
|
||||
for (uint i = 0; i < numSourceSamples; i += 2) {
|
||||
for (int i = 0; i < numSourceSamples; i += 2) {
|
||||
destinationSamples[i / 2] = (sourceSamples[i] / 2) + (sourceSamples[i + 1] / 2);
|
||||
}
|
||||
|
||||
|
@ -668,7 +669,7 @@ bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationS
|
|||
} else if (sourceChannelCount == 1 && destinationChannelCount == 2) {
|
||||
|
||||
// loop through the mono input audio and repeat each sample twice
|
||||
for (uint i = 0; i < numSourceSamples; ++i) {
|
||||
for (int i = 0; i < numSourceSamples; ++i) {
|
||||
destinationSamples[i * 2] = destinationSamples[(i * 2) + 1] = sourceSamples[i];
|
||||
}
|
||||
|
||||
|
@ -678,10 +679,13 @@ bool sampleChannelConversion(const int16_t* sourceSamples, int16_t* destinationS
|
|||
return false;
|
||||
}
|
||||
|
||||
void possibleResampling(AudioSRC* resampler,
|
||||
const int16_t* sourceSamples, int16_t* destinationSamples,
|
||||
unsigned int numSourceSamples, unsigned int numDestinationSamples,
|
||||
const int sourceChannelCount, const int destinationChannelCount) {
|
||||
int possibleResampling(AudioSRC* resampler,
|
||||
const int16_t* sourceSamples, int16_t* destinationSamples,
|
||||
int numSourceSamples, int maxDestinationSamples,
|
||||
const int sourceChannelCount, const int destinationChannelCount) {
|
||||
|
||||
int numSourceFrames = numSourceSamples / sourceChannelCount;
|
||||
int numDestinationFrames = 0;
|
||||
|
||||
if (numSourceSamples > 0) {
|
||||
if (!resampler) {
|
||||
|
@ -690,33 +694,30 @@ void possibleResampling(AudioSRC* resampler,
|
|||
// no conversion, we can copy the samples directly across
|
||||
memcpy(destinationSamples, sourceSamples, numSourceSamples * AudioConstants::SAMPLE_SIZE);
|
||||
}
|
||||
numDestinationFrames = numSourceFrames;
|
||||
} else {
|
||||
|
||||
if (sourceChannelCount != destinationChannelCount) {
|
||||
|
||||
int numChannelCoversionSamples = (numSourceSamples * destinationChannelCount) / sourceChannelCount;
|
||||
int16_t* channelConversionSamples = new int16_t[numChannelCoversionSamples];
|
||||
int16_t* channelConversionSamples = new int16_t[numSourceFrames * destinationChannelCount];
|
||||
|
||||
sampleChannelConversion(sourceSamples, channelConversionSamples, numSourceSamples,
|
||||
sourceChannelCount, destinationChannelCount);
|
||||
|
||||
resampler->render(channelConversionSamples, destinationSamples, numChannelCoversionSamples);
|
||||
numDestinationFrames = resampler->render(channelConversionSamples, destinationSamples, numSourceFrames);
|
||||
|
||||
delete[] channelConversionSamples;
|
||||
} else {
|
||||
|
||||
unsigned int numAdjustedSourceSamples = numSourceSamples;
|
||||
unsigned int numAdjustedDestinationSamples = numDestinationSamples;
|
||||
|
||||
if (sourceChannelCount == 2 && destinationChannelCount == 2) {
|
||||
numAdjustedSourceSamples /= 2;
|
||||
numAdjustedDestinationSamples /= 2;
|
||||
}
|
||||
|
||||
resampler->render(sourceSamples, destinationSamples, numAdjustedSourceSamples);
|
||||
numDestinationFrames = resampler->render(sourceSamples, destinationSamples, numSourceFrames);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int numDestinationSamples = numDestinationFrames * destinationChannelCount;
|
||||
if (numDestinationSamples > maxDestinationSamples) {
|
||||
qCWarning(audioclient) << "Resampler overflow! numDestinationSamples =" << numDestinationSamples
|
||||
<< "but maxDestinationSamples =" << maxDestinationSamples;
|
||||
}
|
||||
return numDestinationSamples;
|
||||
}
|
||||
|
||||
void AudioClient::start() {
|
||||
|
@ -1085,13 +1086,6 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
|||
return;
|
||||
}
|
||||
|
||||
// NOTE: we assume the inputFormat and the outputFormat are the same, since on any modern
|
||||
// multimedia OS they should be. If there is a device that this is not true for, we can
|
||||
// add back support to do resampling.
|
||||
if (_inputFormat.sampleRate() != _outputFormat.sampleRate()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if this person wants local loopback add that to the locally injected audio
|
||||
// if there is reverb apply it to local audio and substract the origin samples
|
||||
|
||||
|
@ -1108,21 +1102,30 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) {
|
|||
}
|
||||
}
|
||||
|
||||
// if required, create loopback resampler
|
||||
if (_inputFormat.sampleRate() != _outputFormat.sampleRate() && !_loopbackResampler) {
|
||||
qCDebug(audioclient) << "Resampling from" << _inputFormat.sampleRate() << "to" << _outputFormat.sampleRate() << "for audio loopback.";
|
||||
_loopbackResampler = new AudioSRC(_inputFormat.sampleRate(), _outputFormat.sampleRate(), OUTPUT_CHANNEL_COUNT);
|
||||
}
|
||||
|
||||
static QByteArray loopBackByteArray;
|
||||
|
||||
int numInputSamples = inputByteArray.size() / AudioConstants::SAMPLE_SIZE;
|
||||
int numLoopbackSamples = (numInputSamples * OUTPUT_CHANNEL_COUNT) / _inputFormat.channelCount();
|
||||
int numInputFrames = numInputSamples / _inputFormat.channelCount();
|
||||
int maxLoopbackFrames = _loopbackResampler ? _loopbackResampler->getMaxOutput(numInputFrames) : numInputFrames;
|
||||
int maxLoopbackSamples = maxLoopbackFrames * OUTPUT_CHANNEL_COUNT;
|
||||
|
||||
loopBackByteArray.resize(numLoopbackSamples * AudioConstants::SAMPLE_SIZE);
|
||||
loopBackByteArray.resize(maxLoopbackSamples * AudioConstants::SAMPLE_SIZE);
|
||||
|
||||
int16_t* inputSamples = reinterpret_cast<int16_t*>(inputByteArray.data());
|
||||
int16_t* loopbackSamples = reinterpret_cast<int16_t*>(loopBackByteArray.data());
|
||||
|
||||
// upmix mono to stereo
|
||||
if (!sampleChannelConversion(inputSamples, loopbackSamples, numInputSamples, _inputFormat.channelCount(), OUTPUT_CHANNEL_COUNT)) {
|
||||
// no conversion, just copy the samples
|
||||
memcpy(loopbackSamples, inputSamples, numInputSamples * AudioConstants::SAMPLE_SIZE);
|
||||
}
|
||||
int numLoopbackSamples = possibleResampling(_loopbackResampler,
|
||||
inputSamples, loopbackSamples,
|
||||
numInputSamples, maxLoopbackSamples,
|
||||
_inputFormat.channelCount(), OUTPUT_CHANNEL_COUNT);
|
||||
|
||||
loopBackByteArray.resize(numLoopbackSamples * AudioConstants::SAMPLE_SIZE);
|
||||
|
||||
// apply stereo reverb at the source, to the loopback audio
|
||||
if (!_shouldEchoLocally && hasReverb) {
|
||||
|
@ -1665,12 +1668,17 @@ bool AudioClient::switchInputToAudioDevice(const QAudioDeviceInfo inputDeviceInf
|
|||
_dummyAudioInput = NULL;
|
||||
}
|
||||
|
||||
// cleanup any resamplers
|
||||
if (_inputToNetworkResampler) {
|
||||
// if we were using an input to network resampler, delete it here
|
||||
delete _inputToNetworkResampler;
|
||||
_inputToNetworkResampler = NULL;
|
||||
}
|
||||
|
||||
if (_loopbackResampler) {
|
||||
delete _loopbackResampler;
|
||||
_loopbackResampler = NULL;
|
||||
}
|
||||
|
||||
if (_audioGate) {
|
||||
delete _audioGate;
|
||||
_audioGate = nullptr;
|
||||
|
@ -1869,6 +1877,7 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI
|
|||
if (_audioOutput) {
|
||||
_audioOutputIODevice.close();
|
||||
_audioOutput->stop();
|
||||
_audioOutputInitialized = false;
|
||||
|
||||
//must be deleted in next eventloop cycle when its called from notify()
|
||||
_audioOutput->deleteLater();
|
||||
|
@ -1891,15 +1900,22 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI
|
|||
_outputDeviceInfo = QAudioDeviceInfo();
|
||||
}
|
||||
|
||||
// cleanup any resamplers
|
||||
if (_networkToOutputResampler) {
|
||||
// if we were using an input to network resampler, delete it here
|
||||
delete _networkToOutputResampler;
|
||||
_networkToOutputResampler = NULL;
|
||||
}
|
||||
|
||||
if (_localToOutputResampler) {
|
||||
delete _localToOutputResampler;
|
||||
_localToOutputResampler = NULL;
|
||||
}
|
||||
|
||||
if (_loopbackResampler) {
|
||||
delete _loopbackResampler;
|
||||
_loopbackResampler = NULL;
|
||||
}
|
||||
|
||||
if (isShutdownRequest) {
|
||||
qCDebug(audioclient) << "The audio output device has shut down.";
|
||||
return true;
|
||||
|
@ -1939,52 +1955,50 @@ bool AudioClient::switchOutputToAudioDevice(const QAudioDeviceInfo outputDeviceI
|
|||
int requestedSize = _sessionOutputBufferSizeFrames * frameSize * AudioConstants::SAMPLE_SIZE;
|
||||
_audioOutput->setBufferSize(requestedSize);
|
||||
|
||||
// initialize mix buffers on the _audioOutput thread to avoid races
|
||||
connect(_audioOutput, &QAudioOutput::stateChanged, [&, frameSize, requestedSize](QAudio::State state) {
|
||||
if (state == QAudio::ActiveState) {
|
||||
// restrict device callback to _outputPeriod samples
|
||||
_outputPeriod = _audioOutput->periodSize() / AudioConstants::SAMPLE_SIZE;
|
||||
// device callback may exceed reported period, so double it to avoid stutter
|
||||
_outputPeriod *= 2;
|
||||
|
||||
_outputMixBuffer = new float[_outputPeriod];
|
||||
_outputScratchBuffer = new int16_t[_outputPeriod];
|
||||
|
||||
// size local output mix buffer based on resampled network frame size
|
||||
int networkPeriod = _localToOutputResampler ? _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO) : AudioConstants::NETWORK_FRAME_SAMPLES_STEREO;
|
||||
_localOutputMixBuffer = new float[networkPeriod];
|
||||
|
||||
// local period should be at least twice the output period,
|
||||
// in case two device reads happen before more data can be read (worst case)
|
||||
int localPeriod = _outputPeriod * 2;
|
||||
// round up to an exact multiple of networkPeriod
|
||||
localPeriod = ((localPeriod + networkPeriod - 1) / networkPeriod) * networkPeriod;
|
||||
// this ensures lowest latency without stutter from underrun
|
||||
_localInjectorsStream.resizeForFrameSize(localPeriod);
|
||||
|
||||
int bufferSize = _audioOutput->bufferSize();
|
||||
int bufferSamples = bufferSize / AudioConstants::SAMPLE_SIZE;
|
||||
int bufferFrames = bufferSamples / (float)frameSize;
|
||||
qCDebug(audioclient) << "frame (samples):" << frameSize;
|
||||
qCDebug(audioclient) << "buffer (frames):" << bufferFrames;
|
||||
qCDebug(audioclient) << "buffer (samples):" << bufferSamples;
|
||||
qCDebug(audioclient) << "buffer (bytes):" << bufferSize;
|
||||
qCDebug(audioclient) << "requested (bytes):" << requestedSize;
|
||||
qCDebug(audioclient) << "period (samples):" << _outputPeriod;
|
||||
qCDebug(audioclient) << "local buffer (samples):" << localPeriod;
|
||||
|
||||
disconnect(_audioOutput, &QAudioOutput::stateChanged, 0, 0);
|
||||
|
||||
// unlock to avoid a deadlock with the device callback (which always succeeds this initialization)
|
||||
localAudioLock.unlock();
|
||||
}
|
||||
});
|
||||
connect(_audioOutput, &QAudioOutput::notify, this, &AudioClient::outputNotify);
|
||||
|
||||
// start the output device
|
||||
_audioOutputIODevice.start();
|
||||
|
||||
_audioOutput->start(&_audioOutputIODevice);
|
||||
|
||||
// initialize mix buffers
|
||||
|
||||
// restrict device callback to _outputPeriod samples
|
||||
_outputPeriod = _audioOutput->periodSize() / AudioConstants::SAMPLE_SIZE;
|
||||
// device callback may exceed reported period, so double it to avoid stutter
|
||||
_outputPeriod *= 2;
|
||||
|
||||
_outputMixBuffer = new float[_outputPeriod];
|
||||
_outputScratchBuffer = new int16_t[_outputPeriod];
|
||||
|
||||
// size local output mix buffer based on resampled network frame size
|
||||
int networkPeriod = _localToOutputResampler ? _localToOutputResampler->getMaxOutput(AudioConstants::NETWORK_FRAME_SAMPLES_STEREO) : AudioConstants::NETWORK_FRAME_SAMPLES_STEREO;
|
||||
_localOutputMixBuffer = new float[networkPeriod];
|
||||
|
||||
// local period should be at least twice the output period,
|
||||
// in case two device reads happen before more data can be read (worst case)
|
||||
int localPeriod = _outputPeriod * 2;
|
||||
// round up to an exact multiple of networkPeriod
|
||||
localPeriod = ((localPeriod + networkPeriod - 1) / networkPeriod) * networkPeriod;
|
||||
// this ensures lowest latency without stutter from underrun
|
||||
_localInjectorsStream.resizeForFrameSize(localPeriod);
|
||||
|
||||
_audioOutputInitialized = true;
|
||||
|
||||
int bufferSize = _audioOutput->bufferSize();
|
||||
int bufferSamples = bufferSize / AudioConstants::SAMPLE_SIZE;
|
||||
int bufferFrames = bufferSamples / (float)frameSize;
|
||||
qCDebug(audioclient) << "frame (samples):" << frameSize;
|
||||
qCDebug(audioclient) << "buffer (frames):" << bufferFrames;
|
||||
qCDebug(audioclient) << "buffer (samples):" << bufferSamples;
|
||||
qCDebug(audioclient) << "buffer (bytes):" << bufferSize;
|
||||
qCDebug(audioclient) << "requested (bytes):" << requestedSize;
|
||||
qCDebug(audioclient) << "period (samples):" << _outputPeriod;
|
||||
qCDebug(audioclient) << "local buffer (samples):" << localPeriod;
|
||||
|
||||
// unlock to avoid a deadlock with the device callback (which always succeeds this initialization)
|
||||
localAudioLock.unlock();
|
||||
|
||||
// setup a loopback audio output device
|
||||
_loopbackAudioOutput = new QAudioOutput(outputDeviceInfo, _outputFormat, this);
|
||||
|
||||
|
@ -2082,6 +2096,12 @@ float AudioClient::gainForSource(float distance, float volume) {
|
|||
|
||||
qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
||||
|
||||
// lock-free wait for initialization to avoid races
|
||||
if (!_audio->_audioOutputInitialized.load(std::memory_order_acquire)) {
|
||||
memset(data, 0, maxSize);
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
// samples requested from OUTPUT_CHANNEL_COUNT
|
||||
int deviceChannelCount = _audio->_outputFormat.channelCount();
|
||||
int samplesRequested = (int)(maxSize / AudioConstants::SAMPLE_SIZE) * OUTPUT_CHANNEL_COUNT / deviceChannelCount;
|
||||
|
@ -2162,6 +2182,8 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
|||
}
|
||||
|
||||
bytesWritten = framesPopped * AudioConstants::SAMPLE_SIZE * deviceChannelCount;
|
||||
assert(bytesWritten <= maxSize);
|
||||
|
||||
} else {
|
||||
// nothing on network, don't grab anything from injectors, and just return 0s
|
||||
memset(data, 0, maxSize);
|
||||
|
@ -2174,7 +2196,6 @@ qint64 AudioClient::AudioOutputIODevice::readData(char * data, qint64 maxSize) {
|
|||
_audio->_audioFileWav.addRawAudioChunk(reinterpret_cast<char*>(scratchBuffer), bytesWritten);
|
||||
}
|
||||
|
||||
|
||||
int bytesAudioOutputUnplayed = _audio->_audioOutput->bufferSize() - _audio->_audioOutput->bytesFree();
|
||||
float msecsAudioOutputUnplayed = bytesAudioOutputUnplayed / (float)_audio->_outputFormat.bytesForDuration(USECS_PER_MSEC);
|
||||
_audio->_stats.updateOutputMsUnplayed(msecsAudioOutputUnplayed);
|
||||
|
|
|
@ -340,6 +340,7 @@ private:
|
|||
QIODevice* _inputDevice;
|
||||
int _numInputCallbackBytes;
|
||||
QAudioOutput* _audioOutput;
|
||||
std::atomic<bool> _audioOutputInitialized { false };
|
||||
QAudioFormat _desiredOutputFormat;
|
||||
QAudioFormat _outputFormat;
|
||||
int _outputFrameSize;
|
||||
|
@ -389,6 +390,7 @@ private:
|
|||
AudioSRC* _inputToNetworkResampler;
|
||||
AudioSRC* _networkToOutputResampler;
|
||||
AudioSRC* _localToOutputResampler;
|
||||
AudioSRC* _loopbackResampler;
|
||||
|
||||
// for network audio (used by network audio thread)
|
||||
int16_t _networkScratchBuffer[AudioConstants::NETWORK_FRAME_SAMPLES_AMBISONIC];
|
||||
|
|
|
@ -364,10 +364,19 @@ int InboundAudioStream::popSamples(int maxSamples, bool allOrNothing) {
|
|||
// buffer calculations.
|
||||
setToStarved();
|
||||
_consecutiveNotMixedCount++;
|
||||
//Kick PLC to generate a filler frame, reducing 'click'
|
||||
lostAudioData(allOrNothing ? (maxSamples - samplesAvailable) / _ringBuffer.getNumFrameSamples() : 1);
|
||||
samplesPopped = _ringBuffer.samplesAvailable();
|
||||
if (samplesPopped) {
|
||||
|
||||
// use PLC to generate extrapolated audio data, to reduce clicking
|
||||
if (allOrNothing) {
|
||||
int samplesNeeded = maxSamples - samplesAvailable;
|
||||
int packetsNeeded = (samplesNeeded + _ringBuffer.getNumFrameSamples() - 1) / _ringBuffer.getNumFrameSamples();
|
||||
lostAudioData(packetsNeeded);
|
||||
} else {
|
||||
lostAudioData(1);
|
||||
}
|
||||
samplesAvailable = _ringBuffer.samplesAvailable();
|
||||
|
||||
if (samplesAvailable > 0) {
|
||||
samplesPopped = std::min(samplesAvailable, maxSamples);
|
||||
popSamplesNoCheck(samplesPopped);
|
||||
} else {
|
||||
// No samples available means a packet is currently being
|
||||
|
|
|
@ -34,15 +34,26 @@ int AudioSRC::multirateFilter1_AVX2(const float* input0, float* output0, int inp
|
|||
const float* c0 = &_polyphaseFilter[_numTaps * _phase];
|
||||
|
||||
__m256 acc0 = _mm256_setzero_ps();
|
||||
__m256 acc1 = _mm256_setzero_ps();
|
||||
|
||||
for (int j = 0; j < _numTaps; j += 8) {
|
||||
int j = 0;
|
||||
for (; j < _numTaps - 15; j += 16) { // unrolled x 2
|
||||
|
||||
//float coef = c0[j];
|
||||
__m256 coef0 = _mm256_loadu_ps(&c0[j]);
|
||||
__m256 coef0 = _mm256_loadu_ps(&c0[j + 0]);
|
||||
__m256 coef1 = _mm256_loadu_ps(&c0[j + 8]);
|
||||
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j + 0]), coef0, acc0);
|
||||
acc1 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j + 8]), coef1, acc1);
|
||||
}
|
||||
if (j < _numTaps) {
|
||||
|
||||
__m256 coef0 = _mm256_loadu_ps(&c0[j]);
|
||||
|
||||
acc0 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j]), coef0, acc0);
|
||||
}
|
||||
acc0 = _mm256_add_ps(acc0, acc1);
|
||||
|
||||
// horizontal sum
|
||||
acc0 = _mm256_hadd_ps(acc0, acc0);
|
||||
|
@ -73,19 +84,36 @@ int AudioSRC::multirateFilter1_AVX2(const float* input0, float* output0, int inp
|
|||
const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)];
|
||||
|
||||
__m256 acc0 = _mm256_setzero_ps();
|
||||
__m256 acc1 = _mm256_setzero_ps();
|
||||
__m256 frac = _mm256_broadcast_ss(&ftmp);
|
||||
|
||||
for (int j = 0; j < _numTaps; j += 8) {
|
||||
int j = 0;
|
||||
for (; j < _numTaps - 15; j += 16) { // unrolled x 2
|
||||
|
||||
//float coef = c0[j] + frac * (c1[j] - c0[j]);
|
||||
__m256 coef0 = _mm256_loadu_ps(&c0[j + 0]);
|
||||
__m256 coef1 = _mm256_loadu_ps(&c1[j + 0]);
|
||||
__m256 coef2 = _mm256_loadu_ps(&c0[j + 8]);
|
||||
__m256 coef3 = _mm256_loadu_ps(&c1[j + 8]);
|
||||
coef1 = _mm256_sub_ps(coef1, coef0);
|
||||
coef3 = _mm256_sub_ps(coef3, coef2);
|
||||
coef0 = _mm256_fmadd_ps(coef1, frac, coef0);
|
||||
coef2 = _mm256_fmadd_ps(coef3, frac, coef2);
|
||||
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j + 0]), coef0, acc0);
|
||||
acc1 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j + 8]), coef2, acc1);
|
||||
}
|
||||
if (j < _numTaps) {
|
||||
|
||||
__m256 coef0 = _mm256_loadu_ps(&c0[j]);
|
||||
__m256 coef1 = _mm256_loadu_ps(&c1[j]);
|
||||
coef1 = _mm256_sub_ps(coef1, coef0);
|
||||
coef0 = _mm256_fmadd_ps(coef1, frac, coef0);
|
||||
|
||||
//acc += input[i + j] * coef;
|
||||
acc0 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j]), coef0, acc0);
|
||||
}
|
||||
acc0 = _mm256_add_ps(acc0, acc1);
|
||||
|
||||
// horizontal sum
|
||||
acc0 = _mm256_hadd_ps(acc0, acc0);
|
||||
|
|
|
@ -163,7 +163,7 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
|
|||
transform = _renderTransform;
|
||||
});
|
||||
|
||||
if (!_visible || !texture || !texture->isLoaded()) {
|
||||
if (!_visible || !texture || !texture->isLoaded() || color.a == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -214,4 +214,4 @@ void ImageEntityRenderer::doRender(RenderArgs* args) {
|
|||
);
|
||||
|
||||
batch->setResourceTexture(0, nullptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -744,7 +744,7 @@ bool RenderableModelEntityItem::shouldBePhysical() const {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
return !isDead() && shapeType != SHAPE_TYPE_NONE && QUrl(_modelURL).isValid();
|
||||
return !isDead() && shapeType != SHAPE_TYPE_NONE && !isLocalEntity() && QUrl(_modelURL).isValid();
|
||||
}
|
||||
|
||||
int RenderableModelEntityItem::getJointParent(int index) const {
|
||||
|
|
|
@ -251,11 +251,16 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) {
|
|||
outColor = EntityRenderer::calculatePulseColor(outColor, _pulseProperties, _created);
|
||||
});
|
||||
|
||||
if (outColor.a == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (pipelineType == Pipeline::PROCEDURAL) {
|
||||
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(materials.top().material);
|
||||
outColor = procedural->getColor(outColor);
|
||||
outColor.a *= procedural->isFading() ? Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) : 1.0f;
|
||||
procedural->prepare(batch, _position, _dimensions, _orientation, _created, ProceduralProgramKey(outColor.a < 1.0f));
|
||||
|
||||
if (render::ShapeKey(args->_globalShapeKey).isWireframe() || primitiveMode == PrimitiveMode::LINES) {
|
||||
geometryCache->renderWireShape(batch, geometryShape, outColor);
|
||||
} else {
|
||||
|
|
|
@ -324,7 +324,7 @@ public:
|
|||
bool getDynamic() const;
|
||||
void setDynamic(bool value);
|
||||
|
||||
virtual bool shouldBePhysical() const { return !isDead() && getShapeType() != SHAPE_TYPE_NONE; }
|
||||
virtual bool shouldBePhysical() const { return !isDead() && getShapeType() != SHAPE_TYPE_NONE && !isLocalEntity(); }
|
||||
bool isVisuallyReady() const { return _visuallyReady; }
|
||||
|
||||
bool getLocked() const;
|
||||
|
|
|
@ -104,41 +104,199 @@ bool EntityItemProperties::constructFromBuffer(const unsigned char* data, int da
|
|||
return true;
|
||||
}
|
||||
|
||||
QHash<QString, ShapeType> stringToShapeTypeLookup;
|
||||
|
||||
void addShapeType(ShapeType type) {
|
||||
stringToShapeTypeLookup[ShapeInfo::getNameForShapeType(type)] = type;
|
||||
inline void addShapeType(QHash<QString, ShapeType>& lookup, ShapeType type) { lookup[ShapeInfo::getNameForShapeType(type)] = type; }
|
||||
QHash<QString, ShapeType> stringToShapeTypeLookup = [] {
|
||||
QHash<QString, ShapeType> toReturn;
|
||||
addShapeType(toReturn, SHAPE_TYPE_NONE);
|
||||
addShapeType(toReturn, SHAPE_TYPE_BOX);
|
||||
addShapeType(toReturn, SHAPE_TYPE_SPHERE);
|
||||
addShapeType(toReturn, SHAPE_TYPE_CAPSULE_X);
|
||||
addShapeType(toReturn, SHAPE_TYPE_CAPSULE_Y);
|
||||
addShapeType(toReturn, SHAPE_TYPE_CAPSULE_Z);
|
||||
addShapeType(toReturn, SHAPE_TYPE_CYLINDER_X);
|
||||
addShapeType(toReturn, SHAPE_TYPE_CYLINDER_Y);
|
||||
addShapeType(toReturn, SHAPE_TYPE_CYLINDER_Z);
|
||||
addShapeType(toReturn, SHAPE_TYPE_HULL);
|
||||
addShapeType(toReturn, SHAPE_TYPE_PLANE);
|
||||
addShapeType(toReturn, SHAPE_TYPE_COMPOUND);
|
||||
addShapeType(toReturn, SHAPE_TYPE_SIMPLE_HULL);
|
||||
addShapeType(toReturn, SHAPE_TYPE_SIMPLE_COMPOUND);
|
||||
addShapeType(toReturn, SHAPE_TYPE_STATIC_MESH);
|
||||
addShapeType(toReturn, SHAPE_TYPE_ELLIPSOID);
|
||||
addShapeType(toReturn, SHAPE_TYPE_CIRCLE);
|
||||
return toReturn;
|
||||
}();
|
||||
QString EntityItemProperties::getShapeTypeAsString() const { return ShapeInfo::getNameForShapeType(_shapeType); }
|
||||
void EntityItemProperties::setShapeTypeFromString(const QString& shapeName) {
|
||||
auto shapeTypeItr = stringToShapeTypeLookup.find(shapeName.toLower());
|
||||
if (shapeTypeItr != stringToShapeTypeLookup.end()) {
|
||||
_shapeType = shapeTypeItr.value();
|
||||
_shapeTypeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void buildStringToShapeTypeLookup() {
|
||||
addShapeType(SHAPE_TYPE_NONE);
|
||||
addShapeType(SHAPE_TYPE_BOX);
|
||||
addShapeType(SHAPE_TYPE_SPHERE);
|
||||
addShapeType(SHAPE_TYPE_CAPSULE_X);
|
||||
addShapeType(SHAPE_TYPE_CAPSULE_Y);
|
||||
addShapeType(SHAPE_TYPE_CAPSULE_Z);
|
||||
addShapeType(SHAPE_TYPE_CYLINDER_X);
|
||||
addShapeType(SHAPE_TYPE_CYLINDER_Y);
|
||||
addShapeType(SHAPE_TYPE_CYLINDER_Z);
|
||||
addShapeType(SHAPE_TYPE_HULL);
|
||||
addShapeType(SHAPE_TYPE_PLANE);
|
||||
addShapeType(SHAPE_TYPE_COMPOUND);
|
||||
addShapeType(SHAPE_TYPE_SIMPLE_HULL);
|
||||
addShapeType(SHAPE_TYPE_SIMPLE_COMPOUND);
|
||||
addShapeType(SHAPE_TYPE_STATIC_MESH);
|
||||
addShapeType(SHAPE_TYPE_ELLIPSOID);
|
||||
addShapeType(SHAPE_TYPE_CIRCLE);
|
||||
inline void addMaterialMappingMode(QHash<QString, MaterialMappingMode>& lookup, MaterialMappingMode mode) { lookup[MaterialMappingModeHelpers::getNameForMaterialMappingMode(mode)] = mode; }
|
||||
const QHash<QString, MaterialMappingMode> stringToMaterialMappingModeLookup = [] {
|
||||
QHash<QString, MaterialMappingMode> toReturn;
|
||||
addMaterialMappingMode(toReturn, UV);
|
||||
addMaterialMappingMode(toReturn, PROJECTED);
|
||||
return toReturn;
|
||||
}();
|
||||
QString EntityItemProperties::getMaterialMappingModeAsString() const { return MaterialMappingModeHelpers::getNameForMaterialMappingMode(_materialMappingMode); }
|
||||
void EntityItemProperties::setMaterialMappingModeFromString(const QString& materialMappingMode) {
|
||||
auto materialMappingModeItr = stringToMaterialMappingModeLookup.find(materialMappingMode.toLower());
|
||||
if (materialMappingModeItr != stringToMaterialMappingModeLookup.end()) {
|
||||
_materialMappingMode = materialMappingModeItr.value();
|
||||
_materialMappingModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, MaterialMappingMode> stringToMaterialMappingModeLookup;
|
||||
|
||||
void addMaterialMappingMode(MaterialMappingMode mode) {
|
||||
stringToMaterialMappingModeLookup[MaterialMappingModeHelpers::getNameForMaterialMappingMode(mode)] = mode;
|
||||
inline void addBillboardMode(QHash<QString, BillboardMode>& lookup, BillboardMode mode) { lookup[BillboardModeHelpers::getNameForBillboardMode(mode)] = mode; }
|
||||
const QHash<QString, BillboardMode> stringToBillboardModeLookup = [] {
|
||||
QHash<QString, BillboardMode> toReturn;
|
||||
addBillboardMode(toReturn, BillboardMode::NONE);
|
||||
addBillboardMode(toReturn, BillboardMode::YAW);
|
||||
addBillboardMode(toReturn, BillboardMode::FULL);
|
||||
return toReturn;
|
||||
}();
|
||||
QString EntityItemProperties::getBillboardModeAsString() const { return BillboardModeHelpers::getNameForBillboardMode(_billboardMode); }
|
||||
void EntityItemProperties::setBillboardModeFromString(const QString& billboardMode) {
|
||||
auto billboardModeItr = stringToBillboardModeLookup.find(billboardMode.toLower());
|
||||
if (billboardModeItr != stringToBillboardModeLookup.end()) {
|
||||
_billboardMode = billboardModeItr.value();
|
||||
_billboardModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void buildStringToMaterialMappingModeLookup() {
|
||||
addMaterialMappingMode(UV);
|
||||
addMaterialMappingMode(PROJECTED);
|
||||
inline void addRenderLayer(QHash<QString, RenderLayer>& lookup, RenderLayer mode) { lookup[RenderLayerHelpers::getNameForRenderLayer(mode)] = mode; }
|
||||
const QHash<QString, RenderLayer> stringToRenderLayerLookup = [] {
|
||||
QHash<QString, RenderLayer> toReturn;
|
||||
addRenderLayer(toReturn, RenderLayer::WORLD);
|
||||
addRenderLayer(toReturn, RenderLayer::FRONT);
|
||||
addRenderLayer(toReturn, RenderLayer::HUD);
|
||||
return toReturn;
|
||||
}();
|
||||
QString EntityItemProperties::getRenderLayerAsString() const { return RenderLayerHelpers::getNameForRenderLayer(_renderLayer); }
|
||||
void EntityItemProperties::setRenderLayerFromString(const QString& renderLayer) {
|
||||
auto renderLayerItr = stringToRenderLayerLookup.find(renderLayer.toLower());
|
||||
if (renderLayerItr != stringToRenderLayerLookup.end()) {
|
||||
_renderLayer = renderLayerItr.value();
|
||||
_renderLayerChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void addPrimitiveMode(QHash<QString, PrimitiveMode>& lookup, PrimitiveMode mode) { lookup[PrimitiveModeHelpers::getNameForPrimitiveMode(mode)] = mode; }
|
||||
const QHash<QString, PrimitiveMode> stringToPrimitiveModeLookup = [] {
|
||||
QHash<QString, PrimitiveMode> toReturn;
|
||||
addPrimitiveMode(toReturn, PrimitiveMode::SOLID);
|
||||
addPrimitiveMode(toReturn, PrimitiveMode::LINES);
|
||||
return toReturn;
|
||||
}();
|
||||
QString EntityItemProperties::getPrimitiveModeAsString() const { return PrimitiveModeHelpers::getNameForPrimitiveMode(_primitiveMode); }
|
||||
void EntityItemProperties::setPrimitiveModeFromString(const QString& primitiveMode) {
|
||||
auto primitiveModeItr = stringToPrimitiveModeLookup.find(primitiveMode.toLower());
|
||||
if (primitiveModeItr != stringToPrimitiveModeLookup.end()) {
|
||||
_primitiveMode = primitiveModeItr.value();
|
||||
_primitiveModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void addWebInputMode(QHash<QString, WebInputMode>& lookup, WebInputMode mode) { lookup[WebInputModeHelpers::getNameForWebInputMode(mode)] = mode; }
|
||||
const QHash<QString, WebInputMode> stringToWebInputModeLookup = [] {
|
||||
QHash<QString, WebInputMode> toReturn;
|
||||
addWebInputMode(toReturn, WebInputMode::TOUCH);
|
||||
addWebInputMode(toReturn, WebInputMode::MOUSE);
|
||||
return toReturn;
|
||||
}();
|
||||
QString EntityItemProperties::getInputModeAsString() const { return WebInputModeHelpers::getNameForWebInputMode(_inputMode); }
|
||||
void EntityItemProperties::setInputModeFromString(const QString& webInputMode) {
|
||||
auto webInputModeItr = stringToWebInputModeLookup.find(webInputMode.toLower());
|
||||
if (webInputModeItr != stringToWebInputModeLookup.end()) {
|
||||
_inputMode = webInputModeItr.value();
|
||||
_inputModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void addGizmoType(QHash<QString, GizmoType>& lookup, GizmoType mode) { lookup[GizmoTypeHelpers::getNameForGizmoType(mode)] = mode; }
|
||||
const QHash<QString, GizmoType> stringToGizmoTypeLookup = [] {
|
||||
QHash<QString, GizmoType> toReturn;
|
||||
addGizmoType(toReturn, GizmoType::RING);
|
||||
return toReturn;
|
||||
}();
|
||||
QString EntityItemProperties::getGizmoTypeAsString() const { return GizmoTypeHelpers::getNameForGizmoType(_gizmoType); }
|
||||
void EntityItemProperties::setGizmoTypeFromString(const QString& gizmoType) {
|
||||
auto gizmoTypeItr = stringToGizmoTypeLookup.find(gizmoType.toLower());
|
||||
if (gizmoTypeItr != stringToGizmoTypeLookup.end()) {
|
||||
_gizmoType = gizmoTypeItr.value();
|
||||
_gizmoTypeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void addComponentMode(QHash<QString, ComponentMode>& lookup, ComponentMode mode) { lookup[ComponentModeHelpers::getNameForComponentMode(mode)] = mode; }
|
||||
const QHash<QString, ComponentMode> stringToComponentMode = [] {
|
||||
QHash<QString, ComponentMode> toReturn;
|
||||
addComponentMode(toReturn, ComponentMode::COMPONENT_MODE_INHERIT);
|
||||
addComponentMode(toReturn, ComponentMode::COMPONENT_MODE_DISABLED);
|
||||
addComponentMode(toReturn, ComponentMode::COMPONENT_MODE_ENABLED);
|
||||
return toReturn;
|
||||
}();
|
||||
QString EntityItemProperties::getComponentModeAsString(uint32_t mode) { return ComponentModeHelpers::getNameForComponentMode((ComponentMode)mode); }
|
||||
QString EntityItemProperties::getSkyboxModeAsString() const { return getComponentModeAsString(_skyboxMode); }
|
||||
QString EntityItemProperties::getKeyLightModeAsString() const { return getComponentModeAsString(_keyLightMode); }
|
||||
QString EntityItemProperties::getAmbientLightModeAsString() const { return getComponentModeAsString(_ambientLightMode); }
|
||||
QString EntityItemProperties::getHazeModeAsString() const { return getComponentModeAsString(_hazeMode); }
|
||||
QString EntityItemProperties::getBloomModeAsString() const { return getComponentModeAsString(_bloomMode); }
|
||||
void EntityItemProperties::setSkyboxModeFromString(const QString& mode) {
|
||||
auto modeItr = stringToComponentMode.find(mode.toLower());
|
||||
if (modeItr != stringToComponentMode.end()) {
|
||||
_skyboxMode = modeItr.value();
|
||||
_skyboxModeChanged = true;
|
||||
}
|
||||
}
|
||||
void EntityItemProperties::setKeyLightModeFromString(const QString& mode) {
|
||||
auto modeItr = stringToComponentMode.find(mode.toLower());
|
||||
if (modeItr != stringToComponentMode.end()) {
|
||||
_keyLightMode = modeItr.value();
|
||||
_keyLightModeChanged = true;
|
||||
}
|
||||
}
|
||||
void EntityItemProperties::setAmbientLightModeFromString(const QString& mode) {
|
||||
auto modeItr = stringToComponentMode.find(mode.toLower());
|
||||
if (modeItr != stringToComponentMode.end()) {
|
||||
_ambientLightMode = modeItr.value();
|
||||
_ambientLightModeChanged = true;
|
||||
}
|
||||
}
|
||||
void EntityItemProperties::setHazeModeFromString(const QString& mode) {
|
||||
auto modeItr = stringToComponentMode.find(mode.toLower());
|
||||
if (modeItr != stringToComponentMode.end()) {
|
||||
_hazeMode = modeItr.value();
|
||||
_hazeModeChanged = true;
|
||||
}
|
||||
}
|
||||
void EntityItemProperties::setBloomModeFromString(const QString& mode) {
|
||||
auto modeItr = stringToComponentMode.find(mode.toLower());
|
||||
if (modeItr != stringToComponentMode.end()) {
|
||||
_bloomMode = modeItr.value();
|
||||
_bloomModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
inline void addAvatarPriorityMode(QHash<QString, AvatarPriorityMode>& lookup, AvatarPriorityMode mode) { lookup[AvatarPriorityModeHelpers::getNameForAvatarPriorityMode(mode)] = mode; }
|
||||
const QHash<QString, AvatarPriorityMode> stringToAvatarPriority = [] {
|
||||
QHash<QString, AvatarPriorityMode> toReturn;
|
||||
addAvatarPriorityMode(toReturn, AvatarPriorityMode::AVATAR_PRIORITY_INHERIT);
|
||||
addAvatarPriorityMode(toReturn, AvatarPriorityMode::AVATAR_PRIORITY_CROWD);
|
||||
addAvatarPriorityMode(toReturn, AvatarPriorityMode::AVATAR_PRIORITY_HERO);
|
||||
return toReturn;
|
||||
}();
|
||||
QString EntityItemProperties::getAvatarPriorityAsString() const { return AvatarPriorityModeHelpers::getNameForAvatarPriorityMode((AvatarPriorityMode)_avatarPriority); }
|
||||
void EntityItemProperties::setAvatarPriorityFromString(const QString& mode) {
|
||||
auto modeItr = stringToAvatarPriority.find(mode.toLower());
|
||||
if (modeItr != stringToAvatarPriority.end()) {
|
||||
_avatarPriority = modeItr.value();
|
||||
_avatarPriorityChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QString getCollisionGroupAsString(uint16_t group) {
|
||||
|
@ -194,134 +352,6 @@ void EntityItemProperties::setCollisionMaskFromString(const QString& maskString)
|
|||
_collisionMaskChanged = true;
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getShapeTypeAsString() const {
|
||||
return ShapeInfo::getNameForShapeType(_shapeType);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setShapeTypeFromString(const QString& shapeName) {
|
||||
if (stringToShapeTypeLookup.empty()) {
|
||||
buildStringToShapeTypeLookup();
|
||||
}
|
||||
auto shapeTypeItr = stringToShapeTypeLookup.find(shapeName.toLower());
|
||||
if (shapeTypeItr != stringToShapeTypeLookup.end()) {
|
||||
_shapeType = shapeTypeItr.value();
|
||||
_shapeTypeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getComponentModeAsString(uint32_t mode) {
|
||||
// return "inherit" if mode is not valid
|
||||
if (mode < COMPONENT_MODE_ITEM_COUNT) {
|
||||
return COMPONENT_MODES[mode].second;
|
||||
} else {
|
||||
return COMPONENT_MODES[COMPONENT_MODE_INHERIT].second;
|
||||
}
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getHazeModeAsString() const {
|
||||
return getComponentModeAsString(_hazeMode);
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getBloomModeAsString() const {
|
||||
return getComponentModeAsString(_bloomMode);
|
||||
}
|
||||
|
||||
namespace {
|
||||
const QStringList AVATAR_PRIORITIES_AS_STRING
|
||||
{ "inherit", "crowd", "hero" };
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getAvatarPriorityAsString() const {
|
||||
return AVATAR_PRIORITIES_AS_STRING.value(_avatarPriority);
|
||||
}
|
||||
|
||||
std::array<ComponentPair, COMPONENT_MODE_ITEM_COUNT>::const_iterator EntityItemProperties::findComponent(const QString& mode) {
|
||||
return std::find_if(COMPONENT_MODES.begin(), COMPONENT_MODES.end(), [&](const ComponentPair& pair) {
|
||||
return (pair.second == mode);
|
||||
});
|
||||
}
|
||||
|
||||
void EntityItemProperties::setHazeModeFromString(const QString& hazeMode) {
|
||||
auto result = findComponent(hazeMode);
|
||||
|
||||
if (result != COMPONENT_MODES.end()) {
|
||||
_hazeMode = result->first;
|
||||
_hazeModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityItemProperties::setBloomModeFromString(const QString& bloomMode) {
|
||||
auto result = findComponent(bloomMode);
|
||||
|
||||
if (result != COMPONENT_MODES.end()) {
|
||||
_bloomMode = result->first;
|
||||
_bloomModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
void EntityItemProperties::setAvatarPriorityFromString(QString const& avatarPriority) {
|
||||
auto result = AVATAR_PRIORITIES_AS_STRING.indexOf(avatarPriority);
|
||||
|
||||
if (result != -1) {
|
||||
_avatarPriority = result;
|
||||
_avatarPriorityChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getKeyLightModeAsString() const {
|
||||
return getComponentModeAsString(_keyLightMode);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setKeyLightModeFromString(const QString& keyLightMode) {
|
||||
auto result = findComponent(keyLightMode);
|
||||
|
||||
if (result != COMPONENT_MODES.end()) {
|
||||
_keyLightMode = result->first;
|
||||
_keyLightModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getAmbientLightModeAsString() const {
|
||||
return getComponentModeAsString(_ambientLightMode);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setAmbientLightModeFromString(const QString& ambientLightMode) {
|
||||
auto result = findComponent(ambientLightMode);
|
||||
|
||||
if (result != COMPONENT_MODES.end()) {
|
||||
_ambientLightMode = result->first;
|
||||
_ambientLightModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getSkyboxModeAsString() const {
|
||||
return getComponentModeAsString(_skyboxMode);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setSkyboxModeFromString(const QString& skyboxMode) {
|
||||
auto result = findComponent(skyboxMode);
|
||||
|
||||
if (result != COMPONENT_MODES.end()) {
|
||||
_skyboxMode = result->first;
|
||||
_skyboxModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getMaterialMappingModeAsString() const {
|
||||
return MaterialMappingModeHelpers::getNameForMaterialMappingMode(_materialMappingMode);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setMaterialMappingModeFromString(const QString& materialMappingMode) {
|
||||
if (stringToMaterialMappingModeLookup.empty()) {
|
||||
buildStringToMaterialMappingModeLookup();
|
||||
}
|
||||
auto materialMappingModeItr = stringToMaterialMappingModeLookup.find(materialMappingMode.toLower());
|
||||
if (materialMappingModeItr != stringToMaterialMappingModeLookup.end()) {
|
||||
_materialMappingMode = materialMappingModeItr.value();
|
||||
_materialMappingModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getEntityHostTypeAsString() const {
|
||||
switch (_entityHostType) {
|
||||
case entity::HostType::DOMAIN:
|
||||
|
@ -345,137 +375,6 @@ void EntityItemProperties::setEntityHostTypeFromString(const QString& entityHost
|
|||
}
|
||||
}
|
||||
|
||||
QHash<QString, BillboardMode> stringToBillboardModeLookup;
|
||||
|
||||
void addBillboardMode(BillboardMode mode) {
|
||||
stringToBillboardModeLookup[BillboardModeHelpers::getNameForBillboardMode(mode)] = mode;
|
||||
}
|
||||
|
||||
void buildStringToBillboardModeLookup() {
|
||||
addBillboardMode(BillboardMode::NONE);
|
||||
addBillboardMode(BillboardMode::YAW);
|
||||
addBillboardMode(BillboardMode::FULL);
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getBillboardModeAsString() const {
|
||||
return BillboardModeHelpers::getNameForBillboardMode(_billboardMode);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setBillboardModeFromString(const QString& billboardMode) {
|
||||
if (stringToBillboardModeLookup.empty()) {
|
||||
buildStringToBillboardModeLookup();
|
||||
}
|
||||
auto billboardModeItr = stringToBillboardModeLookup.find(billboardMode.toLower());
|
||||
if (billboardModeItr != stringToBillboardModeLookup.end()) {
|
||||
_billboardMode = billboardModeItr.value();
|
||||
_billboardModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, RenderLayer> stringToRenderLayerLookup;
|
||||
|
||||
void addRenderLayer(RenderLayer mode) {
|
||||
stringToRenderLayerLookup[RenderLayerHelpers::getNameForRenderLayer(mode)] = mode;
|
||||
}
|
||||
|
||||
void buildStringToRenderLayerLookup() {
|
||||
addRenderLayer(RenderLayer::WORLD);
|
||||
addRenderLayer(RenderLayer::FRONT);
|
||||
addRenderLayer(RenderLayer::HUD);
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getRenderLayerAsString() const {
|
||||
return RenderLayerHelpers::getNameForRenderLayer(_renderLayer);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setRenderLayerFromString(const QString& renderLayer) {
|
||||
if (stringToRenderLayerLookup.empty()) {
|
||||
buildStringToRenderLayerLookup();
|
||||
}
|
||||
auto renderLayerItr = stringToRenderLayerLookup.find(renderLayer.toLower());
|
||||
if (renderLayerItr != stringToRenderLayerLookup.end()) {
|
||||
_renderLayer = renderLayerItr.value();
|
||||
_renderLayerChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, PrimitiveMode> stringToPrimitiveModeLookup;
|
||||
|
||||
void addPrimitiveMode(PrimitiveMode mode) {
|
||||
stringToPrimitiveModeLookup[PrimitiveModeHelpers::getNameForPrimitiveMode(mode)] = mode;
|
||||
}
|
||||
|
||||
void buildStringToPrimitiveModeLookup() {
|
||||
addPrimitiveMode(PrimitiveMode::SOLID);
|
||||
addPrimitiveMode(PrimitiveMode::LINES);
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getPrimitiveModeAsString() const {
|
||||
return PrimitiveModeHelpers::getNameForPrimitiveMode(_primitiveMode);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setPrimitiveModeFromString(const QString& primitiveMode) {
|
||||
if (stringToPrimitiveModeLookup.empty()) {
|
||||
buildStringToPrimitiveModeLookup();
|
||||
}
|
||||
auto primitiveModeItr = stringToPrimitiveModeLookup.find(primitiveMode.toLower());
|
||||
if (primitiveModeItr != stringToPrimitiveModeLookup.end()) {
|
||||
_primitiveMode = primitiveModeItr.value();
|
||||
_primitiveModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, WebInputMode> stringToWebInputModeLookup;
|
||||
|
||||
void addWebInputMode(WebInputMode mode) {
|
||||
stringToWebInputModeLookup[WebInputModeHelpers::getNameForWebInputMode(mode)] = mode;
|
||||
}
|
||||
|
||||
void buildStringToWebInputModeLookup() {
|
||||
addWebInputMode(WebInputMode::TOUCH);
|
||||
addWebInputMode(WebInputMode::MOUSE);
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getInputModeAsString() const {
|
||||
return WebInputModeHelpers::getNameForWebInputMode(_inputMode);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setInputModeFromString(const QString& webInputMode) {
|
||||
if (stringToWebInputModeLookup.empty()) {
|
||||
buildStringToWebInputModeLookup();
|
||||
}
|
||||
auto webInputModeItr = stringToWebInputModeLookup.find(webInputMode.toLower());
|
||||
if (webInputModeItr != stringToWebInputModeLookup.end()) {
|
||||
_inputMode = webInputModeItr.value();
|
||||
_inputModeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
QHash<QString, GizmoType> stringToGizmoTypeLookup;
|
||||
|
||||
void addGizmoType(GizmoType mode) {
|
||||
stringToGizmoTypeLookup[GizmoTypeHelpers::getNameForGizmoType(mode)] = mode;
|
||||
}
|
||||
|
||||
void buildStringToGizmoTypeLookup() {
|
||||
addGizmoType(GizmoType::RING);
|
||||
}
|
||||
|
||||
QString EntityItemProperties::getGizmoTypeAsString() const {
|
||||
return GizmoTypeHelpers::getNameForGizmoType(_gizmoType);
|
||||
}
|
||||
|
||||
void EntityItemProperties::setGizmoTypeFromString(const QString& gizmoType) {
|
||||
if (stringToGizmoTypeLookup.empty()) {
|
||||
buildStringToGizmoTypeLookup();
|
||||
}
|
||||
auto gizmoTypeItr = stringToGizmoTypeLookup.find(gizmoType.toLower());
|
||||
if (gizmoTypeItr != stringToGizmoTypeLookup.end()) {
|
||||
_gizmoType = gizmoTypeItr.value();
|
||||
_gizmoTypeChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||
EntityPropertyFlags changedProperties;
|
||||
|
||||
|
|
|
@ -67,13 +67,6 @@
|
|||
|
||||
const quint64 UNKNOWN_CREATED_TIME = 0;
|
||||
|
||||
using ComponentPair = std::pair<const ComponentMode, const QString>;
|
||||
const std::array<ComponentPair, COMPONENT_MODE_ITEM_COUNT> COMPONENT_MODES = { {
|
||||
ComponentPair { COMPONENT_MODE_INHERIT, { "inherit" } },
|
||||
ComponentPair { COMPONENT_MODE_DISABLED, { "disabled" } },
|
||||
ComponentPair { COMPONENT_MODE_ENABLED, { "enabled" } }
|
||||
} };
|
||||
|
||||
using vec3Color = glm::vec3;
|
||||
using u8vec3Color = glm::u8vec3;
|
||||
|
||||
|
@ -400,8 +393,6 @@ public:
|
|||
|
||||
static QString getComponentModeAsString(uint32_t mode);
|
||||
|
||||
std::array<ComponentPair, COMPONENT_MODE_ITEM_COUNT>::const_iterator findComponent(const QString& mode);
|
||||
|
||||
public:
|
||||
float getMaxDimension() const { return glm::compMax(_dimensions); }
|
||||
|
||||
|
|
|
@ -220,6 +220,10 @@ void GL45Texture::generateMips() const {
|
|||
(void)CHECK_GL_ERROR();
|
||||
}
|
||||
|
||||
// (NOTE: it seems to work now, but for posterity:) DSA ARB does not work on AMD, so use EXT
|
||||
// unless EXT is not available on the driver
|
||||
#define AMD_CUBE_MAP_EXT_WORKAROUND 0
|
||||
|
||||
Size GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const uvec3& size, uint32_t yOffset, GLenum internalFormat, GLenum format, GLenum type, Size sourceSize, const void* sourcePointer) const {
|
||||
Size amountCopied = sourceSize;
|
||||
if (GL_TEXTURE_2D == _target) {
|
||||
|
@ -267,22 +271,26 @@ Size GL45Texture::copyMipFaceLinesFromTexture(uint16_t mip, uint8_t face, const
|
|||
case GL_COMPRESSED_SIGNED_R11_EAC:
|
||||
case GL_COMPRESSED_RG11_EAC:
|
||||
case GL_COMPRESSED_SIGNED_RG11_EAC:
|
||||
#if AMD_CUBE_MAP_EXT_WORKAROUND
|
||||
if (glCompressedTextureSubImage2DEXT) {
|
||||
auto target = GLTexture::CUBE_FACE_LAYOUT[face];
|
||||
glCompressedTextureSubImage2DEXT(_id, target, mip, 0, yOffset, size.x, size.y, internalFormat,
|
||||
static_cast<GLsizei>(sourceSize), sourcePointer);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
glCompressedTextureSubImage3D(_id, mip, 0, yOffset, face, size.x, size.y, 1, internalFormat,
|
||||
static_cast<GLsizei>(sourceSize), sourcePointer);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// DSA ARB does not work on AMD, so use EXT
|
||||
// unless EXT is not available on the driver
|
||||
#if AMD_CUBE_MAP_EXT_WORKAROUND
|
||||
if (glTextureSubImage2DEXT) {
|
||||
auto target = GLTexture::CUBE_FACE_LAYOUT[face];
|
||||
glTextureSubImage2DEXT(_id, target, mip, 0, yOffset, size.x, size.y, format, type, sourcePointer);
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
glTextureSubImage3D(_id, mip, 0, yOffset, face, size.x, size.y, 1, format, type, sourcePointer);
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -26,8 +26,8 @@ const Element Element::COLOR_COMPRESSED_BCX_SRGB { TILE4x4, COMPRESSED, COMPRESS
|
|||
const Element Element::COLOR_COMPRESSED_BCX_SRGBA_MASK { TILE4x4, COMPRESSED, COMPRESSED_BC1_SRGBA };
|
||||
const Element Element::COLOR_COMPRESSED_BCX_SRGBA { TILE4x4, COMPRESSED, COMPRESSED_BC3_SRGBA };
|
||||
const Element Element::COLOR_COMPRESSED_BCX_XY { TILE4x4, COMPRESSED, COMPRESSED_BC5_XY };
|
||||
const Element Element::COLOR_COMPRESSED_BCX_SRGBA_HIGH { TILE4x4, COMPRESSED, COMPRESSED_BC7_SRGBA };
|
||||
const Element Element::COLOR_COMPRESSED_BCX_HDR_RGB { TILE4x4, COMPRESSED, COMPRESSED_BC6_RGB };
|
||||
const Element Element::COLOR_COMPRESSED_BCX_SRGBA_HIGH { TILE4x4, COMPRESSED, COMPRESSED_BC7_SRGBA };
|
||||
|
||||
const Element Element::COLOR_COMPRESSED_ETC2_RGB { TILE4x4, COMPRESSED, COMPRESSED_ETC2_RGB };
|
||||
const Element Element::COLOR_COMPRESSED_ETC2_SRGB { TILE4x4, COMPRESSED, COMPRESSED_ETC2_SRGB };
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "Batch.h"
|
||||
#include "TextureTable.h"
|
||||
|
||||
|
||||
#include "FrameIOKeys.h"
|
||||
|
||||
namespace gpu {
|
||||
|
@ -324,6 +323,13 @@ TexturePointer Deserializer::readTexture(const json& node, uint32_t external) {
|
|||
readOptional(ktxFile, node, keys::ktxFile);
|
||||
Element ktxTexelFormat, ktxMipFormat;
|
||||
if (!ktxFile.empty()) {
|
||||
// If we get a texture that starts with ":" we need to re-route it to the resources directory
|
||||
if (ktxFile.at(0) == ':') {
|
||||
QString frameReaderPath = __FILE__;
|
||||
frameReaderPath.replace("\\", "/");
|
||||
frameReaderPath.replace("libraries/gpu/src/gpu/framereader.cpp", "interface/resources", Qt::CaseInsensitive);
|
||||
ktxFile.replace(0, 1, frameReaderPath.toStdString());
|
||||
}
|
||||
if (QFileInfo(ktxFile.c_str()).isRelative()) {
|
||||
ktxFile = basedir + ktxFile;
|
||||
}
|
||||
|
|
|
@ -26,13 +26,14 @@ layout(location=0) in vec3 _normal;
|
|||
layout(location=0) out vec4 _fragColor;
|
||||
|
||||
void main(void) {
|
||||
vec3 coord = normalize(_normal);
|
||||
vec3 color = skybox.color.rgb;
|
||||
// FIXME: For legacy reasons, when skybox.color.a is 0.5, this is equivalent to:
|
||||
// skyboxColor * skyboxTexel
|
||||
// It should actually be:
|
||||
// mix(skyboxColor, skyboxTexel, skybox.color.a)
|
||||
// and the blend factor should be user controlled
|
||||
|
||||
// blend is only set if there is a cubemap
|
||||
float check = float(skybox.color.a > 0.0);
|
||||
color = mix(color, texture(cubeMap, coord).rgb, check);
|
||||
color *= mix(vec3(1.0), skybox.color.rgb, check * float(skybox.color.a < 1.0));
|
||||
|
||||
_fragColor = vec4(color, 0.0);
|
||||
vec3 skyboxTexel = texture(cubeMap, normalize(_normal)).rgb;
|
||||
vec3 skyboxColor = skybox.color.rgb;
|
||||
_fragColor = vec4(mix(vec3(1.0), skyboxTexel, float(skybox.color.a > 0.0)) *
|
||||
mix(vec3(1.0), skyboxColor, float(skybox.color.a < 1.0)), 1.0);
|
||||
}
|
||||
|
|
|
@ -690,6 +690,8 @@ void convertImageToLDRTexture(gpu::Texture* texture, Image&& image, BackendTarge
|
|||
compressionOptions.setFormat(nvtt::Format_BC4);
|
||||
} else if (mipFormat == gpu::Element::COLOR_COMPRESSED_BCX_XY) {
|
||||
compressionOptions.setFormat(nvtt::Format_BC5);
|
||||
} else if (mipFormat == gpu::Element::COLOR_COMPRESSED_BCX_HDR_RGB) {
|
||||
compressionOptions.setFormat(nvtt::Format_BC6);
|
||||
} else if (mipFormat == gpu::Element::COLOR_COMPRESSED_BCX_SRGBA_HIGH) {
|
||||
alphaMode = nvtt::AlphaMode_Transparency;
|
||||
compressionOptions.setFormat(nvtt::Format_BC7);
|
||||
|
|
|
@ -57,6 +57,7 @@ namespace TextureUsage {
|
|||
* @typedef {number} TextureCache.TextureType
|
||||
*/
|
||||
enum Type {
|
||||
// NOTE: add new texture types at the bottom here
|
||||
DEFAULT_TEXTURE,
|
||||
STRICT_TEXTURE,
|
||||
ALBEDO_TEXTURE,
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <QJsonObject>
|
||||
|
||||
const QString TEXTURE_META_EXTENSION = ".texmeta.json";
|
||||
const uint16_t KTX_VERSION = 1;
|
||||
|
||||
bool TextureMeta::deserialize(const QByteArray& data, TextureMeta* meta) {
|
||||
QJsonParseError error;
|
||||
|
@ -46,6 +47,9 @@ bool TextureMeta::deserialize(const QByteArray& data, TextureMeta* meta) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (root.contains("version")) {
|
||||
meta->version = root["version"].toInt();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -62,6 +66,7 @@ QByteArray TextureMeta::serialize() {
|
|||
root["original"] = original.toString();
|
||||
root["uncompressed"] = uncompressed.toString();
|
||||
root["compressed"] = compressed;
|
||||
root["version"] = KTX_VERSION;
|
||||
doc.setObject(root);
|
||||
|
||||
return doc.toJson();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "khronos/KHR.h"
|
||||
|
||||
extern const QString TEXTURE_META_EXTENSION;
|
||||
extern const uint16_t KTX_VERSION;
|
||||
|
||||
namespace std {
|
||||
template<> struct hash<khronos::gl::texture::InternalFormat> {
|
||||
|
@ -37,6 +38,7 @@ struct TextureMeta {
|
|||
QUrl original;
|
||||
QUrl uncompressed;
|
||||
std::unordered_map<khronos::gl::texture::InternalFormat, QUrl> availableTextureTypes;
|
||||
uint16_t version { 0 };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ void AccountManager::logout() {
|
|||
|
||||
// remove this account from the account settings file
|
||||
removeAccountFromFile();
|
||||
saveLoginStatus(false);
|
||||
|
||||
emit logoutComplete();
|
||||
// the username has changed to blank
|
||||
|
@ -650,6 +651,39 @@ void AccountManager::refreshAccessToken() {
|
|||
}
|
||||
}
|
||||
|
||||
void AccountManager::setAccessTokens(const QString& response) {
|
||||
QJsonDocument jsonResponse = QJsonDocument::fromJson(response.toUtf8());
|
||||
const QJsonObject& rootObject = jsonResponse.object();
|
||||
|
||||
if (!rootObject.contains("error")) {
|
||||
// construct an OAuthAccessToken from the json object
|
||||
|
||||
if (!rootObject.contains("access_token") || !rootObject.contains("expires_in")
|
||||
|| !rootObject.contains("token_type")) {
|
||||
// TODO: error handling - malformed token response
|
||||
qCDebug(networking) << "Received a response for password grant that is missing one or more expected values.";
|
||||
} else {
|
||||
// clear the path from the response URL so we have the right root URL for this access token
|
||||
QUrl rootURL = rootObject.contains("url") ? rootObject["url"].toString() : _authURL;
|
||||
rootURL.setPath("");
|
||||
|
||||
qCDebug(networking) << "Storing an account with access-token for" << qPrintable(rootURL.toString());
|
||||
|
||||
_accountInfo = DataServerAccountInfo();
|
||||
_accountInfo.setAccessTokenFromJSON(rootObject);
|
||||
emit loginComplete(rootURL);
|
||||
|
||||
persistAccountToFile();
|
||||
saveLoginStatus(true);
|
||||
requestProfile();
|
||||
}
|
||||
} else {
|
||||
// TODO: error handling
|
||||
qCDebug(networking) << "Error in response for password grant -" << rootObject["error_description"].toString();
|
||||
emit loginFailed();
|
||||
}
|
||||
}
|
||||
|
||||
void AccountManager::requestAccessTokenFinished() {
|
||||
QNetworkReply* requestReply = reinterpret_cast<QNetworkReply*>(sender());
|
||||
|
||||
|
@ -895,3 +929,34 @@ void AccountManager::handleKeypairGenerationError() {
|
|||
void AccountManager::setLimitedCommerce(bool isLimited) {
|
||||
_limitedCommerce = isLimited;
|
||||
}
|
||||
|
||||
void AccountManager::saveLoginStatus(bool isLoggedIn) {
|
||||
if (!_configFileURL.isEmpty()) {
|
||||
QFile configFile(_configFileURL);
|
||||
configFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
QJsonParseError error;
|
||||
QJsonDocument jsonDocument = QJsonDocument::fromJson(configFile.readAll(), &error);
|
||||
configFile.close();
|
||||
QString launcherPath;
|
||||
if (error.error == QJsonParseError::NoError) {
|
||||
QJsonObject rootObject = jsonDocument.object();
|
||||
if (rootObject.contains("launcherPath")) {
|
||||
launcherPath = rootObject["launcherPath"].toString();
|
||||
}
|
||||
if (rootObject.contains("loggedIn")) {
|
||||
rootObject["loggedIn"] = isLoggedIn;
|
||||
}
|
||||
jsonDocument = QJsonDocument(rootObject);
|
||||
|
||||
}
|
||||
configFile.open(QFile::WriteOnly | QFile::Text | QFile::Truncate);
|
||||
configFile.write(jsonDocument.toJson());
|
||||
configFile.close();
|
||||
if (!isLoggedIn && !launcherPath.isEmpty()) {
|
||||
QProcess launcher;
|
||||
launcher.setProgram(launcherPath);
|
||||
launcher.startDetached();
|
||||
qApp->quit();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -102,6 +102,10 @@ public:
|
|||
bool getLimitedCommerce() { return _limitedCommerce; }
|
||||
void setLimitedCommerce(bool isLimited);
|
||||
|
||||
void setAccessTokens(const QString& response);
|
||||
void setConfigFileURL(const QString& fileURL) { _configFileURL = fileURL; }
|
||||
void saveLoginStatus(bool isLoggedIn);
|
||||
|
||||
public slots:
|
||||
void requestAccessToken(const QString& login, const QString& password);
|
||||
void requestAccessTokenWithSteam(QByteArray authSessionTicket);
|
||||
|
@ -162,6 +166,7 @@ private:
|
|||
QUuid _sessionID { QUuid::createUuid() };
|
||||
|
||||
bool _limitedCommerce { false };
|
||||
QString _configFileURL;
|
||||
};
|
||||
|
||||
#endif // hifi_AccountManager_h
|
||||
|
|
|
@ -869,6 +869,8 @@ void LimitedNodeList::removeSilentNodes() {
|
|||
|
||||
QSet<SharedNodePointer> killedNodes;
|
||||
|
||||
auto startedAt = usecTimestampNow();
|
||||
|
||||
eachNodeHashIterator([&](NodeHash::iterator& it){
|
||||
SharedNodePointer node = it->second;
|
||||
node->getMutex().lock();
|
||||
|
@ -889,7 +891,15 @@ void LimitedNodeList::removeSilentNodes() {
|
|||
});
|
||||
|
||||
foreach(const SharedNodePointer& killedNode, killedNodes) {
|
||||
qCDebug(networking_ice) << "Removing silent node" << killedNode;
|
||||
auto now = usecTimestampNow();
|
||||
qCDebug(networking_ice) << "Removing silent node" << *killedNode << "\n"
|
||||
<< " Now: " << now << "\n"
|
||||
<< " Started at: " << startedAt << " (" << (now - startedAt) << "us ago)\n"
|
||||
<< " Last Heard Microstamp: " << killedNode->getLastHeardMicrostamp() << " (" << (now - killedNode->getLastHeardMicrostamp()) << "us ago)\n"
|
||||
<< " Forced Never Silent: " << killedNode->isForcedNeverSilent() << "\n"
|
||||
<< " Inbound PPS: " << killedNode->getInboundPPS() << "\n"
|
||||
<< " Inbound Kbps: " << killedNode->getInboundKbps() << "\n"
|
||||
<< " Ping: " << killedNode->getPingMs();
|
||||
handleNodeKill(killedNode);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include "NodeList.h"
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QJsonDocument>
|
||||
|
@ -37,6 +39,8 @@
|
|||
#include "SharedUtil.h"
|
||||
#include <Trace.h>
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
const int KEEPALIVE_PING_INTERVAL_MS = 1000;
|
||||
|
||||
NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) :
|
||||
|
@ -412,7 +416,7 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
packetStream << FingerprintUtils::getMachineFingerprint();
|
||||
}
|
||||
|
||||
packetStream << usecTimestampNow();
|
||||
packetStream << quint64(duration_cast<microseconds>(system_clock::now().time_since_epoch()).count());
|
||||
|
||||
// pack our data to send to the domain-server including
|
||||
// the hostname information (so the domain-server can see which place name we came in on)
|
||||
|
@ -641,35 +645,41 @@ void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message)
|
|||
// pull the permissions/right/privileges for this node out of the stream
|
||||
NodePermissions newPermissions;
|
||||
packetStream >> newPermissions;
|
||||
setPermissions(newPermissions);
|
||||
// Is packet authentication enabled?
|
||||
bool isAuthenticated;
|
||||
packetStream >> isAuthenticated;
|
||||
setAuthenticatePackets(isAuthenticated);
|
||||
|
||||
qint64 now = qint64(duration_cast<microseconds>(system_clock::now().time_since_epoch()).count());
|
||||
|
||||
quint64 connectRequestTimestamp;
|
||||
quint64 now = usecTimestampNow();
|
||||
packetStream >> connectRequestTimestamp;
|
||||
quint64 pingLagTime = (now - connectRequestTimestamp) / USECS_PER_MSEC;
|
||||
quint64 domainServerPingReceiveTime;
|
||||
|
||||
packetStream >> domainServerPingReceiveTime;
|
||||
quint64 domainServerRequestLag = (domainServerPingReceiveTime - connectRequestTimestamp) / USECS_PER_MSEC;
|
||||
quint64 domainServerResponseLag = (now - domainServerPingReceiveTime) / USECS_PER_MSEC;
|
||||
quint64 domainServerPingSendTime;
|
||||
packetStream >> domainServerPingSendTime;
|
||||
|
||||
quint64 domainServerCheckinProcessingTime;
|
||||
packetStream >> domainServerCheckinProcessingTime;
|
||||
|
||||
qint64 pingLagTime = (now - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC);
|
||||
|
||||
qint64 domainServerRequestLag = (qint64(domainServerPingSendTime - domainServerCheckinProcessingTime) - qint64(connectRequestTimestamp)) / qint64(USECS_PER_MSEC);;
|
||||
qint64 domainServerResponseLag = (now - qint64(domainServerPingSendTime)) / qint64(USECS_PER_MSEC);
|
||||
|
||||
if (_domainHandler.getSockAddr().isNull()) {
|
||||
qWarning(networking) << "IGNORING DomainList packet while not connected to a Domain Server: sent " << pingLagTime << " msec ago.";
|
||||
qWarning(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec";
|
||||
qWarning(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec";
|
||||
qWarning(networking) << "DomainList request lag (interface->ds): " << domainServerRequestLag << "msec";
|
||||
qWarning(networking) << "DomainList server processing time: " << domainServerCheckinProcessingTime << "usec";
|
||||
qWarning(networking) << "DomainList response lag (ds->interface): " << domainServerResponseLag << "msec";
|
||||
// refuse to process this packet if we aren't currently connected to the DS
|
||||
return;
|
||||
}
|
||||
|
||||
// warn if ping lag is getting long
|
||||
if (pingLagTime > MSECS_PER_SECOND) {
|
||||
if (pingLagTime > qint64(MSECS_PER_SECOND)) {
|
||||
qCDebug(networking) << "DomainList ping is lagging: " << pingLagTime << "msec";
|
||||
qCDebug(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec";
|
||||
qCDebug(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec";
|
||||
qCDebug(networking) << "DomainList request lag (interface->ds): " << domainServerRequestLag << "msec";
|
||||
qCDebug(networking) << "DomainList server processing time: " << domainServerCheckinProcessingTime << "usec";
|
||||
qCDebug(networking) << "DomainList response lag (ds->interface): " << domainServerResponseLag << "msec";
|
||||
}
|
||||
|
||||
// this is a packet from the domain server, reset the count of un-replied check-ins
|
||||
|
@ -684,8 +694,9 @@ void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message)
|
|||
// Recieved packet from different domain.
|
||||
qWarning() << "IGNORING DomainList packet from" << domainUUID << "while connected to"
|
||||
<< _domainHandler.getUUID() << ": sent " << pingLagTime << " msec ago.";
|
||||
qWarning(networking) << "DomainList request lag (with skew): " << domainServerRequestLag << "msec";
|
||||
qWarning(networking) << "DomainList response lag (with skew): " << domainServerResponseLag << "msec";
|
||||
qWarning(networking) << "DomainList request lag (interface->ds): " << domainServerRequestLag << "msec";
|
||||
qWarning(networking) << "DomainList server processing time: " << domainServerCheckinProcessingTime << "usec";
|
||||
qWarning(networking) << "DomainList response lag (ds->interface): " << domainServerResponseLag << "msec";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -719,6 +730,9 @@ void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message)
|
|||
DependencyManager::get<AddressManager>()->lookupShareableNameForDomainID(domainUUID);
|
||||
}
|
||||
|
||||
setPermissions(newPermissions);
|
||||
setAuthenticatePackets(isAuthenticated);
|
||||
|
||||
// pull each node in the packet
|
||||
while (packetStream.device()->pos() < message->getSize()) {
|
||||
parseNodeFromPacketStream(packetStream);
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "ReceivedMessage.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
|
||||
#include "QSharedPointer"
|
||||
|
||||
|
@ -20,6 +21,8 @@ int sharedPtrReceivedMessageMetaTypeId = qRegisterMetaType<QSharedPointer<Receiv
|
|||
|
||||
static const int HEAD_DATA_SIZE = 512;
|
||||
|
||||
using namespace std::chrono;
|
||||
|
||||
ReceivedMessage::ReceivedMessage(const NLPacketList& packetList)
|
||||
: _data(packetList.getMessage()),
|
||||
_headData(_data.mid(0, HEAD_DATA_SIZE)),
|
||||
|
@ -29,6 +32,7 @@ ReceivedMessage::ReceivedMessage(const NLPacketList& packetList)
|
|||
_packetVersion(packetList.getVersion()),
|
||||
_senderSockAddr(packetList.getSenderSockAddr())
|
||||
{
|
||||
_firstPacketReceiveTime = duration_cast<microseconds>(packetList.getFirstPacketReceiveTime().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
ReceivedMessage::ReceivedMessage(NLPacket& packet)
|
||||
|
@ -41,6 +45,7 @@ ReceivedMessage::ReceivedMessage(NLPacket& packet)
|
|||
_senderSockAddr(packet.getSenderSockAddr()),
|
||||
_isComplete(packet.getPacketPosition() == NLPacket::ONLY)
|
||||
{
|
||||
_firstPacketReceiveTime = duration_cast<microseconds>(packet.getReceiveTime().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
ReceivedMessage::ReceivedMessage(QByteArray byteArray, PacketType packetType, PacketVersion packetVersion,
|
||||
|
@ -48,6 +53,7 @@ ReceivedMessage::ReceivedMessage(QByteArray byteArray, PacketType packetType, Pa
|
|||
_data(byteArray),
|
||||
_headData(_data.mid(0, HEAD_DATA_SIZE)),
|
||||
_numPackets(1),
|
||||
_firstPacketReceiveTime(0),
|
||||
_sourceID(sourceID),
|
||||
_packetType(packetType),
|
||||
_packetVersion(packetVersion),
|
||||
|
@ -77,7 +83,13 @@ void ReceivedMessage::appendPacket(NLPacket& packet) {
|
|||
emit progress(getSize());
|
||||
}
|
||||
|
||||
if (packet.getPacketPosition() == NLPacket::PacketPosition::LAST) {
|
||||
auto packetPosition = packet.getPacketPosition();
|
||||
if ((packetPosition == NLPacket::PacketPosition::FIRST) ||
|
||||
(packetPosition == NLPacket::PacketPosition::ONLY)) {
|
||||
_firstPacketReceiveTime = duration_cast<microseconds>(packet.getReceiveTime().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
if (packetPosition == NLPacket::PacketPosition::LAST) {
|
||||
_isComplete = true;
|
||||
emit completed();
|
||||
}
|
||||
|
|
|
@ -48,6 +48,8 @@ public:
|
|||
// Get the number of packets that were used to send this message
|
||||
qint64 getNumPackets() const { return _numPackets; }
|
||||
|
||||
qint64 getFirstPacketReceiveTime() const { return _firstPacketReceiveTime; }
|
||||
|
||||
qint64 getSize() const { return _data.size(); }
|
||||
|
||||
qint64 getBytesLeftToRead() const { return _data.size() - _position; }
|
||||
|
@ -92,6 +94,7 @@ private:
|
|||
|
||||
std::atomic<qint64> _position { 0 };
|
||||
std::atomic<qint64> _numPackets { 0 };
|
||||
std::atomic<quint64> _firstPacketReceiveTime { 0 };
|
||||
|
||||
NLPacket::LocalID _sourceID { NLPacket::NULL_LOCAL_ID };
|
||||
PacketType _packetType;
|
||||
|
|
|
@ -171,6 +171,7 @@ void Packet::copyMembers(const Packet& other) {
|
|||
_packetPosition = other._packetPosition;
|
||||
_messageNumber = other._messageNumber;
|
||||
_messagePartNumber = other._messagePartNumber;
|
||||
_receiveTime = other._receiveTime;
|
||||
}
|
||||
|
||||
void Packet::readHeader() const {
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include "../NetworkLogging.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace udt;
|
||||
|
@ -261,3 +262,11 @@ qint64 PacketList::writeData(const char* data, qint64 maxSize) {
|
|||
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
p_high_resolution_clock::time_point PacketList::getFirstPacketReceiveTime() const {
|
||||
using namespace std::chrono;;
|
||||
if (!_packets.empty()) {
|
||||
return _packets.front()->getReceiveTime();
|
||||
}
|
||||
return p_high_resolution_clock::time_point();
|
||||
}
|
|
@ -59,6 +59,9 @@ public:
|
|||
virtual qint64 size() const override { return getDataSize(); }
|
||||
|
||||
qint64 writeString(const QString& string);
|
||||
|
||||
p_high_resolution_clock::time_point getFirstPacketReceiveTime() const;
|
||||
|
||||
|
||||
protected:
|
||||
PacketList(PacketType packetType, QByteArray extendedHeader = QByteArray(), bool isReliable = false, bool isOrdered = false);
|
||||
|
|
|
@ -334,6 +334,7 @@ void Socket::readPendingDatagrams() {
|
|||
if (system_clock::now() > abortTime) {
|
||||
// We've been running for too long, stop processing packets for now
|
||||
// Once we've processed the event queue, we'll come back to packet processing
|
||||
qCDebug(networking) << "Socket::readPendingDatagrams() running too long, aborting to process event queue";
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,15 +214,26 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
|
|||
_entitiesToRemoveFromPhysics.clear();
|
||||
_entitiesToAddToPhysics.clear();
|
||||
_incomingChanges.clear();
|
||||
_entitiesToDeleteLater.clear();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void PhysicalEntitySimulation::prepareEntityForDelete(EntityItemPointer entity) {
|
||||
// this can be called on any thread
|
||||
assert(entity);
|
||||
assert(entity->isDead());
|
||||
QMutexLocker lock(&_mutex);
|
||||
entity->clearActions(getThisPointer());
|
||||
removeEntityInternal(entity);
|
||||
_entitiesToDeleteLater.push_back(entity);
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::removeDeadEntities() {
|
||||
// only ever call this on the main thread
|
||||
QMutexLocker lock(&_mutex);
|
||||
for (auto& entity : _entitiesToDeleteLater) {
|
||||
entity->clearActions(getThisPointer());
|
||||
removeEntityInternal(entity);
|
||||
}
|
||||
_entitiesToDeleteLater.clear();
|
||||
}
|
||||
// end EntitySimulation overrides
|
||||
|
||||
|
@ -449,6 +460,8 @@ void PhysicalEntitySimulation::buildPhysicsTransaction(PhysicsEngine::Transactio
|
|||
void PhysicalEntitySimulation::handleProcessedPhysicsTransaction(PhysicsEngine::Transaction& transaction) {
|
||||
// things on objectsToRemove are ready for delete
|
||||
for (auto object : transaction.objectsToRemove) {
|
||||
EntityMotionState* entityState = static_cast<EntityMotionState*>(object);
|
||||
removeOwnershipData(entityState);
|
||||
_physicalObjects.remove(object);
|
||||
delete object;
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ protected: // only called by EntitySimulation
|
|||
|
||||
public:
|
||||
virtual void prepareEntityForDelete(EntityItemPointer entity) override;
|
||||
void removeDeadEntities();
|
||||
|
||||
void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction);
|
||||
void handleProcessedPhysicsTransaction(PhysicsEngine::Transaction& transaction);
|
||||
|
@ -121,6 +122,7 @@ private:
|
|||
VectorOfEntityMotionStates _owned;
|
||||
VectorOfEntityMotionStates _bids;
|
||||
SetOfEntities _deadAvatarEntities;
|
||||
std::vector<EntityItemPointer> _entitiesToDeleteLater;
|
||||
workload::SpacePointer _space;
|
||||
uint64_t _nextBidExpiry;
|
||||
uint32_t _lastStepSendPackets { 0 };
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
set(TARGET_NAME platform)
|
||||
setup_hifi_library()
|
||||
|
||||
setup_hifi_library()
|
||||
link_hifi_libraries(shared)
|
||||
|
||||
GroupSources("src")
|
||||
target_json()
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
|
||||
#include "LinuxPlatform.h"
|
||||
#include "platformJsonKeys.h"
|
||||
#include <GPUIdent.h>
|
||||
#include <thread>
|
||||
using namespace platform;
|
||||
|
||||
static void getLCpuId( uint32_t* p, uint32_t ax )
|
||||
{
|
||||
|
||||
#if defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
|
||||
__asm __volatile
|
||||
( "movl %%ebx, %%esi\n\t"
|
||||
"cpuid\n\t"
|
||||
"xchgl %%ebx, %%esi"
|
||||
: "=a" (p[0]), "=S" (p[1]),
|
||||
"=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void LinuxInstance::enumerateCpu() {
|
||||
json cpu = {};
|
||||
|
||||
uint32_t cpuInfo[4]={0,0,0,0};
|
||||
char CPUBrandString[16];
|
||||
char CPUModelString[16];
|
||||
char CPUClockString[16];
|
||||
uint32_t nExIds;
|
||||
getLCpuId(cpuInfo, 0x80000000);
|
||||
nExIds = cpuInfo[0];
|
||||
|
||||
for (uint32_t i = 0x80000000; i <= nExIds; ++i) {
|
||||
getLCpuId(cpuInfo, i);
|
||||
// Interpret CPU brand string
|
||||
if (i == 0x80000002) {
|
||||
memcpy(CPUBrandString, cpuInfo, sizeof(cpuInfo));
|
||||
} else if (i == 0x80000003) {
|
||||
memcpy(CPUModelString, cpuInfo, sizeof(cpuInfo));
|
||||
} else if (i == 0x80000004) {
|
||||
memcpy(CPUClockString, cpuInfo, sizeof(cpuInfo));
|
||||
}
|
||||
}
|
||||
|
||||
cpu["cpuBrand"] = CPUBrandString;
|
||||
cpu["cpuModel"] = CPUModelString;
|
||||
cpu["cpuClockSpeed"] = CPUClockString;
|
||||
cpu["cpuNumCores"] = std::thread::hardware_concurrency();
|
||||
|
||||
_cpu.push_back(cpu);
|
||||
}
|
||||
|
||||
void LinuxInstance::enumerateGpu() {
|
||||
GPUIdent* ident = GPUIdent::getInstance();
|
||||
json gpu = {};
|
||||
gpu["gpuName"] = ident->getName().toUtf8().constData();
|
||||
gpu["gpuMemory"] = ident->getMemory();
|
||||
gpu["gpuDriver"] = ident->getDriver().toUtf8().constData();
|
||||
|
||||
_gpu.push_back(gpu);
|
||||
_display = ident->getOutput();
|
||||
}
|
||||
|
||||
void LinuxInstance::enumerateMemory() {
|
||||
json ram = {};
|
||||
ram["totalMemory"]="";
|
||||
|
||||
_memory.push_back(ram);
|
||||
}
|
||||
|
||||
void LinuxInstance::enumerateComputer(){
|
||||
//no implememntation at this time
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
|
||||
#include "MACOSPlatform.h"
|
||||
#include "platformJsonKeys.h"
|
||||
|
||||
#include <thread>
|
||||
#include <GPUIdent.h>
|
||||
#include <string>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <unistd.h>
|
||||
#include <cpuid.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
using namespace platform;
|
||||
|
||||
static void getCpuId( uint32_t* p, uint32_t ax )
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
__asm __volatile
|
||||
( "movl %%ebx, %%esi\n\t"
|
||||
"cpuid\n\t"
|
||||
"xchgl %%ebx, %%esi"
|
||||
: "=a" (p[0]), "=S" (p[1]),
|
||||
"=c" (p[2]), "=d" (p[3])
|
||||
: "0" (ax)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void MACOSInstance::enumerateCpu() {
|
||||
json cpu = {};
|
||||
uint32_t cpuInfo[4]={0,0,0,0};
|
||||
char CPUBrandString[16];
|
||||
char CPUModelString[16];
|
||||
char CPUClockString[16];
|
||||
uint32_t nExIds;
|
||||
getCpuId(cpuInfo, 0x80000000);
|
||||
nExIds = cpuInfo[0];
|
||||
|
||||
for (uint32_t i = 0x80000000; i <= nExIds; ++i) {
|
||||
getCpuId(cpuInfo, i);
|
||||
// Interpret CPU brand string
|
||||
if (i == 0x80000002) {
|
||||
memcpy(CPUBrandString, cpuInfo, sizeof(cpuInfo));
|
||||
} else if (i == 0x80000003) {
|
||||
memcpy(CPUModelString, cpuInfo, sizeof(cpuInfo));
|
||||
} else if (i == 0x80000004) {
|
||||
memcpy(CPUClockString, cpuInfo, sizeof(cpuInfo));
|
||||
}
|
||||
}
|
||||
|
||||
cpu["cpuBrand"] = CPUBrandString;
|
||||
cpu["cpuModel"] = CPUModelString;
|
||||
cpu["cpuClockSpeed"] = CPUClockString;
|
||||
cpu["cpuNumCores"] = std::thread::hardware_concurrency();
|
||||
|
||||
_cpu.push_back(cpu);
|
||||
}
|
||||
|
||||
void MACOSInstance::enumerateGpu() {
|
||||
GPUIdent* ident = GPUIdent::getInstance();
|
||||
json gpu = {};
|
||||
gpu["gpuName"] = ident->getName().toUtf8().constData();
|
||||
gpu["gpuMemory"] = ident->getMemory();
|
||||
gpu["gpuDriver"] = ident->getDriver().toUtf8().constData();
|
||||
|
||||
_gpu.push_back(gpu);
|
||||
_display = ident->getOutput();
|
||||
|
||||
}
|
||||
|
||||
void MACOSInstance::enumerateMemory() {
|
||||
json ram = {};
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
long pages = sysconf(_SC_PHYS_PAGES);
|
||||
long page_size = sysconf(_SC_PAGE_SIZE);
|
||||
ram["totalMemory"] = pages * page_size;;
|
||||
#endif
|
||||
_memory.push_back(ram);
|
||||
}
|
||||
|
||||
void MACOSInstance::enumerateComputer(){
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
//get system name
|
||||
size_t len=0;
|
||||
sysctlbyname("hw.model",NULL, &len, NULL, 0);
|
||||
char* model = (char *) malloc(sizeof(char)*len+1);
|
||||
sysctlbyname("hw.model", model, &len, NULL,0);
|
||||
|
||||
_computer["computerModel"]=std::string(model);
|
||||
|
||||
free(model);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
|
||||
#include "WINPlatform.h"
|
||||
#include "platformJsonKeys.h"
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
#include <intrin.h>
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#include <thread>
|
||||
#include <GPUIdent.h>
|
||||
#include <string>
|
||||
|
||||
|
||||
using namespace platform;
|
||||
|
||||
void WINInstance::enumerateCpu() {
|
||||
json cpu = {};
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
int CPUInfo[4] = { -1 };
|
||||
unsigned nExIds;
|
||||
unsigned int i = 0;
|
||||
char CPUBrandString[16];
|
||||
char CPUModelString[16];
|
||||
char CPUClockString[16];
|
||||
// Get the information associated with each extended ID.
|
||||
__cpuid(CPUInfo, 0x80000000);
|
||||
nExIds = CPUInfo[0];
|
||||
|
||||
for (i = 0x80000000; i <= nExIds; ++i) {
|
||||
__cpuid(CPUInfo, i);
|
||||
// Interpret CPU brand string
|
||||
if (i == 0x80000002) {
|
||||
memcpy(CPUBrandString, CPUInfo, sizeof(CPUInfo));
|
||||
} else if (i == 0x80000003) {
|
||||
memcpy(CPUModelString, CPUInfo, sizeof(CPUInfo));
|
||||
} else if (i == 0x80000004) {
|
||||
memcpy(CPUClockString, CPUInfo, sizeof(CPUInfo));
|
||||
}
|
||||
}
|
||||
|
||||
cpu["cpuBrand"] = CPUBrandString;
|
||||
cpu["cpuModel"] = CPUModelString;
|
||||
cpu["cpuClockSpeed"] = CPUClockString;
|
||||
cpu["cpuNumCores"] = std::thread::hardware_concurrency();
|
||||
#endif
|
||||
|
||||
_cpu.push_back(cpu);
|
||||
}
|
||||
|
||||
void WINInstance::enumerateGpu() {
|
||||
|
||||
GPUIdent* ident = GPUIdent::getInstance();
|
||||
|
||||
json gpu = {};
|
||||
gpu["gpuName"] = ident->getName().toUtf8().constData();
|
||||
gpu["gpuMemory"] = ident->getMemory();
|
||||
gpu["gpuDriver"] = ident->getDriver().toUtf8().constData();
|
||||
|
||||
_gpu.push_back(gpu);
|
||||
_display = ident->getOutput();
|
||||
}
|
||||
|
||||
void WINInstance::enumerateMemory() {
|
||||
json ram = {};
|
||||
|
||||
#ifdef Q_OS_WINDOWS
|
||||
MEMORYSTATUSEX statex;
|
||||
statex.dwLength = sizeof(statex);
|
||||
GlobalMemoryStatusEx(&statex);
|
||||
int totalRam = statex.ullTotalPhys / 1024 / 1024;
|
||||
ram["totalMemory"] = totalRam;
|
||||
#endif
|
||||
_memory.push_back(ram);
|
||||
}
|
||||
|
||||
void WINInstance::enumerateComputer(){
|
||||
//no implememntation at this time
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include "WINPlatform.h"
|
||||
#elif defined(Q_OS_MAC)
|
||||
#include "MACOSPlatform.h"
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
#include "AndroidPlatform.h"
|
||||
#elif defined(Q_OS_LINUX)
|
||||
#include "LinuxPlatform.h"
|
||||
#endif
|
||||
|
||||
using namespace platform;
|
||||
|
||||
Instance *_instance;
|
||||
|
||||
void platform::create() {
|
||||
#if defined(Q_OS_WIN)
|
||||
_instance =new WINInstance();
|
||||
#elif defined(Q_OS_MAC)
|
||||
_instance = new MACOSInstance();
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
_instance= new AndroidInstance();
|
||||
#elif defined(Q_OS_LINUX)
|
||||
_instance= new LinuxInstance();
|
||||
#endif
|
||||
}
|
||||
|
||||
void platform::destroy() {
|
||||
if(_instance)
|
||||
delete _instance;
|
||||
}
|
||||
|
||||
bool platform::enumeratePlatform() {
|
||||
return _instance->enumeratePlatform();
|
||||
}
|
||||
|
||||
int platform::getNumCPU() {
|
||||
return _instance->getNumCPU();
|
||||
}
|
||||
|
||||
json platform::getCPU(int index) {
|
||||
return _instance->getCPU(index);
|
||||
}
|
||||
|
||||
int platform::getNumGPU() {
|
||||
return _instance->getNumGPU();
|
||||
}
|
||||
|
||||
json platform::getGPU(int index) {
|
||||
return _instance->getGPU(index);
|
||||
}
|
||||
|
||||
int platform::getNumDisplay() {
|
||||
return _instance->getNumDisplay();
|
||||
}
|
||||
|
||||
json platform::getDisplay(int index) {
|
||||
return _instance->getDisplay(index);
|
||||
}
|
||||
|
||||
int platform::getNumMemory() {
|
||||
return _instance->getNumMemory();
|
||||
}
|
||||
|
||||
json platform::getMemory(int index) {
|
||||
return _instance->getMemory(index);
|
||||
}
|
||||
|
||||
json platform::getComputer(){
|
||||
return _instance->getComputer();
|
||||
}
|
|
@ -19,20 +19,20 @@ void create();
|
|||
void destroy();
|
||||
bool enumeratePlatform();
|
||||
|
||||
int getNumCPU();
|
||||
int getNumCPUs();
|
||||
json getCPU(int index);
|
||||
|
||||
int getNumGPU();
|
||||
int getNumGPUs();
|
||||
json getGPU(int index);
|
||||
|
||||
int getNumDisplay();
|
||||
int getNumDisplays();
|
||||
json getDisplay(int index);
|
||||
|
||||
int getNumMemory();
|
||||
int getNumMemories();
|
||||
json getMemory(int index);
|
||||
|
||||
json getComputer();
|
||||
|
||||
|
||||
} // namespace platform
|
||||
|
||||
#endif // hifi_platform_h
|
57
libraries/platform/src/platform/PlatformKeys.h
Normal file
57
libraries/platform/src/platform/PlatformKeys.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
#ifndef hifi_platform_PlatformKeys_h
|
||||
#define hifi_platform_PlatformKeys_h
|
||||
|
||||
namespace platform { namespace keys{
|
||||
namespace cpu {
|
||||
extern const char* vendor;
|
||||
extern const char* vendor_Intel;
|
||||
extern const char* vendor_AMD;
|
||||
|
||||
extern const char* model;
|
||||
extern const char* clockSpeed;
|
||||
extern const char* numCores;
|
||||
}
|
||||
namespace gpu {
|
||||
extern const char* vendor;
|
||||
extern const char* vendor_NVIDIA;
|
||||
extern const char* vendor_AMD;
|
||||
extern const char* vendor_Intel;
|
||||
|
||||
extern const char* model;
|
||||
extern const char* videoMemory;
|
||||
extern const char* driver;
|
||||
}
|
||||
namespace display {
|
||||
extern const char* description;
|
||||
extern const char* name;
|
||||
extern const char* coordsLeft;
|
||||
extern const char* coordsRight;
|
||||
extern const char* coordsTop;
|
||||
extern const char* coordsBottom;
|
||||
}
|
||||
extern const char* memTotal;
|
||||
|
||||
namespace computer {
|
||||
extern const char* OS;
|
||||
extern const char* OS_WINDOWS;
|
||||
extern const char* OS_MACOS;
|
||||
extern const char* OS_LINUX;
|
||||
extern const char* OS_ANDROID;
|
||||
|
||||
extern const char* vendor;
|
||||
extern const char* vendor_Apple;
|
||||
|
||||
extern const char* model;
|
||||
|
||||
extern const char* profileTier;
|
||||
}
|
||||
} } // namespace plaform::keys
|
||||
|
||||
#endif
|
127
libraries/platform/src/platform/Profiler.cpp
Normal file
127
libraries/platform/src/platform/Profiler.cpp
Normal file
|
@ -0,0 +1,127 @@
|
|||
//
|
||||
// Profiler.cpp
|
||||
// libraries/platform/src/platform
|
||||
//
|
||||
// Created by Sam Gateau on 5/22/2019.
|
||||
// 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
|
||||
//
|
||||
#include "Profiler.h"
|
||||
|
||||
#include "Platform.h"
|
||||
#include "PlatformKeys.h"
|
||||
|
||||
using namespace platform;
|
||||
|
||||
const std::array<const char*, Profiler::Tier::NumTiers> Profiler::TierNames = {{ "UNKNOWN", "LOW", "MID", "HIGH" }};
|
||||
|
||||
|
||||
bool filterOnComputer(const platform::json& computer, Profiler::Tier& tier);
|
||||
bool filterOnComputerMACOS(const platform::json& computer, Profiler::Tier& tier);
|
||||
bool filterOnProcessors(const platform::json& computer, const platform::json& cpu, const platform::json& gpu, Profiler::Tier& tier);
|
||||
|
||||
Profiler::Tier Profiler::profilePlatform() {
|
||||
auto platformTier = Profiler::Tier::UNKNOWN; // unknown tier yet
|
||||
|
||||
// first filter on the computer info and catch known models
|
||||
auto computerInfo = platform::getComputer();
|
||||
if (filterOnComputer(computerInfo, platformTier)) {
|
||||
return platformTier;
|
||||
}
|
||||
|
||||
// Not filtered yet, let s try to make sense of the cpu and gpu info
|
||||
auto cpuInfo = platform::getCPU(0);
|
||||
auto gpuInfo = platform::getGPU(0);
|
||||
if (filterOnProcessors(computerInfo, cpuInfo, gpuInfo, platformTier)) {
|
||||
return platformTier;
|
||||
}
|
||||
|
||||
// Default answer is
|
||||
return Profiler::Tier::LOW;
|
||||
}
|
||||
|
||||
// tier filter on computer info
|
||||
bool filterOnComputer(const platform::json& computer, Profiler::Tier& tier) {
|
||||
if (computer.count(keys::computer::OS)) {
|
||||
const auto os = computer[keys::computer::OS].get<std::string>();
|
||||
if (os.compare(keys::computer::OS_MACOS) == 0) {
|
||||
return filterOnComputerMACOS(computer, tier);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// tier filter on computer MACOS
|
||||
bool filterOnComputerMACOS(const platform::json& computer, Profiler::Tier& tier) {
|
||||
|
||||
// it s a macos computer, probably can tell from the model name:
|
||||
if (computer.count(keys::computer::model)) {
|
||||
const auto model = computer[keys::computer::model].get<std::string>();
|
||||
if (model.find("MacBookAir") != std::string::npos) {
|
||||
tier = Profiler::Tier::LOW;
|
||||
return true;
|
||||
} else if (model.find("MacBookPro") != std::string::npos) {
|
||||
tier = Profiler::Tier::MID;
|
||||
return true;
|
||||
} else if (model.find("MacBook") != std::string::npos) {
|
||||
tier = Profiler::Tier::LOW;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool filterOnProcessors(const platform::json& computer, const platform::json& cpu, const platform::json& gpu, Profiler::Tier& tier) {
|
||||
// first filter on the number of cores, <= 4 means LOW
|
||||
int numCores = 0;
|
||||
std::string cpuVendor;
|
||||
if (cpu.count(keys::cpu::numCores)) {
|
||||
numCores = cpu[keys::cpu::numCores].get<int>();
|
||||
if (numCores <= 4) {
|
||||
tier = Profiler::Tier::LOW;
|
||||
return true;
|
||||
}
|
||||
|
||||
cpuVendor = cpu[keys::cpu::vendor].get<std::string>();
|
||||
}
|
||||
|
||||
// enough cores to be mid or high
|
||||
// let s look at the gpu
|
||||
if (gpu.count(keys::gpu::vendor)) {
|
||||
std::string gpuVendor = gpu[keys::gpu::vendor].get<std::string>();
|
||||
std::string gpuModel = gpu[keys::gpu::model].get<std::string>();
|
||||
|
||||
// intel integrated graphics
|
||||
if (gpuVendor.find(keys::gpu::vendor_Intel) != std::string::npos) {
|
||||
// go mid because GPU
|
||||
tier = Profiler::Tier::MID;
|
||||
return true;
|
||||
}
|
||||
// AMD gpu
|
||||
else if (gpuVendor.find(keys::gpu::vendor_AMD) != std::string::npos) {
|
||||
// TODO: Filter base on the model of AMD
|
||||
// that is their integrated graphics, go low!
|
||||
if (gpuModel.find("Vega 3") != std::string::npos) {
|
||||
tier = Profiler::Tier::LOW;
|
||||
return true;
|
||||
}
|
||||
|
||||
// go high because GPU
|
||||
tier = Profiler::Tier::HIGH;
|
||||
return true;
|
||||
}
|
||||
// NVIDIA gpu
|
||||
else if (gpuVendor.find(keys::gpu::vendor_NVIDIA) != std::string::npos) {
|
||||
// TODO: Filter base on the model of NV
|
||||
// go high because GPU
|
||||
tier = Profiler::Tier::HIGH;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Not able to profile
|
||||
return false;
|
||||
}
|
34
libraries/platform/src/platform/Profiler.h
Normal file
34
libraries/platform/src/platform/Profiler.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// Profiler.h
|
||||
// libraries/platform/src/platform
|
||||
//
|
||||
// Created by Sam Gateau on 5/22/2019.
|
||||
// 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
|
||||
//
|
||||
#ifndef hifi_platform_Profiler_h
|
||||
#define hifi_platform_Profiler_h
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace platform {
|
||||
|
||||
class Profiler {
|
||||
public:
|
||||
enum Tier {
|
||||
UNKNOWN = 0,
|
||||
LOW,
|
||||
MID,
|
||||
HIGH,
|
||||
|
||||
NumTiers, // not a valid Tier
|
||||
};
|
||||
static const std::array<const char*, Tier::NumTiers> TierNames;
|
||||
|
||||
static Tier profilePlatform();
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
|
@ -7,38 +7,41 @@
|
|||
//
|
||||
|
||||
#include "AndroidPlatform.h"
|
||||
#include "platformJsonKeys.h"
|
||||
#include "../PlatformKeys.h"
|
||||
#include <GPUIdent.h>
|
||||
|
||||
using namespace platform;
|
||||
|
||||
void AndroidInstance::enumerateCpu() {
|
||||
json cpu;
|
||||
cpu["cpuBrand"] = "";
|
||||
cpu["cpuModel"] = "";
|
||||
cpu["cpuClockSpeed"] = "";
|
||||
cpu["cpuNumCores"] = "";
|
||||
cpu[keys::cpu::vendor] = "";
|
||||
cpu[keys::cpu::model] = "";
|
||||
cpu[keys::cpu::clockSpeed] = "";
|
||||
cpu[keys::cpu::numCores] = 0;
|
||||
_cpu.push_back(cpu);
|
||||
}
|
||||
|
||||
void AndroidInstance::enumerateGpu() {
|
||||
GPUIdent* ident = GPUIdent::getInstance();
|
||||
json gpu = {};
|
||||
gpu["gpuName"] = ident->getName().toUtf8().constData();
|
||||
gpu["gpuMemory"] = ident->getMemory();
|
||||
gpu["gpuDriver"] = ident->getDriver().toUtf8().constData();
|
||||
|
||||
gpu[keys::gpu::vendor] = ident->getName().toUtf8().constData();
|
||||
gpu[keys::gpu::model] = ident->getName().toUtf8().constData();
|
||||
gpu[keys::gpu::videoMemory] = ident->getMemory();
|
||||
gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData();
|
||||
|
||||
_gpu.push_back(gpu);
|
||||
_display = ident->getOutput();
|
||||
}
|
||||
|
||||
void AndroidInstance::enumerateMemory() {
|
||||
json ram = {};
|
||||
ram["totalMemory"]="";
|
||||
ram[keys::memTotal]=0;
|
||||
_memory.push_back(ram);
|
||||
}
|
||||
|
||||
void AndroidInstance::enumerateComputer(){
|
||||
//no implememntation at this time
|
||||
_computer[keys::computer::OS] = keys::computer::OS_ANDROID;
|
||||
_computer[keys::computer::vendor] = "";
|
||||
_computer[keys::computer::model] = "";
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef hifi_AndroidPlatform_h
|
||||
#define hifi_AndroidPlatform_h
|
||||
|
||||
#include "platformInstance.h"
|
||||
#include "PlatformInstance.h"
|
||||
|
||||
namespace platform {
|
||||
class AndroidInstance : public Instance {
|
54
libraries/platform/src/platform/backend/LinuxPlatform.cpp
Normal file
54
libraries/platform/src/platform/backend/LinuxPlatform.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
|
||||
#include "LinuxPlatform.h"
|
||||
#include "../PlatformKeys.h"
|
||||
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <CPUIdent.h>
|
||||
#include <GPUIdent.h>
|
||||
|
||||
using namespace platform;
|
||||
|
||||
void LinuxInstance::enumerateCpu() {
|
||||
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);
|
||||
}
|
||||
|
||||
void LinuxInstance::enumerateGpu() {
|
||||
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::videoMemory] = ident->getMemory();
|
||||
gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData();
|
||||
|
||||
_gpu.push_back(gpu);
|
||||
_display = ident->getOutput();
|
||||
}
|
||||
|
||||
void LinuxInstance::enumerateMemory() {
|
||||
json ram = {};
|
||||
ram[keys::memTotal]=0;
|
||||
|
||||
_memory.push_back(ram);
|
||||
}
|
||||
|
||||
void LinuxInstance::enumerateComputer(){
|
||||
|
||||
_computer[keys::computer::OS] = keys::computer::OS_LINUX;
|
||||
_computer[keys::computer::vendor] = "";
|
||||
_computer[keys::computer::model] = "";
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef hifi_LinuxPlatform_h
|
||||
#define hifi_LinuxPlatform_h
|
||||
|
||||
#include "platformInstance.h"
|
||||
#include "PlatformInstance.h"
|
||||
|
||||
namespace platform {
|
||||
class LinuxInstance : public Instance {
|
77
libraries/platform/src/platform/backend/MACOSPlatform.cpp
Normal file
77
libraries/platform/src/platform/backend/MACOSPlatform.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
|
||||
#include "MACOSPlatform.h"
|
||||
#include "../PlatformKeys.h"
|
||||
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <CPUIdent.h>
|
||||
#include <GPUIdent.h>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <unistd.h>
|
||||
#include <cpuid.h>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
using namespace platform;
|
||||
|
||||
void MACOSInstance::enumerateCpu() {
|
||||
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);
|
||||
}
|
||||
|
||||
void MACOSInstance::enumerateGpu() {
|
||||
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::videoMemory] = ident->getMemory();
|
||||
gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData();
|
||||
|
||||
_gpu.push_back(gpu);
|
||||
_display = ident->getOutput();
|
||||
|
||||
}
|
||||
|
||||
void MACOSInstance::enumerateMemory() {
|
||||
json ram = {};
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
long pages = sysconf(_SC_PHYS_PAGES);
|
||||
long page_size = sysconf(_SC_PAGE_SIZE);
|
||||
ram[keys::memTotal] = pages * page_size;
|
||||
#endif
|
||||
_memory.push_back(ram);
|
||||
}
|
||||
|
||||
void MACOSInstance::enumerateComputer(){
|
||||
_computer[keys::computer::OS] = keys::computer::OS_MACOS;
|
||||
_computer[keys::computer::vendor] = keys::computer::vendor_Apple;
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
|
||||
//get system name
|
||||
size_t len=0;
|
||||
sysctlbyname("hw.model",NULL, &len, NULL, 0);
|
||||
char* model = (char *) malloc(sizeof(char)*len+1);
|
||||
sysctlbyname("hw.model", model, &len, NULL,0);
|
||||
|
||||
_computer[keys::computer::model]=std::string(model);
|
||||
|
||||
free(model);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef hifi_MACOSPlatform_h
|
||||
#define hifi_MACOSPlatform_h
|
||||
|
||||
#include "platformInstance.h"
|
||||
#include "PlatformInstance.h"
|
||||
|
||||
namespace platform {
|
||||
class MACOSInstance : public Instance {
|
130
libraries/platform/src/platform/backend/Platform.cpp
Normal file
130
libraries/platform/src/platform/backend/Platform.cpp
Normal file
|
@ -0,0 +1,130 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
|
||||
|
||||
#include "../Platform.h"
|
||||
#include "../PlatformKeys.h"
|
||||
|
||||
namespace platform { namespace keys {
|
||||
namespace cpu {
|
||||
const char* vendor = "vendor";
|
||||
const char* vendor_Intel = "Intel";
|
||||
const char* vendor_AMD = "AMD";
|
||||
|
||||
const char* model = "model";
|
||||
const char* clockSpeed = "clockSpeed";
|
||||
const char* numCores = "numCores";
|
||||
}
|
||||
namespace gpu {
|
||||
const char* vendor = "vendor";
|
||||
const char* vendor_NVIDIA = "NVIDIA";
|
||||
const char* vendor_AMD = "AMD";
|
||||
const char* vendor_Intel = "Intel";
|
||||
|
||||
const char* model = "model";
|
||||
const char* videoMemory = "videoMemory";
|
||||
const char* driver = "driver";
|
||||
}
|
||||
namespace display {
|
||||
const char* description = "description";
|
||||
const char* name = "deviceName";
|
||||
const char* coordsLeft = "coordinatesleft";
|
||||
const char* coordsRight = "coordinatesright";
|
||||
const char* coordsTop = "coordinatestop";
|
||||
const char* coordsBottom = "coordinatesbottom";
|
||||
}
|
||||
const char* memTotal = "memTotal";
|
||||
|
||||
namespace computer {
|
||||
const char* OS = "OS";
|
||||
const char* OS_WINDOWS = "WINDOWS";
|
||||
const char* OS_MACOS = "MACOS";
|
||||
const char* OS_LINUX = "LINUX";
|
||||
const char* OS_ANDROID = "ANDROID";
|
||||
|
||||
const char* vendor = "vendor";
|
||||
const char* vendor_Apple = "Apple";
|
||||
|
||||
const char* model = "model";
|
||||
|
||||
const char* profileTier = "profileTier";
|
||||
}
|
||||
}}
|
||||
|
||||
#include <qglobal.h>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include "WINPlatform.h"
|
||||
#elif defined(Q_OS_MAC)
|
||||
#include "MACOSPlatform.h"
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
#include "AndroidPlatform.h"
|
||||
#elif defined(Q_OS_LINUX)
|
||||
#include "LinuxPlatform.h"
|
||||
#endif
|
||||
|
||||
using namespace platform;
|
||||
|
||||
Instance *_instance;
|
||||
|
||||
void platform::create() {
|
||||
#if defined(Q_OS_WIN)
|
||||
_instance =new WINInstance();
|
||||
#elif defined(Q_OS_MAC)
|
||||
_instance = new MACOSInstance();
|
||||
#elif defined(Q_OS_ANDROID)
|
||||
_instance= new AndroidInstance();
|
||||
#elif defined(Q_OS_LINUX)
|
||||
_instance= new LinuxInstance();
|
||||
#endif
|
||||
}
|
||||
|
||||
void platform::destroy() {
|
||||
if(_instance)
|
||||
delete _instance;
|
||||
}
|
||||
|
||||
bool platform::enumeratePlatform() {
|
||||
return _instance->enumeratePlatform();
|
||||
}
|
||||
|
||||
int platform::getNumCPUs() {
|
||||
return _instance->getNumCPUs();
|
||||
}
|
||||
|
||||
json platform::getCPU(int index) {
|
||||
return _instance->getCPU(index);
|
||||
}
|
||||
|
||||
int platform::getNumGPUs() {
|
||||
return _instance->getNumGPUs();
|
||||
}
|
||||
|
||||
json platform::getGPU(int index) {
|
||||
return _instance->getGPU(index);
|
||||
}
|
||||
|
||||
int platform::getNumDisplays() {
|
||||
return _instance->getNumDisplays();
|
||||
}
|
||||
|
||||
json platform::getDisplay(int index) {
|
||||
return _instance->getDisplay(index);
|
||||
}
|
||||
|
||||
int platform::getNumMemories() {
|
||||
return _instance->getNumMemories();
|
||||
}
|
||||
|
||||
json platform::getMemory(int index) {
|
||||
return _instance->getMemory(index);
|
||||
}
|
||||
|
||||
json platform::getComputer(){
|
||||
return _instance->getComputer();
|
||||
}
|
|
@ -7,8 +7,10 @@
|
|||
//
|
||||
|
||||
|
||||
#include "platformInstance.h"
|
||||
#include <QtGlobal>
|
||||
#include "PlatformInstance.h"
|
||||
|
||||
#include "../PlatformKeys.h"
|
||||
#include "../Profiler.h"
|
||||
|
||||
using namespace platform;
|
||||
|
||||
|
@ -17,6 +19,10 @@ bool Instance::enumeratePlatform() {
|
|||
enumerateCpu();
|
||||
enumerateGpu();
|
||||
enumerateMemory();
|
||||
|
||||
// And profile the platform and put the tier in "computer"
|
||||
_computer[keys::computer::profileTier] = Profiler::TierNames[Profiler::profilePlatform()];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -72,3 +78,44 @@ Instance::~Instance() {
|
|||
_display.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
json Instance::listAllKeys() {
|
||||
json allKeys;
|
||||
allKeys.array({{
|
||||
keys::cpu::vendor,
|
||||
keys::cpu::vendor_Intel,
|
||||
keys::cpu::vendor_AMD,
|
||||
keys::cpu::model,
|
||||
keys::cpu::clockSpeed,
|
||||
keys::cpu::numCores,
|
||||
|
||||
keys::gpu::vendor,
|
||||
keys::gpu::vendor_NVIDIA,
|
||||
keys::gpu::vendor_AMD,
|
||||
keys::gpu::vendor_Intel,
|
||||
keys::gpu::model,
|
||||
keys::gpu::videoMemory,
|
||||
keys::gpu::driver,
|
||||
|
||||
keys::display::description,
|
||||
keys::display::name,
|
||||
keys::display::coordsLeft,
|
||||
keys::display::coordsRight,
|
||||
keys::display::coordsTop,
|
||||
keys::display::coordsBottom,
|
||||
|
||||
keys::memTotal,
|
||||
|
||||
keys::computer::OS,
|
||||
keys::computer::OS_WINDOWS,
|
||||
keys::computer::OS_MACOS,
|
||||
keys::computer::OS_LINUX,
|
||||
keys::computer::OS_ANDROID,
|
||||
keys::computer::vendor,
|
||||
keys::computer::vendor_Apple,
|
||||
keys::computer::model,
|
||||
keys::computer::profileTier
|
||||
}});
|
||||
return allKeys;
|
||||
}
|
|
@ -19,16 +19,16 @@ class Instance {
|
|||
public:
|
||||
bool virtual enumeratePlatform();
|
||||
|
||||
int getNumCPU() { return (int)_cpu.size(); }
|
||||
int getNumCPUs() { return (int)_cpu.size(); }
|
||||
json getCPU(int index);
|
||||
|
||||
int getNumGPU() { return (int)_gpu.size(); }
|
||||
int getNumGPUs() { return (int)_gpu.size(); }
|
||||
json getGPU(int index);
|
||||
|
||||
int getNumMemory() { return (int)_memory.size(); }
|
||||
int getNumMemories() { return (int)_memory.size(); }
|
||||
json getMemory(int index);
|
||||
|
||||
int getNumDisplay() { return (int)_display.size(); }
|
||||
int getNumDisplays() { return (int)_display.size(); }
|
||||
json getDisplay(int index);
|
||||
|
||||
|
||||
|
@ -41,6 +41,8 @@ public:
|
|||
|
||||
virtual ~Instance();
|
||||
|
||||
static json listAllKeys();
|
||||
|
||||
protected:
|
||||
std::vector<json> _cpu;
|
||||
std::vector<json> _memory;
|
66
libraries/platform/src/platform/backend/WINPlatform.cpp
Normal file
66
libraries/platform/src/platform/backend/WINPlatform.cpp
Normal file
|
@ -0,0 +1,66 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
|
||||
#include "WINPlatform.h"
|
||||
#include "../PlatformKeys.h"
|
||||
|
||||
#include <thread>
|
||||
#include <string>
|
||||
#include <CPUIdent.h>
|
||||
#include <GPUIdent.h>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
using namespace platform;
|
||||
|
||||
void WINInstance::enumerateCpu() {
|
||||
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);
|
||||
}
|
||||
|
||||
void WINInstance::enumerateGpu() {
|
||||
|
||||
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::videoMemory] = ident->getMemory();
|
||||
gpu[keys::gpu::driver] = ident->getDriver().toUtf8().constData();
|
||||
|
||||
_gpu.push_back(gpu);
|
||||
_display = ident->getOutput();
|
||||
}
|
||||
|
||||
void WINInstance::enumerateMemory() {
|
||||
json ram = {};
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
MEMORYSTATUSEX statex;
|
||||
statex.dwLength = sizeof(statex);
|
||||
GlobalMemoryStatusEx(&statex);
|
||||
int totalRam = statex.ullTotalPhys / 1024 / 1024;
|
||||
ram[platform::keys::memTotal] = totalRam;
|
||||
#endif
|
||||
_memory.push_back(ram);
|
||||
}
|
||||
|
||||
void WINInstance::enumerateComputer(){
|
||||
_computer[keys::computer::OS] = keys::computer::OS_WINDOWS;
|
||||
_computer[keys::computer::vendor] = "";
|
||||
_computer[keys::computer::model] = "";
|
||||
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
#ifndef hifi_WinPlatform_h
|
||||
#define hifi_WinPlatform_h
|
||||
|
||||
#include "platformInstance.h"
|
||||
#include "PlatformInstance.h"
|
||||
|
||||
namespace platform {
|
||||
class WINInstance : public Instance {
|
|
@ -1,37 +0,0 @@
|
|||
//
|
||||
// Created by Amer Cerkic 05/02/2019
|
||||
// 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
|
||||
//
|
||||
#pragma once
|
||||
#ifndef hifi_PlatformJsonKeys_h
|
||||
#define hifi_PlatformJsonKeys_h
|
||||
|
||||
namespace platform {
|
||||
namespace jsonKeys{
|
||||
#if 0
|
||||
static const char* cpuBrand { "cpuBrand"};
|
||||
static const char* cpuModel {"cpuModel"};
|
||||
static const char* cpuClockSpeed {"clockSpeed"};
|
||||
static const char* cpuNumCores { "numCores"};
|
||||
static const char* gpuName {"GpuName"};
|
||||
static const char* gpuMemory {"gpuMemory"};
|
||||
static const char* gpuDriver {"gpuDriver"};
|
||||
static const char* totalMemory {"totalMem"};
|
||||
static const char* displayDescription { "description"};
|
||||
static const char* displayName {"deviceName"};
|
||||
static const char* displayCoordsLeft {"coordinatesleft"};
|
||||
static const char* displayCoordsRight { "coordinatesright"};
|
||||
static const char* displayCoordsTop { "coordinatestop"};
|
||||
static const char* displayCoordsBottom { "coordinatesbottom"};
|
||||
static const char* computerModel { "computerModel"};
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
} // namespace plaform::jsonKeys
|
||||
|
||||
#endif
|
|
@ -42,5 +42,5 @@ void main(void) {
|
|||
color = max(color, vec3(0));
|
||||
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
|
||||
color = pow(color, vec3(2.2));
|
||||
_fragColor = vec4(color, 0.0);
|
||||
_fragColor = vec4(color, 1.0);
|
||||
}
|
||||
|
|
|
@ -648,6 +648,7 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) {
|
|||
|
||||
if (!_defaultLight || !_defaultBackground) {
|
||||
auto defaultSkyboxURL = PathUtils::resourcesUrl() + "images/Default-Sky-9-cubemap/Default-Sky-9-cubemap.texmeta.json";
|
||||
auto defaultAmbientURL = PathUtils::resourcesUrl() + "images/Default-Sky-9-cubemap/Default-Sky-9-cubemap-ambient.texmeta.json";
|
||||
|
||||
if (!_defaultSkyboxNetworkTexture) {
|
||||
PROFILE_RANGE(render, "Process Default Skybox");
|
||||
|
@ -658,7 +659,7 @@ void DefaultLightingSetup::run(const RenderContextPointer& renderContext) {
|
|||
if (!_defaultAmbientNetworkTexture) {
|
||||
PROFILE_RANGE(render, "Process Default Ambient map");
|
||||
_defaultAmbientNetworkTexture = DependencyManager::get<TextureCache>()->getTexture(
|
||||
defaultSkyboxURL, image::TextureUsage::AMBIENT_TEXTURE);
|
||||
defaultAmbientURL, image::TextureUsage::AMBIENT_TEXTURE);
|
||||
}
|
||||
|
||||
if (_defaultSkyboxNetworkTexture && _defaultSkyboxNetworkTexture->isLoaded() && _defaultSkyboxNetworkTexture->getGPUTexture()) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue