mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-23 11:04:02 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into sessionDisplayNames
This commit is contained in:
commit
3adc78fecc
86 changed files with 2640 additions and 760 deletions
|
@ -37,6 +37,7 @@
|
||||||
#include "AssignmentClient.h"
|
#include "AssignmentClient.h"
|
||||||
#include "AssignmentClientLogging.h"
|
#include "AssignmentClientLogging.h"
|
||||||
#include "avatars/ScriptableAvatar.h"
|
#include "avatars/ScriptableAvatar.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
const QString ASSIGNMENT_CLIENT_TARGET_NAME = "assignment-client";
|
const QString ASSIGNMENT_CLIENT_TARGET_NAME = "assignment-client";
|
||||||
const long long ASSIGNMENT_REQUEST_INTERVAL_MSECS = 1 * 1000;
|
const long long ASSIGNMENT_REQUEST_INTERVAL_MSECS = 1 * 1000;
|
||||||
|
@ -48,6 +49,7 @@ AssignmentClient::AssignmentClient(Assignment::Type requestAssignmentType, QStri
|
||||||
{
|
{
|
||||||
LogUtils::init();
|
LogUtils::init();
|
||||||
|
|
||||||
|
DependencyManager::set<tracing::Tracer>();
|
||||||
DependencyManager::set<AccountManager>();
|
DependencyManager::set<AccountManager>();
|
||||||
|
|
||||||
auto scriptableAvatar = DependencyManager::set<ScriptableAvatar>();
|
auto scriptableAvatar = DependencyManager::set<ScriptableAvatar>();
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
|
|
||||||
#include "DomainServerNodeData.h"
|
#include "DomainServerNodeData.h"
|
||||||
#include "NodeConnectionData.h"
|
#include "NodeConnectionData.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
int const DomainServer::EXIT_CODE_REBOOT = 234923;
|
int const DomainServer::EXIT_CODE_REBOOT = 234923;
|
||||||
|
|
||||||
|
@ -73,6 +74,8 @@ DomainServer::DomainServer(int argc, char* argv[]) :
|
||||||
{
|
{
|
||||||
parseCommandLine();
|
parseCommandLine();
|
||||||
|
|
||||||
|
DependencyManager::set<tracing::Tracer>();
|
||||||
|
|
||||||
LogUtils::init();
|
LogUtils::init();
|
||||||
Setting::init();
|
Setting::init();
|
||||||
|
|
||||||
|
|
36
interface/resources/qml/hifi/NameCard.qml
Normal file
36
interface/resources/qml/hifi/NameCard.qml
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
//
|
||||||
|
// NameCard.qml
|
||||||
|
// qml/hifi
|
||||||
|
//
|
||||||
|
// Created by Howard Stearns on 12/9/2016
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
import Hifi 1.0
|
||||||
|
import QtQuick 2.5
|
||||||
|
import "../styles-uit"
|
||||||
|
|
||||||
|
|
||||||
|
Column {
|
||||||
|
property string displayName: "";
|
||||||
|
property string userName: "";
|
||||||
|
property int displayTextHeight: 18;
|
||||||
|
property int usernameTextHeight: 12;
|
||||||
|
|
||||||
|
RalewaySemiBold {
|
||||||
|
text: parent.displayName;
|
||||||
|
size: parent.displayTextHeight;
|
||||||
|
elide: Text.ElideRight;
|
||||||
|
width: parent.width;
|
||||||
|
}
|
||||||
|
RalewayLight {
|
||||||
|
visible: parent.displayName;
|
||||||
|
text: parent.userName;
|
||||||
|
size: parent.usernameTextHeight;
|
||||||
|
elide: Text.ElideRight;
|
||||||
|
width: parent.width;
|
||||||
|
}
|
||||||
|
}
|
207
interface/resources/qml/hifi/Pal.qml
Normal file
207
interface/resources/qml/hifi/Pal.qml
Normal file
|
@ -0,0 +1,207 @@
|
||||||
|
//
|
||||||
|
// Pal.qml
|
||||||
|
// qml/hifi
|
||||||
|
//
|
||||||
|
// People Action List
|
||||||
|
//
|
||||||
|
// Created by Howard Stearns on 12/12/2016
|
||||||
|
// Copyright 2016 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
|
||||||
|
//
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
|
||||||
|
prototype:
|
||||||
|
- only show kick/mute when canKick
|
||||||
|
- margins everywhere
|
||||||
|
- column head centering
|
||||||
|
- column head font
|
||||||
|
- proper button .svg on toolbar
|
||||||
|
|
||||||
|
mvp:
|
||||||
|
- Show all participants, including ignored, and populate initial ignore/mute status.
|
||||||
|
- If name is elided, hover should scroll name left so the full name can be read.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.5
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: pal;
|
||||||
|
property int keepFromHorizontalScroll: 1;
|
||||||
|
width: parent.width - keepFromHorizontalScroll;
|
||||||
|
height: parent.height;
|
||||||
|
|
||||||
|
property int nameWidth: width/2;
|
||||||
|
property int actionWidth: nameWidth / (table.columnCount - 1);
|
||||||
|
property int rowHeight: 50;
|
||||||
|
property var userData: [];
|
||||||
|
property var myData: ({displayName: "", userName: ""}); // valid dummy until set
|
||||||
|
property bool iAmAdmin: false;
|
||||||
|
function findSessionIndex(sessionId, optionalData) { // no findIndex in .qml
|
||||||
|
var i, data = optionalData || userData, length = data.length;
|
||||||
|
for (var i = 0; i < length; i++) {
|
||||||
|
if (data[i].sessionId === sessionId) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
function fromScript(message) {
|
||||||
|
switch (message.method) {
|
||||||
|
case 'users':
|
||||||
|
var data = message.params;
|
||||||
|
var myIndex = findSessionIndex('', data);
|
||||||
|
iAmAdmin = Users.canKick;
|
||||||
|
myData = data[myIndex];
|
||||||
|
data.splice(myIndex, 1);
|
||||||
|
userData = data;
|
||||||
|
sortModel();
|
||||||
|
break;
|
||||||
|
case 'select':
|
||||||
|
var sessionId = message.params[0];
|
||||||
|
var selected = message.params[1];
|
||||||
|
var userIndex = findSessionIndex(sessionId);
|
||||||
|
if (selected) {
|
||||||
|
table.selection.clear(); // for now, no multi-select
|
||||||
|
table.selection.select(userIndex);
|
||||||
|
} else {
|
||||||
|
table.selection.deselect(userIndex);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
console.log('Unrecognized message:', JSON.stringify(message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ListModel {
|
||||||
|
id: userModel
|
||||||
|
}
|
||||||
|
function sortModel() {
|
||||||
|
var sortProperty = table.getColumn(table.sortIndicatorColumn).role;
|
||||||
|
var before = (table.sortIndicatorOrder === Qt.AscendingOrder) ? -1 : 1;
|
||||||
|
var after = -1 * before;
|
||||||
|
userData.sort(function (a, b) {
|
||||||
|
var aValue = a[sortProperty].toString().toLowerCase(), bValue = b[sortProperty].toString().toLowerCase();
|
||||||
|
switch (true) {
|
||||||
|
case (aValue < bValue): return before;
|
||||||
|
case (aValue > bValue): return after;
|
||||||
|
default: return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
table.selection.clear();
|
||||||
|
userModel.clear();
|
||||||
|
var userIndex = 0;
|
||||||
|
userData.forEach(function (datum) {
|
||||||
|
function init(property) {
|
||||||
|
if (datum[property] === undefined) {
|
||||||
|
datum[property] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
['ignore', 'spacer', 'mute', 'kick'].forEach(init);
|
||||||
|
datum.userIndex = userIndex++;
|
||||||
|
userModel.append(datum);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
signal sendToScript(var message);
|
||||||
|
function noticeSelection() {
|
||||||
|
var userIds = [];
|
||||||
|
table.selection.forEach(function (userIndex) {
|
||||||
|
userIds.push(userData[userIndex].sessionId);
|
||||||
|
});
|
||||||
|
pal.sendToScript({method: 'selected', params: userIds});
|
||||||
|
}
|
||||||
|
Connections {
|
||||||
|
target: table.selection
|
||||||
|
onSelectionChanged: pal.noticeSelection()
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
NameCard {
|
||||||
|
id: myCard;
|
||||||
|
width: nameWidth;
|
||||||
|
displayName: myData.displayName;
|
||||||
|
userName: myData.userName;
|
||||||
|
}
|
||||||
|
TableView {
|
||||||
|
id: table;
|
||||||
|
TableViewColumn {
|
||||||
|
role: "displayName";
|
||||||
|
title: "Name";
|
||||||
|
width: nameWidth
|
||||||
|
}
|
||||||
|
TableViewColumn {
|
||||||
|
role: "ignore";
|
||||||
|
title: "Ignore"
|
||||||
|
width: actionWidth
|
||||||
|
}
|
||||||
|
TableViewColumn {
|
||||||
|
title: "";
|
||||||
|
width: actionWidth
|
||||||
|
}
|
||||||
|
TableViewColumn {
|
||||||
|
visible: iAmAdmin;
|
||||||
|
role: "mute";
|
||||||
|
title: "Mute";
|
||||||
|
width: actionWidth
|
||||||
|
}
|
||||||
|
TableViewColumn {
|
||||||
|
visible: iAmAdmin;
|
||||||
|
role: "kick";
|
||||||
|
title: "Ban"
|
||||||
|
width: actionWidth
|
||||||
|
}
|
||||||
|
model: userModel;
|
||||||
|
rowDelegate: Rectangle { // The only way I know to specify a row height.
|
||||||
|
height: rowHeight;
|
||||||
|
// The rest of this is cargo-culted to restore the default styling
|
||||||
|
SystemPalette {
|
||||||
|
id: myPalette;
|
||||||
|
colorGroup: SystemPalette.Active
|
||||||
|
}
|
||||||
|
color: {
|
||||||
|
var baseColor = styleData.alternate?myPalette.alternateBase:myPalette.base
|
||||||
|
return styleData.selected?myPalette.highlight:baseColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
itemDelegate: Item {
|
||||||
|
id: itemCell;
|
||||||
|
property bool isCheckBox: typeof(styleData.value) === 'boolean';
|
||||||
|
NameCard {
|
||||||
|
id: nameCard;
|
||||||
|
visible: !isCheckBox;
|
||||||
|
width: nameWidth;
|
||||||
|
displayName: styleData.value;
|
||||||
|
userName: model.userName;
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
radius: itemCell.height / 4;
|
||||||
|
visible: isCheckBox;
|
||||||
|
color: styleData.value ? "green" : "red";
|
||||||
|
anchors.fill: parent;
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent;
|
||||||
|
acceptedButtons: Qt.LeftButton;
|
||||||
|
hoverEnabled: true;
|
||||||
|
onClicked: {
|
||||||
|
var newValue = !model[styleData.role];
|
||||||
|
var datum = userData[model.userIndex];
|
||||||
|
datum[styleData.role] = model[styleData.role] = newValue;
|
||||||
|
Users[styleData.role](model.sessionId);
|
||||||
|
// Just for now, while we cannot undo things:
|
||||||
|
userData.splice(model.userIndex, 1);
|
||||||
|
sortModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
height: pal.height - myCard.height;
|
||||||
|
width: pal.width;
|
||||||
|
sortIndicatorVisible: true;
|
||||||
|
onSortIndicatorColumnChanged: sortModel();
|
||||||
|
onSortIndicatorOrderChanged: sortModel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,6 +46,8 @@
|
||||||
#include <gl/QOpenGLContextWrapper.h>
|
#include <gl/QOpenGLContextWrapper.h>
|
||||||
|
|
||||||
#include <shared/GlobalAppProperties.h>
|
#include <shared/GlobalAppProperties.h>
|
||||||
|
#include <StatTracker.h>
|
||||||
|
#include <Trace.h>
|
||||||
#include <ResourceScriptingInterface.h>
|
#include <ResourceScriptingInterface.h>
|
||||||
#include <AccountManager.h>
|
#include <AccountManager.h>
|
||||||
#include <AddressManager.h>
|
#include <AddressManager.h>
|
||||||
|
@ -423,6 +425,8 @@ bool setupEssentials(int& argc, char** argv) {
|
||||||
steamClient->init();
|
steamClient->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DependencyManager::set<tracing::Tracer>();
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
// Select appropriate audio DLL
|
// Select appropriate audio DLL
|
||||||
QString audioDLLPath = QCoreApplication::applicationDirPath();
|
QString audioDLLPath = QCoreApplication::applicationDirPath();
|
||||||
|
@ -445,6 +449,7 @@ bool setupEssentials(int& argc, char** argv) {
|
||||||
|
|
||||||
// Set dependencies
|
// Set dependencies
|
||||||
DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp));
|
DependencyManager::set<AccountManager>(std::bind(&Application::getUserAgent, qApp));
|
||||||
|
DependencyManager::set<StatTracker>();
|
||||||
DependencyManager::set<ScriptEngines>();
|
DependencyManager::set<ScriptEngines>();
|
||||||
DependencyManager::set<Preferences>();
|
DependencyManager::set<Preferences>();
|
||||||
DependencyManager::set<recording::Deck>();
|
DependencyManager::set<recording::Deck>();
|
||||||
|
@ -557,6 +562,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
|
|
||||||
{
|
{
|
||||||
const QString TEST_SCRIPT = "--testScript";
|
const QString TEST_SCRIPT = "--testScript";
|
||||||
|
const QString TRACE_FILE = "--traceFile";
|
||||||
const QStringList args = arguments();
|
const QStringList args = arguments();
|
||||||
for (int i = 0; i < args.size() - 1; ++i) {
|
for (int i = 0; i < args.size() - 1; ++i) {
|
||||||
if (args.at(i) == TEST_SCRIPT) {
|
if (args.at(i) == TEST_SCRIPT) {
|
||||||
|
@ -564,6 +570,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
||||||
if (QFileInfo(testScriptPath).exists()) {
|
if (QFileInfo(testScriptPath).exists()) {
|
||||||
setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath));
|
setProperty(hifi::properties::TEST, QUrl::fromLocalFile(testScriptPath));
|
||||||
}
|
}
|
||||||
|
} else if (args.at(i) == TRACE_FILE) {
|
||||||
|
QString traceFilePath = args.at(i + 1);
|
||||||
|
setProperty(hifi::properties::TRACING, traceFilePath);
|
||||||
|
DependencyManager::get<tracing::Tracer>()->startTracing();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1572,6 +1582,13 @@ void Application::cleanupBeforeQuit() {
|
||||||
QString webengineRemoteDebugging = QProcessEnvironment::systemEnvironment().value("QTWEBENGINE_REMOTE_DEBUGGING", "false");
|
QString webengineRemoteDebugging = QProcessEnvironment::systemEnvironment().value("QTWEBENGINE_REMOTE_DEBUGGING", "false");
|
||||||
qCDebug(interfaceapp) << "QTWEBENGINE_REMOTE_DEBUGGING =" << webengineRemoteDebugging;
|
qCDebug(interfaceapp) << "QTWEBENGINE_REMOTE_DEBUGGING =" << webengineRemoteDebugging;
|
||||||
|
|
||||||
|
if (tracing::enabled()) {
|
||||||
|
auto tracer = DependencyManager::get<tracing::Tracer>();
|
||||||
|
tracer->stopTracing();
|
||||||
|
auto outputFile = property(hifi::properties::TRACING).toString();
|
||||||
|
tracer->serialize(outputFile);
|
||||||
|
}
|
||||||
|
|
||||||
// Stop third party processes so that they're not left running in the event of a subsequent shutdown crash.
|
// Stop third party processes so that they're not left running in the event of a subsequent shutdown crash.
|
||||||
#ifdef HAVE_DDE
|
#ifdef HAVE_DDE
|
||||||
DependencyManager::get<DdeFaceTracker>()->setEnabled(false);
|
DependencyManager::get<DdeFaceTracker>()->setEnabled(false);
|
||||||
|
@ -1849,6 +1866,7 @@ void Application::initializeUi() {
|
||||||
rootContext->setContextProperty("Assets", new AssetMappingsScriptingInterface());
|
rootContext->setContextProperty("Assets", new AssetMappingsScriptingInterface());
|
||||||
|
|
||||||
rootContext->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data());
|
rootContext->setContextProperty("AvatarList", DependencyManager::get<AvatarManager>().data());
|
||||||
|
rootContext->setContextProperty("Users", DependencyManager::get<UsersScriptingInterface>().data());
|
||||||
|
|
||||||
rootContext->setContextProperty("Camera", &_myCamera);
|
rootContext->setContextProperty("Camera", &_myCamera);
|
||||||
|
|
||||||
|
@ -1927,6 +1945,16 @@ void Application::initializeUi() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::paintGL() {
|
void Application::paintGL() {
|
||||||
|
PROFILE_COUNTER(interfaceapp, "fps", { { "fps", _frameCounter.rate() } });
|
||||||
|
PROFILE_COUNTER(interfaceapp, "downloads", {
|
||||||
|
{ "current", ResourceCache::getLoadingRequests().length() },
|
||||||
|
{ "pending", ResourceCache::getPendingRequestCount() }
|
||||||
|
});
|
||||||
|
PROFILE_COUNTER(interfaceapp, "processing", {
|
||||||
|
{ "current", DependencyManager::get<StatTracker>()->getStat("Processing") },
|
||||||
|
{ "pending", DependencyManager::get<StatTracker>()->getStat("PendingProcessing") }
|
||||||
|
});
|
||||||
|
|
||||||
// Some plugins process message events, allowing paintGL to be called reentrantly.
|
// Some plugins process message events, allowing paintGL to be called reentrantly.
|
||||||
if (_inPaint || _aboutToQuit) {
|
if (_inPaint || _aboutToQuit) {
|
||||||
return;
|
return;
|
||||||
|
@ -1938,7 +1966,7 @@ void Application::paintGL() {
|
||||||
_frameCount++;
|
_frameCount++;
|
||||||
|
|
||||||
auto lastPaintBegin = usecTimestampNow();
|
auto lastPaintBegin = usecTimestampNow();
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff0000ff, (uint64_t)_frameCount);
|
PROFILE_RANGE_EX(interfaceapp, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount);
|
||||||
PerformanceTimer perfTimer("paintGL");
|
PerformanceTimer perfTimer("paintGL");
|
||||||
|
|
||||||
if (nullptr == _displayPlugin) {
|
if (nullptr == _displayPlugin) {
|
||||||
|
@ -2115,7 +2143,7 @@ void Application::paintGL() {
|
||||||
auto finalFramebuffer = framebufferCache->getFramebuffer();
|
auto finalFramebuffer = framebufferCache->getFramebuffer();
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE(__FUNCTION__ "/mainRender");
|
PROFILE_RANGE(interfaceapp, "/mainRender");
|
||||||
PerformanceTimer perfTimer("mainRender");
|
PerformanceTimer perfTimer("mainRender");
|
||||||
renderArgs._boomOffset = boomOffset;
|
renderArgs._boomOffset = boomOffset;
|
||||||
// Viewport is assigned to the size of the framebuffer
|
// Viewport is assigned to the size of the framebuffer
|
||||||
|
@ -2170,7 +2198,7 @@ void Application::paintGL() {
|
||||||
frame->overlay = _applicationOverlay.getOverlayTexture();
|
frame->overlay = _applicationOverlay.getOverlayTexture();
|
||||||
// deliver final scene rendering commands to the display plugin
|
// deliver final scene rendering commands to the display plugin
|
||||||
{
|
{
|
||||||
PROFILE_RANGE(__FUNCTION__ "/pluginOutput");
|
PROFILE_RANGE(interfaceapp, "/pluginOutput");
|
||||||
PerformanceTimer perfTimer("pluginOutput");
|
PerformanceTimer perfTimer("pluginOutput");
|
||||||
_frameCounter.increment();
|
_frameCounter.increment();
|
||||||
displayPlugin->submitFrame(frame);
|
displayPlugin->submitFrame(frame);
|
||||||
|
@ -2258,7 +2286,7 @@ void Application::resizeEvent(QResizeEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::resizeGL() {
|
void Application::resizeGL() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
if (nullptr == _displayPlugin) {
|
if (nullptr == _displayPlugin) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2313,7 +2341,6 @@ bool Application::importSVOFromURL(const QString& urlString) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::event(QEvent* event) {
|
bool Application::event(QEvent* event) {
|
||||||
|
|
||||||
if (!Menu::getInstance()) {
|
if (!Menu::getInstance()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2904,7 +2931,7 @@ void Application::maybeToggleMenuVisible(QMouseEvent* event) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::mouseMoveEvent(QMouseEvent* event) {
|
void Application::mouseMoveEvent(QMouseEvent* event) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
|
|
||||||
if (_aboutToQuit) {
|
if (_aboutToQuit) {
|
||||||
return;
|
return;
|
||||||
|
@ -3198,6 +3225,8 @@ bool Application::shouldPaint(float nsecsElapsed) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::idle(float nsecsElapsed) {
|
void Application::idle(float nsecsElapsed) {
|
||||||
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
|
PerformanceTimer perfTimer("idle");
|
||||||
|
|
||||||
// Update the deadlock watchdog
|
// Update the deadlock watchdog
|
||||||
updateHeartbeat();
|
updateHeartbeat();
|
||||||
|
@ -3212,8 +3241,6 @@ void Application::idle(float nsecsElapsed) {
|
||||||
connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop);
|
connect(offscreenUi.data(), &OffscreenUi::showDesktop, this, &Application::showDesktop);
|
||||||
}
|
}
|
||||||
|
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
|
||||||
|
|
||||||
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
|
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
|
||||||
steamClient->runCallbacks();
|
steamClient->runCallbacks();
|
||||||
}
|
}
|
||||||
|
@ -3234,8 +3261,6 @@ void Application::idle(float nsecsElapsed) {
|
||||||
|
|
||||||
_simCounter.increment();
|
_simCounter.increment();
|
||||||
|
|
||||||
PerformanceTimer perfTimer("idle");
|
|
||||||
|
|
||||||
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
// Normally we check PipelineWarnings, but since idle will often take more than 10ms we only show these idle timing
|
||||||
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
// details if we're in ExtraDebugging mode. However, the ::update() and its subcomponents will show their timing
|
||||||
// details normally.
|
// details normally.
|
||||||
|
@ -3929,9 +3954,11 @@ void Application::updateDialogs(float deltaTime) const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool domainLoadingInProgress = false;
|
||||||
|
|
||||||
void Application::update(float deltaTime) {
|
void Application::update(float deltaTime) {
|
||||||
|
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xffff0000, (uint64_t)_frameCount + 1);
|
PROFILE_RANGE_EX(interfaceapp, __FUNCTION__, 0xffff0000, (uint64_t)_frameCount + 1);
|
||||||
|
|
||||||
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings);
|
||||||
PerformanceWarning warn(showWarnings, "Application::update()");
|
PerformanceWarning warn(showWarnings, "Application::update()");
|
||||||
|
@ -3939,6 +3966,11 @@ void Application::update(float deltaTime) {
|
||||||
updateLOD();
|
updateLOD();
|
||||||
|
|
||||||
if (!_physicsEnabled) {
|
if (!_physicsEnabled) {
|
||||||
|
if (!domainLoadingInProgress) {
|
||||||
|
PROFILE_ASYNC_BEGIN(interfaceapp, "Scene Loading", "");
|
||||||
|
domainLoadingInProgress = true;
|
||||||
|
}
|
||||||
|
|
||||||
// we haven't yet enabled physics. we wait until we think we have all the collision information
|
// we haven't yet enabled physics. we wait until we think we have all the collision information
|
||||||
// for nearby entities before starting bullet up.
|
// for nearby entities before starting bullet up.
|
||||||
quint64 now = usecTimestampNow();
|
quint64 now = usecTimestampNow();
|
||||||
|
@ -3968,6 +4000,9 @@ void Application::update(float deltaTime) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (domainLoadingInProgress) {
|
||||||
|
domainLoadingInProgress = false;
|
||||||
|
PROFILE_ASYNC_END(interfaceapp, "Scene Loading", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -4061,12 +4096,12 @@ void Application::update(float deltaTime) {
|
||||||
QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>();
|
QSharedPointer<AvatarManager> avatarManager = DependencyManager::get<AvatarManager>();
|
||||||
|
|
||||||
if (_physicsEnabled) {
|
if (_physicsEnabled) {
|
||||||
PROFILE_RANGE_EX("Physics", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE_EX(interfaceapp, "Physics", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
|
|
||||||
PerformanceTimer perfTimer("physics");
|
PerformanceTimer perfTimer("physics");
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("UpdateStats", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE_EX(interfaceapp, "UpdateStats", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
|
|
||||||
PerformanceTimer perfTimer("updateStates)");
|
PerformanceTimer perfTimer("updateStates)");
|
||||||
static VectorOfMotionStates motionStates;
|
static VectorOfMotionStates motionStates;
|
||||||
|
@ -4100,14 +4135,14 @@ void Application::update(float deltaTime) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("StepSimulation", 0xffff8000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE_EX(interfaceapp, "StepSimulation", 0xffff8000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
PerformanceTimer perfTimer("stepSimulation");
|
PerformanceTimer perfTimer("stepSimulation");
|
||||||
getEntities()->getTree()->withWriteLock([&] {
|
getEntities()->getTree()->withWriteLock([&] {
|
||||||
_physicsEngine->stepSimulation();
|
_physicsEngine->stepSimulation();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("HarvestChanges", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE_EX(interfaceapp, "HarvestChanges", 0xffffff00, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
PerformanceTimer perfTimer("harvestChanges");
|
PerformanceTimer perfTimer("harvestChanges");
|
||||||
if (_physicsEngine->hasOutgoingChanges()) {
|
if (_physicsEngine->hasOutgoingChanges()) {
|
||||||
getEntities()->getTree()->withWriteLock([&] {
|
getEntities()->getTree()->withWriteLock([&] {
|
||||||
|
@ -4149,20 +4184,20 @@ void Application::update(float deltaTime) {
|
||||||
_avatarSimCounter.increment();
|
_avatarSimCounter.increment();
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("OtherAvatars", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE_EX(interfaceapp, "OtherAvatars", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
avatarManager->updateOtherAvatars(deltaTime);
|
avatarManager->updateOtherAvatars(deltaTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
qApp->updateMyAvatarLookAtPosition();
|
qApp->updateMyAvatarLookAtPosition();
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("MyAvatar", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE_EX(interfaceapp, "MyAvatar", 0xffff00ff, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
avatarManager->updateMyAvatar(deltaTime);
|
avatarManager->updateMyAvatar(deltaTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("Overlays", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE_EX(interfaceapp, "Overlays", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
PerformanceTimer perfTimer("overlays");
|
PerformanceTimer perfTimer("overlays");
|
||||||
_overlays.update(deltaTime);
|
_overlays.update(deltaTime);
|
||||||
}
|
}
|
||||||
|
@ -4182,7 +4217,7 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
// Update my voxel servers with my current voxel query...
|
// Update my voxel servers with my current voxel query...
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("QueryOctree", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
PROFILE_RANGE_EX(interfaceapp, "QueryOctree", 0xffff0000, (uint64_t)getActiveDisplayPlugin()->presentCount());
|
||||||
QMutexLocker viewLocker(&_viewMutex);
|
QMutexLocker viewLocker(&_viewMutex);
|
||||||
PerformanceTimer perfTimer("queryOctree");
|
PerformanceTimer perfTimer("queryOctree");
|
||||||
quint64 sinceLastQuery = now - _lastQueriedTime;
|
quint64 sinceLastQuery = now - _lastQueriedTime;
|
||||||
|
@ -4222,7 +4257,7 @@ void Application::update(float deltaTime) {
|
||||||
avatarManager->postUpdate(deltaTime);
|
avatarManager->postUpdate(deltaTime);
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("PreRenderLambdas", 0xffff0000, (uint64_t)0);
|
PROFILE_RANGE_EX(interfaceapp, "PreRenderLambdas", 0xffff0000, (uint64_t)0);
|
||||||
|
|
||||||
std::unique_lock<std::mutex> guard(_postUpdateLambdasLock);
|
std::unique_lock<std::mutex> guard(_postUpdateLambdasLock);
|
||||||
for (auto& iter : _postUpdateLambdas) {
|
for (auto& iter : _postUpdateLambdas) {
|
||||||
|
@ -4499,8 +4534,8 @@ QRect Application::getDesirableApplicationGeometry() const {
|
||||||
// or the "myCamera".
|
// or the "myCamera".
|
||||||
//
|
//
|
||||||
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
void Application::loadViewFrustum(Camera& camera, ViewFrustum& viewFrustum) {
|
||||||
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
PerformanceTimer perfTimer("loadViewFrustum");
|
PerformanceTimer perfTimer("loadViewFrustum");
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
|
||||||
// We will use these below, from either the camera or head vectors calculated above
|
// We will use these below, from either the camera or head vectors calculated above
|
||||||
viewFrustum.setProjection(camera.getProjection());
|
viewFrustum.setProjection(camera.getProjection());
|
||||||
|
|
||||||
|
@ -4676,7 +4711,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
myAvatar->preDisplaySide(renderArgs);
|
myAvatar->preDisplaySide(renderArgs);
|
||||||
|
|
||||||
activeRenderingThread = QThread::currentThread();
|
activeRenderingThread = QThread::currentThread();
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
PerformanceTimer perfTimer("display");
|
PerformanceTimer perfTimer("display");
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()");
|
||||||
|
|
||||||
|
|
|
@ -184,6 +184,7 @@ void Avatar::animateScaleChanges(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::updateAvatarEntities() {
|
void Avatar::updateAvatarEntities() {
|
||||||
|
PerformanceTimer perfTimer("attachments");
|
||||||
// - if queueEditEntityMessage sees clientOnly flag it does _myAvatar->updateAvatarEntity()
|
// - if queueEditEntityMessage sees clientOnly flag it does _myAvatar->updateAvatarEntity()
|
||||||
// - updateAvatarEntity saves the bytes and sets _avatarEntityDataLocallyEdited
|
// - updateAvatarEntity saves the bytes and sets _avatarEntityDataLocallyEdited
|
||||||
// - MyAvatar::update notices _avatarEntityDataLocallyEdited and calls sendIdentityPacket
|
// - MyAvatar::update notices _avatarEntityDataLocallyEdited and calls sendIdentityPacket
|
||||||
|
@ -285,28 +286,38 @@ void Avatar::simulate(float deltaTime) {
|
||||||
}
|
}
|
||||||
animateScaleChanges(deltaTime);
|
animateScaleChanges(deltaTime);
|
||||||
|
|
||||||
// update the shouldAnimate flag to match whether or not we will render the avatar.
|
bool avatarPositionInView = false;
|
||||||
const float MINIMUM_VISIBILITY_FOR_ON = 0.4f;
|
bool avatarMeshInView = false;
|
||||||
const float MAXIMUM_VISIBILITY_FOR_OFF = 0.6f;
|
{ // update the shouldAnimate flag to match whether or not we will render the avatar.
|
||||||
ViewFrustum viewFrustum;
|
PerformanceTimer perfTimer("cull");
|
||||||
qApp->copyViewFrustum(viewFrustum);
|
ViewFrustum viewFrustum;
|
||||||
float visibility = calculateRenderAccuracy(viewFrustum.getPosition(),
|
{
|
||||||
getBounds(), DependencyManager::get<LODManager>()->getOctreeSizeScale());
|
PerformanceTimer perfTimer("LOD");
|
||||||
if (!_shouldAnimate) {
|
const float MINIMUM_VISIBILITY_FOR_ON = 0.4f;
|
||||||
if (visibility > MINIMUM_VISIBILITY_FOR_ON) {
|
const float MAXIMUM_VISIBILITY_FOR_OFF = 0.6f;
|
||||||
_shouldAnimate = true;
|
qApp->copyViewFrustum(viewFrustum);
|
||||||
qCDebug(interfaceapp) << "Restoring" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility;
|
float visibility = calculateRenderAccuracy(viewFrustum.getPosition(),
|
||||||
|
getBounds(), DependencyManager::get<LODManager>()->getOctreeSizeScale());
|
||||||
|
if (!_shouldAnimate) {
|
||||||
|
if (visibility > MINIMUM_VISIBILITY_FOR_ON) {
|
||||||
|
_shouldAnimate = true;
|
||||||
|
qCDebug(interfaceapp) << "Restoring" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility;
|
||||||
|
}
|
||||||
|
} else if (visibility < MAXIMUM_VISIBILITY_FOR_OFF) {
|
||||||
|
_shouldAnimate = false;
|
||||||
|
qCDebug(interfaceapp) << "Optimizing" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (visibility < MAXIMUM_VISIBILITY_FOR_OFF) {
|
|
||||||
_shouldAnimate = false;
|
|
||||||
qCDebug(interfaceapp) << "Optimizing" << (isMyAvatar() ? "myself" : getSessionUUID()) << "for visibility" << visibility;
|
|
||||||
}
|
|
||||||
|
|
||||||
// simple frustum check
|
{
|
||||||
float boundingRadius = getBoundingRadius();
|
PerformanceTimer perfTimer("inView");
|
||||||
qApp->copyDisplayViewFrustum(viewFrustum);
|
// simple frustum check
|
||||||
bool avatarPositionInView = viewFrustum.sphereIntersectsFrustum(getPosition(), boundingRadius);
|
float boundingRadius = getBoundingRadius();
|
||||||
bool avatarMeshInView = viewFrustum.boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound());
|
qApp->copyDisplayViewFrustum(viewFrustum);
|
||||||
|
avatarPositionInView = viewFrustum.sphereIntersectsFrustum(getPosition(), boundingRadius);
|
||||||
|
avatarMeshInView = viewFrustum.boxIntersectsFrustum(_skeletonModel->getRenderableMeshBound());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (_shouldAnimate && !_shouldSkipRender && (avatarPositionInView || avatarMeshInView)) {
|
if (_shouldAnimate && !_shouldSkipRender && (avatarPositionInView || avatarMeshInView)) {
|
||||||
{
|
{
|
||||||
|
@ -331,6 +342,7 @@ void Avatar::simulate(float deltaTime) {
|
||||||
} else {
|
} else {
|
||||||
// a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated.
|
// a non-full update is still required so that the position, rotation, scale and bounds of the skeletonModel are updated.
|
||||||
getHead()->setPosition(getPosition());
|
getHead()->setPosition(getPosition());
|
||||||
|
PerformanceTimer perfTimer("skeleton");
|
||||||
_skeletonModel->simulate(deltaTime, false);
|
_skeletonModel->simulate(deltaTime, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -379,6 +391,7 @@ void Avatar::applyPositionDelta(const glm::vec3& delta) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::measureMotionDerivatives(float deltaTime) {
|
void Avatar::measureMotionDerivatives(float deltaTime) {
|
||||||
|
PerformanceTimer perfTimer("derivatives");
|
||||||
// linear
|
// linear
|
||||||
float invDeltaTime = 1.0f / deltaTime;
|
float invDeltaTime = 1.0f / deltaTime;
|
||||||
// Floating point error prevents us from computing velocity in a naive way
|
// Floating point error prevents us from computing velocity in a naive way
|
||||||
|
@ -645,6 +658,7 @@ bool Avatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
||||||
|
|
||||||
// virtual
|
// virtual
|
||||||
void Avatar::simulateAttachments(float deltaTime) {
|
void Avatar::simulateAttachments(float deltaTime) {
|
||||||
|
PerformanceTimer perfTimer("attachments");
|
||||||
for (int i = 0; i < (int)_attachmentModels.size(); i++) {
|
for (int i = 0; i < (int)_attachmentModels.size(); i++) {
|
||||||
const AttachmentData& attachment = _attachmentData.at(i);
|
const AttachmentData& attachment = _attachmentData.at(i);
|
||||||
auto& model = _attachmentModels.at(i);
|
auto& model = _attachmentModels.at(i);
|
||||||
|
@ -1039,6 +1053,7 @@ void Avatar::setAttachmentData(const QVector<AttachmentData>& attachmentData) {
|
||||||
|
|
||||||
|
|
||||||
int Avatar::parseDataFromBuffer(const QByteArray& buffer) {
|
int Avatar::parseDataFromBuffer(const QByteArray& buffer) {
|
||||||
|
PerformanceTimer perfTimer("unpack");
|
||||||
if (!_initialized) {
|
if (!_initialized) {
|
||||||
// now that we have data for this Avatar we are go for init
|
// now that we have data for this Avatar we are go for init
|
||||||
init();
|
init();
|
||||||
|
@ -1258,6 +1273,7 @@ void Avatar::setOrientation(const glm::quat& orientation) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Avatar::updatePalms() {
|
void Avatar::updatePalms() {
|
||||||
|
PerformanceTimer perfTimer("palms");
|
||||||
// update thread-safe caches
|
// update thread-safe caches
|
||||||
_leftPalmRotationCache.set(getUncachedLeftPalmRotation());
|
_leftPalmRotationCache.set(getUncachedLeftPalmRotation());
|
||||||
_rightPalmRotationCache.set(getUncachedRightPalmRotation());
|
_rightPalmRotationCache.set(getUncachedRightPalmRotation());
|
||||||
|
|
|
@ -10,6 +10,10 @@
|
||||||
#include "TestScriptingInterface.h"
|
#include "TestScriptingInterface.h"
|
||||||
|
|
||||||
#include <QtCore/QCoreApplication>
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QLoggingCategory>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
TestScriptingInterface* TestScriptingInterface::getInstance() {
|
TestScriptingInterface* TestScriptingInterface::getInstance() {
|
||||||
static TestScriptingInterface sharedInstance;
|
static TestScriptingInterface sharedInstance;
|
||||||
|
@ -28,3 +32,27 @@ void TestScriptingInterface::waitForDownloadIdle() {
|
||||||
|
|
||||||
void TestScriptingInterface::waitIdle() {
|
void TestScriptingInterface::waitIdle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TestScriptingInterface::startTracing(QString logrules) {
|
||||||
|
if (!logrules.isEmpty()) {
|
||||||
|
QLoggingCategory::setFilterRules(logrules);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!DependencyManager::isSet<tracing::Tracer>()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DependencyManager::get<tracing::Tracer>()->startTracing();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TestScriptingInterface::stopTracing(QString filename) {
|
||||||
|
if (!DependencyManager::isSet<tracing::Tracer>()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tracer = DependencyManager::get<tracing::Tracer>();
|
||||||
|
tracer->stopTracing();
|
||||||
|
tracer->serialize(filename);
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -38,6 +38,17 @@ public slots:
|
||||||
*/
|
*/
|
||||||
void waitIdle();
|
void waitIdle();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Start recording Chrome compatible tracing events
|
||||||
|
* logRules can be used to specify a set of logging category rules to limit what gets captured
|
||||||
|
*/
|
||||||
|
bool startTracing(QString logrules = "");
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Stop recording Chrome compatible tracing events and serialize recorded events to a file
|
||||||
|
* Using a filename with a .gz extension will automatically compress the output file
|
||||||
|
*/
|
||||||
|
bool stopTracing(QString filename);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_TestScriptingInterface_h
|
#endif // hifi_TestScriptingInterface_h
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "ui/Stats.h"
|
#include "ui/Stats.h"
|
||||||
#include "ui/AvatarInputs.h"
|
#include "ui/AvatarInputs.h"
|
||||||
#include "OffscreenUi.h"
|
#include "OffscreenUi.h"
|
||||||
|
#include "InterfaceLogging.h"
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
|
|
||||||
const vec4 CONNECTION_STATUS_BORDER_COLOR{ 1.0f, 0.0f, 0.0f, 0.8f };
|
const vec4 CONNECTION_STATUS_BORDER_COLOR{ 1.0f, 0.0f, 0.0f, 0.8f };
|
||||||
|
@ -56,7 +57,7 @@ ApplicationOverlay::~ApplicationOverlay() {
|
||||||
|
|
||||||
// Renders the overlays either to a texture or to the screen
|
// Renders the overlays either to a texture or to the screen
|
||||||
void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
|
||||||
|
|
||||||
buildFramebufferObject();
|
buildFramebufferObject();
|
||||||
|
@ -95,7 +96,7 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) {
|
void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
|
|
||||||
if (!_uiTexture) {
|
if (!_uiTexture) {
|
||||||
_uiTexture = gpu::TexturePointer(gpu::Texture::createExternal2D(OffscreenQmlSurface::getDiscardLambda()));
|
_uiTexture = gpu::TexturePointer(gpu::Texture::createExternal2D(OffscreenQmlSurface::getDiscardLambda()));
|
||||||
|
@ -123,7 +124,7 @@ void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationOverlay::renderAudioScope(RenderArgs* renderArgs) {
|
void ApplicationOverlay::renderAudioScope(RenderArgs* renderArgs) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
|
|
||||||
gpu::Batch& batch = *renderArgs->_batch;
|
gpu::Batch& batch = *renderArgs->_batch;
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
@ -142,7 +143,7 @@ void ApplicationOverlay::renderAudioScope(RenderArgs* renderArgs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) {
|
void ApplicationOverlay::renderOverlays(RenderArgs* renderArgs) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
|
|
||||||
gpu::Batch& batch = *renderArgs->_batch;
|
gpu::Batch& batch = *renderArgs->_batch;
|
||||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||||
|
@ -261,7 +262,7 @@ static const auto DEFAULT_SAMPLER = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LI
|
||||||
static const auto DEPTH_FORMAT = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH);
|
static const auto DEPTH_FORMAT = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH);
|
||||||
|
|
||||||
void ApplicationOverlay::buildFramebufferObject() {
|
void ApplicationOverlay::buildFramebufferObject() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
|
|
||||||
auto uiSize = qApp->getUiSize();
|
auto uiSize = qApp->getUiSize();
|
||||||
if (!_overlayFramebuffer || uiSize != _overlayFramebuffer->getSize()) {
|
if (!_overlayFramebuffer || uiSize != _overlayFramebuffer->getSize()) {
|
||||||
|
@ -287,4 +288,4 @@ gpu::TexturePointer ApplicationOverlay::getOverlayTexture() {
|
||||||
return gpu::TexturePointer();
|
return gpu::TexturePointer();
|
||||||
}
|
}
|
||||||
return _overlayFramebuffer->getRenderBuffer(0);
|
return _overlayFramebuffer->getRenderBuffer(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <RegisteredMetaTypes.h>
|
#include <RegisteredMetaTypes.h>
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
|
#include "InterfaceLogging.h"
|
||||||
#include "Image3DOverlay.h"
|
#include "Image3DOverlay.h"
|
||||||
#include "Circle3DOverlay.h"
|
#include "Circle3DOverlay.h"
|
||||||
#include "Cube3DOverlay.h"
|
#include "Cube3DOverlay.h"
|
||||||
|
@ -101,7 +102,7 @@ void Overlays::cleanupOverlaysToDelete() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Overlays::renderHUD(RenderArgs* renderArgs) {
|
void Overlays::renderHUD(RenderArgs* renderArgs) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(interfaceapp, __FUNCTION__);
|
||||||
QReadLocker lock(&_lock);
|
QReadLocker lock(&_lock);
|
||||||
gpu::Batch& batch = *renderArgs->_batch;
|
gpu::Batch& batch = *renderArgs->_batch;
|
||||||
|
|
||||||
|
|
|
@ -394,7 +394,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
||||||
loadPoses(underPoses);
|
loadPoses(underPoses);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
PROFILE_RANGE_EX("ik/relax", 0xffff00ff, 0);
|
PROFILE_RANGE_EX(animation, "ik/relax", 0xffff00ff, 0);
|
||||||
|
|
||||||
// relax toward underPoses
|
// relax toward underPoses
|
||||||
// HACK: this relaxation needs to be constant per-frame rather than per-realtime
|
// HACK: this relaxation needs to be constant per-frame rather than per-realtime
|
||||||
|
@ -433,7 +433,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
||||||
// build a list of targets from _targetVarVec
|
// build a list of targets from _targetVarVec
|
||||||
std::vector<IKTarget> targets;
|
std::vector<IKTarget> targets;
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("ik/computeTargets", 0xffff00ff, 0);
|
PROFILE_RANGE_EX(animation, "ik/computeTargets", 0xffff00ff, 0);
|
||||||
computeTargets(animVars, targets, underPoses);
|
computeTargets(animVars, targets, underPoses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("ik/shiftHips", 0xffff00ff, 0);
|
PROFILE_RANGE_EX(animation, "ik/shiftHips", 0xffff00ff, 0);
|
||||||
|
|
||||||
// shift hips according to the _hipsOffset from the previous frame
|
// shift hips according to the _hipsOffset from the previous frame
|
||||||
float offsetLength = glm::length(_hipsOffset);
|
float offsetLength = glm::length(_hipsOffset);
|
||||||
|
@ -476,12 +476,12 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("ik/ccd", 0xffff00ff, 0);
|
PROFILE_RANGE_EX(animation, "ik/ccd", 0xffff00ff, 0);
|
||||||
solveWithCyclicCoordinateDescent(targets);
|
solveWithCyclicCoordinateDescent(targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("ik/measureHipsOffset", 0xffff00ff, 0);
|
PROFILE_RANGE_EX(animation, "ik/measureHipsOffset", 0xffff00ff, 0);
|
||||||
|
|
||||||
// measure new _hipsOffset for next frame
|
// measure new _hipsOffset for next frame
|
||||||
// by looking for discrepancies between where a targeted endEffector is
|
// by looking for discrepancies between where a targeted endEffector is
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
|
|
||||||
#include "AnimationCache.h"
|
#include "AnimationCache.h"
|
||||||
#include "AnimationLogging.h"
|
#include "AnimationLogging.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
#include <StatTracker.h>
|
||||||
|
#include <Profile.h>
|
||||||
|
|
||||||
int animationPointerMetaTypeId = qRegisterMetaType<AnimationPointer>();
|
int animationPointerMetaTypeId = qRegisterMetaType<AnimationPointer>();
|
||||||
|
|
||||||
|
@ -45,9 +48,14 @@ Animation::Animation(const QUrl& url) : Resource(url) {}
|
||||||
AnimationReader::AnimationReader(const QUrl& url, const QByteArray& data) :
|
AnimationReader::AnimationReader(const QUrl& url, const QByteArray& data) :
|
||||||
_url(url),
|
_url(url),
|
||||||
_data(data) {
|
_data(data) {
|
||||||
|
DependencyManager::get<StatTracker>()->incrementStat("PendingProcessing");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationReader::run() {
|
void AnimationReader::run() {
|
||||||
|
DependencyManager::get<StatTracker>()->decrementStat("PendingProcessing");
|
||||||
|
CounterStat counter("Processing");
|
||||||
|
|
||||||
|
PROFILE_RANGE_EX(animation, __FUNCTION__, 0xFF00FF00, 0, { { "url", _url.toString() } });
|
||||||
auto originalPriority = QThread::currentThread()->priority();
|
auto originalPriority = QThread::currentThread()->priority();
|
||||||
if (originalPriority == QThread::InheritPriority) {
|
if (originalPriority == QThread::InheritPriority) {
|
||||||
originalPriority = QThread::NormalPriority;
|
originalPriority = QThread::NormalPriority;
|
||||||
|
|
|
@ -65,6 +65,8 @@ public:
|
||||||
|
|
||||||
explicit Animation(const QUrl& url);
|
explicit Animation(const QUrl& url);
|
||||||
|
|
||||||
|
QString getType() const override { return "Animation"; }
|
||||||
|
|
||||||
const FBXGeometry& getGeometry() const { return *_geometry; }
|
const FBXGeometry& getGeometry() const { return *_geometry; }
|
||||||
|
|
||||||
virtual bool isLoaded() const override;
|
virtual bool isLoaded() const override;
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <GeometryUtil.h>
|
#include <GeometryUtil.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <DebugDraw.h>
|
#include <DebugDraw.h>
|
||||||
|
#include <PerfStat.h>
|
||||||
#include <ScriptValueUtils.h>
|
#include <ScriptValueUtils.h>
|
||||||
#include <shared/NsightHelpers.h>
|
#include <shared/NsightHelpers.h>
|
||||||
|
|
||||||
|
@ -882,7 +883,7 @@ void Rig::updateAnimationStateHandlers() { // called on avatar update thread (wh
|
||||||
|
|
||||||
void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
|
void Rig::updateAnimations(float deltaTime, glm::mat4 rootTransform) {
|
||||||
|
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xffff00ff, 0);
|
PROFILE_RANGE_EX(animation, __FUNCTION__, 0xffff00ff, 0);
|
||||||
|
|
||||||
setModelOffset(rootTransform);
|
setModelOffset(rootTransform);
|
||||||
|
|
||||||
|
@ -1249,6 +1250,7 @@ void Rig::copyJointsIntoJointData(QVector<JointData>& jointDataVec) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
void Rig::copyJointsFromJointData(const QVector<JointData>& jointDataVec) {
|
||||||
|
PerformanceTimer perfTimer("copyJoints");
|
||||||
if (_animSkeleton && jointDataVec.size() == (int)_internalPoseSet._overrideFlags.size()) {
|
if (_animSkeleton && jointDataVec.size() == (int)_internalPoseSet._overrideFlags.size()) {
|
||||||
|
|
||||||
// transform all the default poses into rig space.
|
// transform all the default poses into rig space.
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
static const int SRC_MAX_CHANNELS = 2;
|
static const int SRC_MAX_CHANNELS = 4;
|
||||||
|
|
||||||
// polyphase filter
|
// polyphase filter
|
||||||
static const int SRC_PHASEBITS = 8;
|
static const int SRC_PHASEBITS = 8;
|
||||||
|
@ -48,8 +48,6 @@ public:
|
||||||
int getMinInput(int outputFrames);
|
int getMinInput(int outputFrames);
|
||||||
int getMaxInput(int outputFrames);
|
int getMaxInput(int outputFrames);
|
||||||
|
|
||||||
int getExactInput(int outputFrames);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float* _polyphaseFilter;
|
float* _polyphaseFilter;
|
||||||
int* _stepTable;
|
int* _stepTable;
|
||||||
|
@ -77,12 +75,18 @@ private:
|
||||||
|
|
||||||
int multirateFilter1(const float* input0, float* output0, int inputFrames);
|
int multirateFilter1(const float* input0, float* output0, int inputFrames);
|
||||||
int multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
int multirateFilter2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
||||||
|
int multirateFilter4(const float* input0, const float* input1, const float* input2, const float* input3,
|
||||||
|
float* output0, float* output1, float* output2, float* output3, int inputFrames);
|
||||||
|
|
||||||
int multirateFilter1_SSE(const float* input0, float* output0, int inputFrames);
|
int multirateFilter1_ref(const float* input0, float* output0, int inputFrames);
|
||||||
int multirateFilter2_SSE(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
int multirateFilter2_ref(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
||||||
|
int multirateFilter4_ref(const float* input0, const float* input1, const float* input2, const float* input3,
|
||||||
|
float* output0, float* output1, float* output2, float* output3, int inputFrames);
|
||||||
|
|
||||||
int multirateFilter1_AVX2(const float* input0, float* output0, int inputFrames);
|
int multirateFilter1_AVX2(const float* input0, float* output0, int inputFrames);
|
||||||
int multirateFilter2_AVX2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
int multirateFilter2_AVX2(const float* input0, const float* input1, float* output0, float* output1, int inputFrames);
|
||||||
|
int multirateFilter4_AVX2(const float* input0, const float* input1, const float* input2, const float* input3,
|
||||||
|
float* output0, float* output1, float* output2, float* output3, int inputFrames);
|
||||||
|
|
||||||
void convertInput(const int16_t* input, float** outputs, int numFrames);
|
void convertInput(const int16_t* input, float** outputs, int numFrames);
|
||||||
void convertOutput(float** inputs, int16_t* output, int numFrames);
|
void convertOutput(float** inputs, int16_t* output, int numFrames);
|
||||||
|
|
|
@ -97,54 +97,9 @@ void Sound::downSample(const QByteArray& rawAudioByteArray, int sampleRate) {
|
||||||
// no resampling needed
|
// no resampling needed
|
||||||
_byteArray = rawAudioByteArray;
|
_byteArray = rawAudioByteArray;
|
||||||
|
|
||||||
} else if (_isAmbisonic) {
|
|
||||||
|
|
||||||
// FIXME: add a proper Ambisonic resampler!
|
|
||||||
int numChannels = 4;
|
|
||||||
AudioSRC resampler[4] { {sampleRate, AudioConstants::SAMPLE_RATE, 1},
|
|
||||||
{sampleRate, AudioConstants::SAMPLE_RATE, 1},
|
|
||||||
{sampleRate, AudioConstants::SAMPLE_RATE, 1},
|
|
||||||
{sampleRate, AudioConstants::SAMPLE_RATE, 1} };
|
|
||||||
|
|
||||||
// resize to max possible output
|
|
||||||
int numSourceFrames = rawAudioByteArray.size() / (numChannels * sizeof(AudioConstants::AudioSample));
|
|
||||||
int maxDestinationFrames = resampler[0].getMaxOutput(numSourceFrames);
|
|
||||||
int maxDestinationBytes = maxDestinationFrames * numChannels * sizeof(AudioConstants::AudioSample);
|
|
||||||
_byteArray.resize(maxDestinationBytes);
|
|
||||||
|
|
||||||
int numDestinationFrames = 0;
|
|
||||||
|
|
||||||
// iterate over channels
|
|
||||||
int16_t* srcBuffer = new int16_t[numSourceFrames];
|
|
||||||
int16_t* dstBuffer = new int16_t[maxDestinationFrames];
|
|
||||||
for (int ch = 0; ch < 4; ch++) {
|
|
||||||
|
|
||||||
int16_t* src = (int16_t*)rawAudioByteArray.data();
|
|
||||||
int16_t* dst = (int16_t*)_byteArray.data();
|
|
||||||
|
|
||||||
// deinterleave samples
|
|
||||||
for (int i = 0; i < numSourceFrames; i++) {
|
|
||||||
srcBuffer[i] = src[4*i + ch];
|
|
||||||
}
|
|
||||||
|
|
||||||
// resample one channel
|
|
||||||
numDestinationFrames = resampler[ch].render(srcBuffer, dstBuffer, numSourceFrames);
|
|
||||||
|
|
||||||
// reinterleave samples
|
|
||||||
for (int i = 0; i < numDestinationFrames; i++) {
|
|
||||||
dst[4*i + ch] = dstBuffer[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] srcBuffer;
|
|
||||||
delete[] dstBuffer;
|
|
||||||
|
|
||||||
// truncate to actual output
|
|
||||||
int numDestinationBytes = numDestinationFrames * numChannels * sizeof(AudioConstants::AudioSample);
|
|
||||||
_byteArray.resize(numDestinationBytes);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
int numChannels = _isStereo ? 2 : 1;
|
int numChannels = _isAmbisonic ? AudioConstants::AMBISONIC : (_isStereo ? AudioConstants::STEREO : AudioConstants::MONO);
|
||||||
AudioSRC resampler(sampleRate, AudioConstants::SAMPLE_RATE, numChannels);
|
AudioSRC resampler(sampleRate, AudioConstants::SAMPLE_RATE, numChannels);
|
||||||
|
|
||||||
// resize to max possible output
|
// resize to max possible output
|
||||||
|
|
|
@ -198,4 +198,109 @@ int AudioSRC::multirateFilter2_AVX2(const float* input0, const float* input1, fl
|
||||||
return outputFrames;
|
return outputFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AudioSRC::multirateFilter4_AVX2(const float* input0, const float* input1, const float* input2, const float* input3,
|
||||||
|
float* output0, float* output1, float* output2, float* output3, int inputFrames) {
|
||||||
|
int outputFrames = 0;
|
||||||
|
|
||||||
|
assert(_numTaps % 8 == 0); // SIMD8
|
||||||
|
|
||||||
|
if (_step == 0) { // rational
|
||||||
|
|
||||||
|
int32_t i = HI32(_offset);
|
||||||
|
|
||||||
|
while (i < inputFrames) {
|
||||||
|
|
||||||
|
const float* c0 = &_polyphaseFilter[_numTaps * _phase];
|
||||||
|
|
||||||
|
__m256 acc0 = _mm256_setzero_ps();
|
||||||
|
__m256 acc1 = _mm256_setzero_ps();
|
||||||
|
__m256 acc2 = _mm256_setzero_ps();
|
||||||
|
__m256 acc3 = _mm256_setzero_ps();
|
||||||
|
|
||||||
|
for (int j = 0; j < _numTaps; j += 8) {
|
||||||
|
|
||||||
|
//float coef = c0[j];
|
||||||
|
__m256 coef0 = _mm256_loadu_ps(&c0[j]);
|
||||||
|
|
||||||
|
//acc += input[i + j] * coef;
|
||||||
|
acc0 = _mm256_fmadd_ps(_mm256_loadu_ps(&input0[i + j]), coef0, acc0);
|
||||||
|
acc1 = _mm256_fmadd_ps(_mm256_loadu_ps(&input1[i + j]), coef0, acc1);
|
||||||
|
acc2 = _mm256_fmadd_ps(_mm256_loadu_ps(&input2[i + j]), coef0, acc2);
|
||||||
|
acc3 = _mm256_fmadd_ps(_mm256_loadu_ps(&input3[i + j]), coef0, acc3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// horizontal sum
|
||||||
|
acc0 = _mm256_hadd_ps(acc0, acc1);
|
||||||
|
acc2 = _mm256_hadd_ps(acc2, acc3);
|
||||||
|
acc0 = _mm256_hadd_ps(acc0, acc2);
|
||||||
|
__m128 t0 = _mm_add_ps(_mm256_castps256_ps128(acc0), _mm256_extractf128_ps(acc0, 1));
|
||||||
|
|
||||||
|
_mm_store_ss(&output0[outputFrames], t0);
|
||||||
|
_mm_store_ss(&output1[outputFrames], _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(0,0,0,1)));
|
||||||
|
_mm_store_ss(&output2[outputFrames], _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(0,0,0,2)));
|
||||||
|
_mm_store_ss(&output3[outputFrames], _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(0,0,0,3)));
|
||||||
|
outputFrames += 1;
|
||||||
|
|
||||||
|
i += _stepTable[_phase];
|
||||||
|
if (++_phase == _upFactor) {
|
||||||
|
_phase = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_offset = (int64_t)(i - inputFrames) << 32;
|
||||||
|
|
||||||
|
} else { // irrational
|
||||||
|
|
||||||
|
while (HI32(_offset) < inputFrames) {
|
||||||
|
|
||||||
|
int32_t i = HI32(_offset);
|
||||||
|
uint32_t f = LO32(_offset);
|
||||||
|
|
||||||
|
uint32_t phase = f >> SRC_FRACBITS;
|
||||||
|
float ftmp = (f & SRC_FRACMASK) * QFRAC_TO_FLOAT;
|
||||||
|
|
||||||
|
const float* c0 = &_polyphaseFilter[_numTaps * (phase + 0)];
|
||||||
|
const float* c1 = &_polyphaseFilter[_numTaps * (phase + 1)];
|
||||||
|
|
||||||
|
__m256 acc0 = _mm256_setzero_ps();
|
||||||
|
__m256 acc1 = _mm256_setzero_ps();
|
||||||
|
__m256 acc2 = _mm256_setzero_ps();
|
||||||
|
__m256 acc3 = _mm256_setzero_ps();
|
||||||
|
__m256 frac = _mm256_broadcast_ss(&ftmp);
|
||||||
|
|
||||||
|
for (int j = 0; j < _numTaps; j += 8) {
|
||||||
|
|
||||||
|
//float coef = c0[j] + frac * (c1[j] - c0[j]);
|
||||||
|
__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);
|
||||||
|
acc1 = _mm256_fmadd_ps(_mm256_loadu_ps(&input1[i + j]), coef0, acc1);
|
||||||
|
acc2 = _mm256_fmadd_ps(_mm256_loadu_ps(&input2[i + j]), coef0, acc2);
|
||||||
|
acc3 = _mm256_fmadd_ps(_mm256_loadu_ps(&input3[i + j]), coef0, acc3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// horizontal sum
|
||||||
|
acc0 = _mm256_hadd_ps(acc0, acc1);
|
||||||
|
acc2 = _mm256_hadd_ps(acc2, acc3);
|
||||||
|
acc0 = _mm256_hadd_ps(acc0, acc2);
|
||||||
|
__m128 t0 = _mm_add_ps(_mm256_castps256_ps128(acc0), _mm256_extractf128_ps(acc0, 1));
|
||||||
|
|
||||||
|
_mm_store_ss(&output0[outputFrames], t0);
|
||||||
|
_mm_store_ss(&output1[outputFrames], _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(0,0,0,1)));
|
||||||
|
_mm_store_ss(&output2[outputFrames], _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(0,0,0,2)));
|
||||||
|
_mm_store_ss(&output3[outputFrames], _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(0,0,0,3)));
|
||||||
|
outputFrames += 1;
|
||||||
|
|
||||||
|
_offset += _step;
|
||||||
|
}
|
||||||
|
_offset -= (int64_t)inputFrames << 32;
|
||||||
|
}
|
||||||
|
_mm256_zeroupper();
|
||||||
|
|
||||||
|
return outputFrames;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <udt/PacketHeaders.h>
|
#include <udt/PacketHeaders.h>
|
||||||
|
#include <PerfStat.h>
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
#include "AvatarLogging.h"
|
#include "AvatarLogging.h"
|
||||||
|
@ -98,6 +99,7 @@ AvatarSharedPointer AvatarHashMap::findAvatar(const QUuid& sessionUUID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarHashMap::processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
void AvatarHashMap::processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||||
|
PerformanceTimer perfTimer("receiveAvatar");
|
||||||
// enumerate over all of the avatars in this packet
|
// enumerate over all of the avatars in this packet
|
||||||
// only add them if mixerWeakPointer points to something (meaning that mixer is still around)
|
// only add them if mixerWeakPointer points to something (meaning that mixer is still around)
|
||||||
while (message->getBytesLeftToRead()) {
|
while (message->getBytesLeftToRead()) {
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
#include <QtOpenGL/QGLWidget>
|
#include <QtOpenGL/QGLWidget>
|
||||||
#include <QtGui/QImage>
|
#include <QtGui/QImage>
|
||||||
|
|
||||||
#if defined(Q_OS_MAC)
|
#if defined(Q_OS_MAC)
|
||||||
#include <OpenGL/CGLCurrent.h>
|
#include <OpenGL/CGLCurrent.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -44,6 +43,7 @@
|
||||||
#include <CursorManager.h>
|
#include <CursorManager.h>
|
||||||
|
|
||||||
#include "CompositorHelper.h"
|
#include "CompositorHelper.h"
|
||||||
|
#include "Logging.h"
|
||||||
|
|
||||||
const char* SRGB_TO_LINEAR_FRAG = R"SCRIBE(
|
const char* SRGB_TO_LINEAR_FRAG = R"SCRIBE(
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ public:
|
||||||
_context->makeCurrent();
|
_context->makeCurrent();
|
||||||
while (!_shutdown) {
|
while (!_shutdown) {
|
||||||
if (_pendingMainThreadOperation) {
|
if (_pendingMainThreadOperation) {
|
||||||
PROFILE_RANGE("MainThreadOp")
|
PROFILE_RANGE(displayPlugins, "MainThreadOp")
|
||||||
{
|
{
|
||||||
Lock lock(_mutex);
|
Lock lock(_mutex);
|
||||||
_context->doneCurrent();
|
_context->doneCurrent();
|
||||||
|
@ -203,7 +203,7 @@ public:
|
||||||
// Execute the frame and present it to the display device.
|
// Execute the frame and present it to the display device.
|
||||||
_context->makeCurrent();
|
_context->makeCurrent();
|
||||||
{
|
{
|
||||||
PROFILE_RANGE("PluginPresent")
|
PROFILE_RANGE(displayPlugins, "PluginPresent")
|
||||||
currentPlugin->present();
|
currentPlugin->present();
|
||||||
CHECK_GL_ERROR();
|
CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
@ -560,22 +560,22 @@ void OpenGLDisplayPlugin::compositeLayers() {
|
||||||
updateCompositeFramebuffer();
|
updateCompositeFramebuffer();
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("compositeScene", 0xff0077ff, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, "compositeScene", 0xff0077ff, (uint64_t)presentCount())
|
||||||
compositeScene();
|
compositeScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("compositeOverlay", 0xff0077ff, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, "compositeOverlay", 0xff0077ff, (uint64_t)presentCount())
|
||||||
compositeOverlay();
|
compositeOverlay();
|
||||||
}
|
}
|
||||||
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
auto compositorHelper = DependencyManager::get<CompositorHelper>();
|
||||||
if (compositorHelper->getReticleVisible()) {
|
if (compositorHelper->getReticleVisible()) {
|
||||||
PROFILE_RANGE_EX("compositePointer", 0xff0077ff, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, "compositePointer", 0xff0077ff, (uint64_t)presentCount())
|
||||||
compositePointer();
|
compositePointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("compositeExtra", 0xff0077ff, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, "compositeExtra", 0xff0077ff, (uint64_t)presentCount())
|
||||||
compositeExtra();
|
compositeExtra();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,12 +595,12 @@ void OpenGLDisplayPlugin::internalPresent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::present() {
|
void OpenGLDisplayPlugin::present() {
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xffffff00, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, __FUNCTION__, 0xffffff00, (uint64_t)presentCount())
|
||||||
updateFrameData();
|
updateFrameData();
|
||||||
incrementPresentCount();
|
incrementPresentCount();
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("recycle", 0xff00ff00, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, "recycle", 0xff00ff00, (uint64_t)presentCount())
|
||||||
_gpuContext->recycle();
|
_gpuContext->recycle();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -614,19 +614,19 @@ void OpenGLDisplayPlugin::present() {
|
||||||
_lastFrame = _currentFrame.get();
|
_lastFrame = _currentFrame.get();
|
||||||
});
|
});
|
||||||
// Execute the frame rendering commands
|
// Execute the frame rendering commands
|
||||||
PROFILE_RANGE_EX("execute", 0xff00ff00, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, "execute", 0xff00ff00, (uint64_t)presentCount())
|
||||||
_gpuContext->executeFrame(_currentFrame);
|
_gpuContext->executeFrame(_currentFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write all layers to a local framebuffer
|
// Write all layers to a local framebuffer
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("composite", 0xff00ffff, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, "composite", 0xff00ffff, (uint64_t)presentCount())
|
||||||
compositeLayers();
|
compositeLayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Take the composite framebuffer and send it to the output device
|
// Take the composite framebuffer and send it to the output device
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("internalPresent", 0xff00ffff, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, "internalPresent", 0xff00ffff, (uint64_t)presentCount())
|
||||||
internalPresent();
|
internalPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ float HmdDisplayPlugin::getLeftCenterPixel() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HmdDisplayPlugin::internalPresent() {
|
void HmdDisplayPlugin::internalPresent() {
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)presentCount())
|
PROFILE_RANGE_EX(displayPlugins, __FUNCTION__, 0xff00ff00, (uint64_t)presentCount())
|
||||||
|
|
||||||
// Composite together the scene, overlay and mouse cursor
|
// Composite together the scene, overlay and mouse cursor
|
||||||
hmdPresent();
|
hmdPresent();
|
||||||
|
|
|
@ -211,7 +211,7 @@ namespace render {
|
||||||
template <> void payloadRender(const RenderableModelEntityItemMeta::Pointer& payload, RenderArgs* args) {
|
template <> void payloadRender(const RenderableModelEntityItemMeta::Pointer& payload, RenderArgs* args) {
|
||||||
if (args) {
|
if (args) {
|
||||||
if (payload && payload->entity) {
|
if (payload && payload->entity) {
|
||||||
PROFILE_RANGE("MetaModelRender");
|
PROFILE_RANGE(renderlogging, "MetaModelRender");
|
||||||
payload->entity->render(args);
|
payload->entity->render(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1169,6 +1169,7 @@ void RenderableModelEntityItem::setJointTranslationsSet(const QVector<bool>& tra
|
||||||
|
|
||||||
|
|
||||||
void RenderableModelEntityItem::locationChanged(bool tellPhysics) {
|
void RenderableModelEntityItem::locationChanged(bool tellPhysics) {
|
||||||
|
PerformanceTimer pertTimer("locationChanged");
|
||||||
EntityItem::locationChanged(tellPhysics);
|
EntityItem::locationChanged(tellPhysics);
|
||||||
if (_model && _model->isActive()) {
|
if (_model && _model->isActive()) {
|
||||||
_model->setRotation(getRotation());
|
_model->setRotation(getRotation());
|
||||||
|
|
|
@ -321,7 +321,7 @@ FBXNode parseTextFBXNode(Tokenizer& tokenizer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FBXNode FBXReader::parseFBX(QIODevice* device) {
|
FBXNode FBXReader::parseFBX(QIODevice* device) {
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff0000ff, device);
|
PROFILE_RANGE_EX(modelformat, __FUNCTION__, 0xff0000ff, device);
|
||||||
// verify the prolog
|
// verify the prolog
|
||||||
const QByteArray BINARY_PROLOG = "Kaydara FBX Binary ";
|
const QByteArray BINARY_PROLOG = "Kaydara FBX Binary ";
|
||||||
if (device->peek(BINARY_PROLOG.size()) != BINARY_PROLOG) {
|
if (device->peek(BINARY_PROLOG.size()) != BINARY_PROLOG) {
|
||||||
|
|
|
@ -420,7 +420,7 @@ done:
|
||||||
|
|
||||||
|
|
||||||
FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, const QUrl& url) {
|
FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, const QUrl& url) {
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xffff0000, nullptr);
|
PROFILE_RANGE_EX(modelformat, __FUNCTION__, 0xffff0000, nullptr);
|
||||||
QBuffer buffer { &model };
|
QBuffer buffer { &model };
|
||||||
buffer.open(QIODevice::ReadOnly);
|
buffer.open(QIODevice::ReadOnly);
|
||||||
|
|
||||||
|
|
|
@ -11,4 +11,4 @@
|
||||||
|
|
||||||
#include "GLLogging.h"
|
#include "GLLogging.h"
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(glLogging, "hifi.glLogging")
|
Q_LOGGING_CATEGORY(glLogging, "hifi.gl")
|
||||||
|
|
|
@ -284,7 +284,7 @@ void OffscreenQmlSurface::render() {
|
||||||
GLuint texture = offscreenTextures.getNextTexture(_size);
|
GLuint texture = offscreenTextures.getNextTexture(_size);
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo);
|
||||||
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
|
glFramebufferTexture(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture, 0);
|
||||||
PROFILE_RANGE("qml_render->rendercontrol")
|
PROFILE_RANGE(glLogging, "qml_render->rendercontrol")
|
||||||
_renderControl->render();
|
_renderControl->render();
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture);
|
glBindTexture(GL_TEXTURE_2D, texture);
|
||||||
|
@ -622,7 +622,7 @@ void OffscreenQmlSurface::updateQuick() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_render) {
|
if (_render) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(glLogging, __FUNCTION__);
|
||||||
render();
|
render();
|
||||||
_render = false;
|
_render = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "GLTexture.h"
|
#include "GLTexture.h"
|
||||||
#include "GLShader.h"
|
#include "GLShader.h"
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
using namespace gpu::gl;
|
using namespace gpu::gl;
|
||||||
|
|
||||||
|
@ -199,7 +200,7 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
|
||||||
|
|
||||||
_inRenderTransferPass = true;
|
_inRenderTransferPass = true;
|
||||||
{ // Sync all the buffers
|
{ // Sync all the buffers
|
||||||
PROFILE_RANGE("syncGPUBuffer");
|
PROFILE_RANGE(gpugllogging, "syncGPUBuffer");
|
||||||
|
|
||||||
for (auto& cached : batch._buffers._items) {
|
for (auto& cached : batch._buffers._items) {
|
||||||
if (cached._data) {
|
if (cached._data) {
|
||||||
|
@ -209,7 +210,7 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Sync all the buffers
|
{ // Sync all the buffers
|
||||||
PROFILE_RANGE("syncCPUTransform");
|
PROFILE_RANGE(gpugllogging, "syncCPUTransform");
|
||||||
_transform._cameras.clear();
|
_transform._cameras.clear();
|
||||||
_transform._cameraOffsets.clear();
|
_transform._cameraOffsets.clear();
|
||||||
|
|
||||||
|
@ -241,7 +242,7 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // Sync the transform buffers
|
{ // Sync the transform buffers
|
||||||
PROFILE_RANGE("syncGPUTransform");
|
PROFILE_RANGE(gpugllogging, "syncGPUTransform");
|
||||||
transferTransformState(batch);
|
transferTransformState(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,7 +304,7 @@ void GLBackend::render(const Batch& batch) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE("Transfer");
|
PROFILE_RANGE(gpugllogging, "Transfer");
|
||||||
renderPassTransfer(batch);
|
renderPassTransfer(batch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,7 +314,7 @@ void GLBackend::render(const Batch& batch) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
PROFILE_RANGE(_stereo._enable ? "Render Stereo" : "Render");
|
PROFILE_RANGE(gpugllogging, _stereo._enable ? "Render Stereo" : "Render");
|
||||||
renderPassDraw(batch);
|
renderPassDraw(batch);
|
||||||
}
|
}
|
||||||
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
|
#ifdef GPU_STEREO_DRAWCALL_INSTANCED
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
#include "GLBackend.h"
|
#include "GLBackend.h"
|
||||||
#include "GLQuery.h"
|
#include "GLQuery.h"
|
||||||
|
#include "GLShared.h"
|
||||||
|
|
||||||
using namespace gpu;
|
using namespace gpu;
|
||||||
using namespace gpu::gl;
|
using namespace gpu::gl;
|
||||||
|
@ -27,7 +28,7 @@ void GLBackend::do_beginQuery(const Batch& batch, size_t paramOffset) {
|
||||||
auto query = batch._queries.get(batch._params[paramOffset]._uint);
|
auto query = batch._queries.get(batch._params[paramOffset]._uint);
|
||||||
GLQuery* glquery = syncGPUObject(*query);
|
GLQuery* glquery = syncGPUObject(*query);
|
||||||
if (glquery) {
|
if (glquery) {
|
||||||
PROFILE_RANGE_BEGIN(glquery->_profileRangeId, query->getName().c_str(), 0xFFFF7F00);
|
PROFILE_RANGE_BEGIN(gpugllogging, glquery->_profileRangeId, query->getName().c_str(), 0xFFFF7F00);
|
||||||
|
|
||||||
++_queryStage._rangeQueryDepth;
|
++_queryStage._rangeQueryDepth;
|
||||||
glGetInteger64v(GL_TIMESTAMP, (GLint64*)&glquery->_batchElapsedTime);
|
glGetInteger64v(GL_TIMESTAMP, (GLint64*)&glquery->_batchElapsedTime);
|
||||||
|
@ -61,7 +62,7 @@ void GLBackend::do_endQuery(const Batch& batch, size_t paramOffset) {
|
||||||
glGetInteger64v(GL_TIMESTAMP, &now);
|
glGetInteger64v(GL_TIMESTAMP, &now);
|
||||||
glquery->_batchElapsedTime = now - glquery->_batchElapsedTime;
|
glquery->_batchElapsedTime = now - glquery->_batchElapsedTime;
|
||||||
|
|
||||||
PROFILE_RANGE_END(glquery->_profileRangeId);
|
PROFILE_RANGE_END(gpugllogging, glquery->_profileRangeId);
|
||||||
|
|
||||||
(void)CHECK_GL_ERROR();
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <QtCore/QThread>
|
|
||||||
|
|
||||||
#include "../gl/GLTexelFormat.h"
|
#include "../gl/GLTexelFormat.h"
|
||||||
|
|
||||||
|
@ -123,7 +122,7 @@ void GL41Texture::transferMip(uint16_t mipLevel, uint8_t face) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void GL41Texture::startTransfer() {
|
void GL41Texture::startTransfer() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(gpugllogging, __FUNCTION__);
|
||||||
Parent::startTransfer();
|
Parent::startTransfer();
|
||||||
|
|
||||||
glBindTexture(_target, _id);
|
glBindTexture(_target, _id);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QThread>
|
#include <QtCore/QThread>
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
|
||||||
|
@ -757,6 +758,9 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
|
||||||
if(width != cubeTexture.getHeight()) {
|
if(width != cubeTexture.getHeight()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROFILE_RANGE(gpulogging, "sphericalHarmonicsFromTexture");
|
||||||
|
|
||||||
const uint sqOrder = order*order;
|
const uint sqOrder = order*order;
|
||||||
|
|
||||||
// allocate memory for calculations
|
// allocate memory for calculations
|
||||||
|
@ -788,6 +792,7 @@ bool sphericalHarmonicsFromTexture(const gpu::Texture& cubeTexture, std::vector<
|
||||||
|
|
||||||
// for each face of cube texture
|
// for each face of cube texture
|
||||||
for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) {
|
for(int face=0; face < gpu::Texture::NUM_CUBE_FACES; face++) {
|
||||||
|
PROFILE_RANGE(gpulogging, "ProcessFace");
|
||||||
|
|
||||||
auto numComponents = cubeTexture.accessStoredMipFace(0,face)->getFormat().getScalarCount();
|
auto numComponents = cubeTexture.accessStoredMipFace(0,face)->getFormat().getScalarCount();
|
||||||
auto data = cubeTexture.accessStoredMipFace(0,face)->readData();
|
auto data = cubeTexture.accessStoredMipFace(0,face)->readData();
|
||||||
|
@ -995,4 +1000,4 @@ Texture::ExternalUpdates Texture::getUpdates() const {
|
||||||
_externalUpdates.swap(result);
|
_externalUpdates.swap(result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <QThreadPool>
|
#include <QThreadPool>
|
||||||
|
|
||||||
#include "ModelNetworkingLogging.h"
|
#include "ModelNetworkingLogging.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
#include <StatTracker.h>
|
||||||
|
|
||||||
class GeometryReader;
|
class GeometryReader;
|
||||||
|
|
||||||
|
@ -39,6 +41,8 @@ class GeometryMappingResource : public GeometryResource {
|
||||||
public:
|
public:
|
||||||
GeometryMappingResource(const QUrl& url) : GeometryResource(url) {};
|
GeometryMappingResource(const QUrl& url) : GeometryResource(url) {};
|
||||||
|
|
||||||
|
QString getType() const override { return "GeometryMapping"; }
|
||||||
|
|
||||||
virtual void downloadFinished(const QByteArray& data) override;
|
virtual void downloadFinished(const QByteArray& data) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
@ -50,6 +54,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void GeometryMappingResource::downloadFinished(const QByteArray& data) {
|
void GeometryMappingResource::downloadFinished(const QByteArray& data) {
|
||||||
|
PROFILE_ASYNC_BEGIN(modelnetworking, "GeometryMappingResource::downloadFinished", _url.toString(),
|
||||||
|
{ { "url", _url.toString() } });
|
||||||
|
|
||||||
auto mapping = FSTReader::readMapping(data);
|
auto mapping = FSTReader::readMapping(data);
|
||||||
|
|
||||||
QString filename = mapping.value("filename").toString();
|
QString filename = mapping.value("filename").toString();
|
||||||
|
@ -113,6 +120,7 @@ void GeometryMappingResource::onGeometryMappingLoaded(bool success) {
|
||||||
disconnect(_connection); // FIXME Should not have to do this
|
disconnect(_connection); // FIXME Should not have to do this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROFILE_ASYNC_END(modelnetworking, "GeometryMappingResource::downloadFinished", _url.toString());
|
||||||
finishedLoading(success);
|
finishedLoading(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,8 +128,10 @@ class GeometryReader : public QRunnable {
|
||||||
public:
|
public:
|
||||||
GeometryReader(QWeakPointer<Resource>& resource, const QUrl& url, const QVariantHash& mapping,
|
GeometryReader(QWeakPointer<Resource>& resource, const QUrl& url, const QVariantHash& mapping,
|
||||||
const QByteArray& data) :
|
const QByteArray& data) :
|
||||||
_resource(resource), _url(url), _mapping(mapping), _data(data) {}
|
_resource(resource), _url(url), _mapping(mapping), _data(data) {
|
||||||
virtual ~GeometryReader() = default;
|
|
||||||
|
DependencyManager::get<StatTracker>()->incrementStat("PendingProcessing");
|
||||||
|
}
|
||||||
|
|
||||||
virtual void run() override;
|
virtual void run() override;
|
||||||
|
|
||||||
|
@ -133,6 +143,9 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
void GeometryReader::run() {
|
void GeometryReader::run() {
|
||||||
|
DependencyManager::get<StatTracker>()->decrementStat("PendingProcessing");
|
||||||
|
CounterStat counter("Processing");
|
||||||
|
PROFILE_RANGE_EX(modelnetworking, "GeometryReader::run", 0xFF00FF00, 0, { { "url", _url.toString() } });
|
||||||
auto originalPriority = QThread::currentThread()->priority();
|
auto originalPriority = QThread::currentThread()->priority();
|
||||||
if (originalPriority == QThread::InheritPriority) {
|
if (originalPriority == QThread::InheritPriority) {
|
||||||
originalPriority = QThread::NormalPriority;
|
originalPriority = QThread::NormalPriority;
|
||||||
|
@ -197,6 +210,8 @@ public:
|
||||||
GeometryDefinitionResource(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl) :
|
GeometryDefinitionResource(const QUrl& url, const QVariantHash& mapping, const QUrl& textureBaseUrl) :
|
||||||
GeometryResource(url, resolveTextureBaseUrl(url, textureBaseUrl)), _mapping(mapping) {}
|
GeometryResource(url, resolveTextureBaseUrl(url, textureBaseUrl)), _mapping(mapping) {}
|
||||||
|
|
||||||
|
QString getType() const override { return "GeometryDefinition"; }
|
||||||
|
|
||||||
virtual void downloadFinished(const QByteArray& data) override;
|
virtual void downloadFinished(const QByteArray& data) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
class NetworkShader : public Resource {
|
class NetworkShader : public Resource {
|
||||||
public:
|
public:
|
||||||
NetworkShader(const QUrl& url);
|
NetworkShader(const QUrl& url);
|
||||||
|
|
||||||
|
QString getType() const override { return "NetworkShader"; }
|
||||||
|
|
||||||
virtual void downloadFinished(const QByteArray& data) override;
|
virtual void downloadFinished(const QByteArray& data) override;
|
||||||
|
|
||||||
QString _source;
|
QString _source;
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
|
||||||
#include "ModelNetworkingLogging.h"
|
#include "ModelNetworkingLogging.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
#include <StatTracker.h>
|
||||||
|
|
||||||
TextureCache::TextureCache() {
|
TextureCache::TextureCache() {
|
||||||
setUnusedResourceCacheSize(0);
|
setUnusedResourceCacheSize(0);
|
||||||
|
@ -331,6 +333,7 @@ ImageReader::ImageReader(const QWeakPointer<Resource>& resource, const QByteArra
|
||||||
outFile.close();
|
outFile.close();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
DependencyManager::get<StatTracker>()->incrementStat("PendingProcessing");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageReader::listSupportedImageFormats() {
|
void ImageReader::listSupportedImageFormats() {
|
||||||
|
@ -342,7 +345,11 @@ void ImageReader::listSupportedImageFormats() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageReader::run() {
|
void ImageReader::run() {
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xffff0000, nullptr);
|
DependencyManager::get<StatTracker>()->decrementStat("PendingProcessing");
|
||||||
|
|
||||||
|
CounterStat counter("Processing");
|
||||||
|
|
||||||
|
PROFILE_RANGE_EX(modelnetworking, __FUNCTION__, 0xffff0000, 0, { { "url", _url.toString() } });
|
||||||
auto originalPriority = QThread::currentThread()->priority();
|
auto originalPriority = QThread::currentThread()->priority();
|
||||||
if (originalPriority == QThread::InheritPriority) {
|
if (originalPriority == QThread::InheritPriority) {
|
||||||
originalPriority = QThread::NormalPriority;
|
originalPriority = QThread::NormalPriority;
|
||||||
|
@ -356,7 +363,6 @@ void ImageReader::run() {
|
||||||
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
qCWarning(modelnetworking) << "Abandoning load of" << _url << "; could not get strong ref";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
listSupportedImageFormats();
|
listSupportedImageFormats();
|
||||||
|
|
||||||
// Help the QImage loader by extracting the image file format from the url filename ext.
|
// Help the QImage loader by extracting the image file format from the url filename ext.
|
||||||
|
@ -378,7 +384,6 @@ void ImageReader::run() {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu::TexturePointer texture = nullptr;
|
gpu::TexturePointer texture = nullptr;
|
||||||
{
|
{
|
||||||
// Double-check the resource still exists between long operations.
|
// Double-check the resource still exists between long operations.
|
||||||
|
@ -390,7 +395,7 @@ void ImageReader::run() {
|
||||||
|
|
||||||
auto url = _url.toString().toStdString();
|
auto url = _url.toString().toStdString();
|
||||||
|
|
||||||
PROFILE_RANGE_EX(__FUNCTION__"::textureLoader", 0xffffff00, nullptr);
|
PROFILE_RANGE_EX(modelnetworking, __FUNCTION__, 0xffffff00, 0);
|
||||||
texture.reset(resource.dynamicCast<NetworkTexture>()->getTextureLoader()(image, url));
|
texture.reset(resource.dynamicCast<NetworkTexture>()->getTextureLoader()(image, url));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,10 +63,13 @@ public:
|
||||||
NetworkTexture(const QUrl& url, Type type, const QByteArray& content);
|
NetworkTexture(const QUrl& url, Type type, const QByteArray& content);
|
||||||
NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content);
|
NetworkTexture(const QUrl& url, const TextureLoaderFunc& textureLoader, const QByteArray& content);
|
||||||
|
|
||||||
|
QString getType() const override { return "NetworkTexture"; }
|
||||||
|
|
||||||
int getOriginalWidth() const { return _originalWidth; }
|
int getOriginalWidth() const { return _originalWidth; }
|
||||||
int getOriginalHeight() const { return _originalHeight; }
|
int getOriginalHeight() const { return _originalHeight; }
|
||||||
int getWidth() const { return _width; }
|
int getWidth() const { return _width; }
|
||||||
int getHeight() const { return _height; }
|
int getHeight() const { return _height; }
|
||||||
|
Type getTextureType() const { return _type; }
|
||||||
|
|
||||||
TextureLoaderFunc getTextureLoader() const;
|
TextureLoaderFunc getTextureLoader() const;
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <Profile.h>
|
||||||
|
|
||||||
#include "ModelLogging.h"
|
#include "ModelLogging.h"
|
||||||
|
|
||||||
using namespace model;
|
using namespace model;
|
||||||
|
@ -744,6 +746,8 @@ const CubeLayout CubeLayout::CUBEMAP_LAYOUTS[] = {
|
||||||
const int CubeLayout::NUM_CUBEMAP_LAYOUTS = sizeof(CubeLayout::CUBEMAP_LAYOUTS) / sizeof(CubeLayout);
|
const int CubeLayout::NUM_CUBEMAP_LAYOUTS = sizeof(CubeLayout::CUBEMAP_LAYOUTS) / sizeof(CubeLayout);
|
||||||
|
|
||||||
gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcImage, const std::string& srcImageName, bool isLinear, bool doCompress, bool generateMips, bool generateIrradiance) {
|
gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcImage, const std::string& srcImageName, bool isLinear, bool doCompress, bool generateMips, bool generateIrradiance) {
|
||||||
|
PROFILE_RANGE(modelLog, "processCubeTextureColorFromImage");
|
||||||
|
|
||||||
gpu::Texture* theTexture = nullptr;
|
gpu::Texture* theTexture = nullptr;
|
||||||
if ((srcImage.width() > 0) && (srcImage.height() > 0)) {
|
if ((srcImage.width() > 0) && (srcImage.height() > 0)) {
|
||||||
QImage image = processSourceImage(srcImage, true);
|
QImage image = processSourceImage(srcImage, true);
|
||||||
|
@ -801,11 +805,13 @@ gpu::Texture* TextureUsage::processCubeTextureColorFromImage(const QImage& srcIm
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generateMips) {
|
if (generateMips) {
|
||||||
|
PROFILE_RANGE(modelLog, "generateMips");
|
||||||
theTexture->autoGenerateMips(-1);
|
theTexture->autoGenerateMips(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate irradiance while we are at it
|
// Generate irradiance while we are at it
|
||||||
if (generateIrradiance) {
|
if (generateIrradiance) {
|
||||||
|
PROFILE_RANGE(modelLog, "generateIrradiance");
|
||||||
theTexture->generateIrradiance();
|
theTexture->generateIrradiance();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -604,7 +604,7 @@ bool AssetClient::cancelGetAssetRequest(MessageID id) {
|
||||||
for (auto& kv : _pendingRequests) {
|
for (auto& kv : _pendingRequests) {
|
||||||
auto& messageCallbackMap = kv.second;
|
auto& messageCallbackMap = kv.second;
|
||||||
auto requestIt = messageCallbackMap.find(id);
|
auto requestIt = messageCallbackMap.find(id);
|
||||||
if (requestIt != kv.second.end()) {
|
if (requestIt != messageCallbackMap.end()) {
|
||||||
|
|
||||||
auto& message = requestIt->second.message;
|
auto& message = requestIt->second.message;
|
||||||
if (message) {
|
if (message) {
|
||||||
|
|
|
@ -19,8 +19,12 @@
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
#include "NodeList.h"
|
#include "NodeList.h"
|
||||||
#include "ResourceCache.h"
|
#include "ResourceCache.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
|
static int requestID = 0;
|
||||||
|
|
||||||
AssetRequest::AssetRequest(const QString& hash) :
|
AssetRequest::AssetRequest(const QString& hash) :
|
||||||
|
_requestID(++requestID),
|
||||||
_hash(hash)
|
_hash(hash)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ signals:
|
||||||
void progress(qint64 totalReceived, qint64 total);
|
void progress(qint64 totalReceived, qint64 total);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int _requestID;
|
||||||
State _state = NotStarted;
|
State _state = NotStarted;
|
||||||
Error _error = NoError;
|
Error _error = NoError;
|
||||||
AssetInfo _info;
|
AssetInfo _info;
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#include "AssetUtils.h"
|
#include "AssetUtils.h"
|
||||||
#include "MappingRequest.h"
|
#include "MappingRequest.h"
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
#include <Profile.h>
|
||||||
|
|
||||||
static const int DOWNLOAD_PROGRESS_LOG_INTERVAL_SECONDS = 5;
|
static const int DOWNLOAD_PROGRESS_LOG_INTERVAL_SECONDS = 5;
|
||||||
|
|
||||||
|
@ -27,12 +29,14 @@ AssetResourceRequest::AssetResourceRequest(const QUrl& url) :
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetResourceRequest::~AssetResourceRequest() {
|
AssetResourceRequest::~AssetResourceRequest() {
|
||||||
if (_assetMappingRequest) {
|
if (_assetRequest || _assetMappingRequest) {
|
||||||
_assetMappingRequest->deleteLater();
|
if (_assetMappingRequest) {
|
||||||
}
|
_assetMappingRequest->deleteLater();
|
||||||
|
}
|
||||||
if (_assetRequest) {
|
|
||||||
_assetRequest->deleteLater();
|
if (_assetRequest) {
|
||||||
|
_assetRequest->deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +112,6 @@ void AssetResourceRequest::requestMappingForPath(const AssetPath& path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetResourceRequest::requestHash(const AssetHash& hash) {
|
void AssetResourceRequest::requestHash(const AssetHash& hash) {
|
||||||
|
|
||||||
// Make request to atp
|
// Make request to atp
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
_assetRequest = assetClient->createRequest(hash);
|
_assetRequest = assetClient->createRequest(hash);
|
||||||
|
@ -118,7 +121,7 @@ void AssetResourceRequest::requestHash(const AssetHash& hash) {
|
||||||
Q_ASSERT(_state == InProgress);
|
Q_ASSERT(_state == InProgress);
|
||||||
Q_ASSERT(req == _assetRequest);
|
Q_ASSERT(req == _assetRequest);
|
||||||
Q_ASSERT(req->getState() == AssetRequest::Finished);
|
Q_ASSERT(req->getState() == AssetRequest::Finished);
|
||||||
|
|
||||||
switch (req->getError()) {
|
switch (req->getError()) {
|
||||||
case AssetRequest::Error::NoError:
|
case AssetRequest::Error::NoError:
|
||||||
_data = req->getData();
|
_data = req->getData();
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <BuildInfo.h>
|
#include <BuildInfo.h>
|
||||||
#include "Assignment.h"
|
#include "Assignment.h"
|
||||||
#include <QtCore/QStandardPaths>
|
#include <QtCore/QStandardPaths>
|
||||||
|
#include <QtCore/QDir>
|
||||||
|
|
||||||
Assignment::Type Assignment::typeForNodeType(NodeType_t nodeType) {
|
Assignment::Type Assignment::typeForNodeType(NodeType_t nodeType) {
|
||||||
switch (nodeType) {
|
switch (nodeType) {
|
||||||
|
@ -51,7 +52,7 @@ Assignment::Assignment() :
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Assignment::Assignment(Assignment::Command command, Assignment::Type type, const QString& pool, Assignment::Location location) :
|
Assignment::Assignment(Assignment::Command command, Assignment::Type type, const QString& pool, Assignment::Location location, QString dataDirectory) :
|
||||||
_uuid(),
|
_uuid(),
|
||||||
_command(command),
|
_command(command),
|
||||||
_type(type),
|
_type(type),
|
||||||
|
@ -60,7 +61,8 @@ Assignment::Assignment(Assignment::Command command, Assignment::Type type, const
|
||||||
_payload(),
|
_payload(),
|
||||||
_isStatic(false),
|
_isStatic(false),
|
||||||
_walletUUID(),
|
_walletUUID(),
|
||||||
_nodeVersion()
|
_nodeVersion(),
|
||||||
|
_dataDirectory(dataDirectory)
|
||||||
{
|
{
|
||||||
if (_command == Assignment::CreateCommand) {
|
if (_command == Assignment::CreateCommand) {
|
||||||
// this is a newly created assignment, generate a random UUID
|
// this is a newly created assignment, generate a random UUID
|
||||||
|
|
|
@ -55,7 +55,8 @@ public:
|
||||||
Assignment(Assignment::Command command,
|
Assignment(Assignment::Command command,
|
||||||
Assignment::Type type,
|
Assignment::Type type,
|
||||||
const QString& pool = emptyPool,
|
const QString& pool = emptyPool,
|
||||||
Assignment::Location location = Assignment::LocalLocation);
|
Assignment::Location location = Assignment::LocalLocation,
|
||||||
|
QString dataDirectory = QString());
|
||||||
Assignment(const Assignment& otherAssignment);
|
Assignment(const Assignment& otherAssignment);
|
||||||
Assignment& operator=(const Assignment &rhsAssignment);
|
Assignment& operator=(const Assignment &rhsAssignment);
|
||||||
|
|
||||||
|
@ -103,6 +104,7 @@ protected:
|
||||||
bool _isStatic; /// defines if this assignment needs to be re-queued in the domain-server if it stops being fulfilled
|
bool _isStatic; /// defines if this assignment needs to be re-queued in the domain-server if it stops being fulfilled
|
||||||
QUuid _walletUUID; /// the UUID for the wallet that should be paid for this assignment
|
QUuid _walletUUID; /// the UUID for the wallet that should be paid for this assignment
|
||||||
QString _nodeVersion;
|
QString _nodeVersion;
|
||||||
|
QString _dataDirectory;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint qHash(const Assignment::Type& key, uint seed);
|
uint qHash(const Assignment::Type& key, uint seed);
|
||||||
|
|
|
@ -109,6 +109,10 @@ void HifiSockAddr::handleLookupResult(const QHostInfo& hostInfo) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString HifiSockAddr::toString() const {
|
||||||
|
return _address.toString() + ":" + QString::number(_port);
|
||||||
|
}
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const HifiSockAddr& sockAddr) {
|
QDebug operator<<(QDebug debug, const HifiSockAddr& sockAddr) {
|
||||||
debug.nospace() << sockAddr._address.toString().toLocal8Bit().constData() << ":" << sockAddr._port;
|
debug.nospace() << sockAddr._address.toString().toLocal8Bit().constData() << ":" << sockAddr._port;
|
||||||
return debug.space();
|
return debug.space();
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
static int packSockAddr(unsigned char* packetData, const HifiSockAddr& packSockAddr);
|
static int packSockAddr(unsigned char* packetData, const HifiSockAddr& packSockAddr);
|
||||||
static int unpackSockAddr(const unsigned char* packetData, HifiSockAddr& unpackDestSockAddr);
|
static int unpackSockAddr(const unsigned char* packetData, HifiSockAddr& unpackDestSockAddr);
|
||||||
|
|
||||||
|
QString toString() const;
|
||||||
|
|
||||||
friend QDebug operator<<(QDebug debug, const HifiSockAddr& sockAddr);
|
friend QDebug operator<<(QDebug debug, const HifiSockAddr& sockAddr);
|
||||||
friend QDataStream& operator<<(QDataStream& dataStream, const HifiSockAddr& sockAddr);
|
friend QDataStream& operator<<(QDataStream& dataStream, const HifiSockAddr& sockAddr);
|
||||||
friend QDataStream& operator>>(QDataStream& dataStream, HifiSockAddr& sockAddr);
|
friend QDataStream& operator>>(QDataStream& dataStream, HifiSockAddr& sockAddr);
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "HifiSockAddr.h"
|
#include "HifiSockAddr.h"
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
#include "udt/Packet.h"
|
#include "udt/Packet.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
static Setting::Handle<quint16> LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0);
|
static Setting::Handle<quint16> LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0);
|
||||||
|
|
||||||
|
@ -1116,7 +1117,6 @@ void LimitedNodeList::flagTimeForConnectionStep(ConnectionStep connectionStep) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LimitedNodeList::flagTimeForConnectionStep(ConnectionStep connectionStep, quint64 timestamp) {
|
void LimitedNodeList::flagTimeForConnectionStep(ConnectionStep connectionStep, quint64 timestamp) {
|
||||||
|
|
||||||
if (connectionStep == ConnectionStep::LookupAddress) {
|
if (connectionStep == ConnectionStep::LookupAddress) {
|
||||||
QWriteLocker writeLock(&_connectionTimeLock);
|
QWriteLocker writeLock(&_connectionTimeLock);
|
||||||
|
|
||||||
|
|
|
@ -103,8 +103,7 @@ public:
|
||||||
ReceiveFirstAudioPacket
|
ReceiveFirstAudioPacket
|
||||||
};
|
};
|
||||||
|
|
||||||
Q_ENUMS(ConnectionStep);
|
Q_ENUM(ConnectionStep);
|
||||||
|
|
||||||
const QUuid& getSessionUUID() const { return _sessionUUID; }
|
const QUuid& getSessionUUID() const { return _sessionUUID; }
|
||||||
void setSessionUUID(const QUuid& sessionUUID);
|
void setSessionUUID(const QUuid& sessionUUID);
|
||||||
|
|
||||||
|
|
|
@ -12,5 +12,6 @@
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(networking, "hifi.networking")
|
Q_LOGGING_CATEGORY(networking, "hifi.networking")
|
||||||
|
Q_LOGGING_CATEGORY(resourceLog, "hifi.networking.resource")
|
||||||
Q_LOGGING_CATEGORY(asset_client, "hifi.networking.asset_client")
|
Q_LOGGING_CATEGORY(asset_client, "hifi.networking.asset_client")
|
||||||
Q_LOGGING_CATEGORY(messages_client, "hifi.networking.messages_client")
|
Q_LOGGING_CATEGORY(messages_client, "hifi.networking.messages_client")
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(resourceLog)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(networking)
|
Q_DECLARE_LOGGING_CATEGORY(networking)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(asset_client)
|
Q_DECLARE_LOGGING_CATEGORY(asset_client)
|
||||||
Q_DECLARE_LOGGING_CATEGORY(messages_client)
|
Q_DECLARE_LOGGING_CATEGORY(messages_client)
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "BandwidthRecorder.h"
|
#include "BandwidthRecorder.h"
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
#include "NodeType.h"
|
||||||
|
|
||||||
|
|
||||||
NetworkPeer::NetworkPeer(QObject* parent) :
|
NetworkPeer::NetworkPeer(QObject* parent) :
|
||||||
|
@ -156,6 +158,7 @@ void NetworkPeer::activateMatchingOrNewSymmetricSocket(const HifiSockAddr& match
|
||||||
}
|
}
|
||||||
|
|
||||||
void NetworkPeer::softReset() {
|
void NetworkPeer::softReset() {
|
||||||
|
qDebug() << "Soft reset ";
|
||||||
// a soft reset should clear the sockets and reset the number of connection attempts
|
// a soft reset should clear the sockets and reset the number of connection attempts
|
||||||
_localSocket.clear();
|
_localSocket.clear();
|
||||||
_publicSocket.clear();
|
_publicSocket.clear();
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
#include "udt/PacketHeaders.h"
|
#include "udt/PacketHeaders.h"
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
const int KEEPALIVE_PING_INTERVAL_MS = 1000;
|
const int KEEPALIVE_PING_INTERVAL_MS = 1000;
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "NodeList.h"
|
#include "NodeList.h"
|
||||||
|
|
||||||
#include "ResourceCache.h"
|
#include "ResourceCache.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
#include <Profile.h>
|
||||||
|
|
||||||
#define clamp(x, min, max) (((x) < (min)) ? (min) :\
|
#define clamp(x, min, max) (((x) < (min)) ? (min) :\
|
||||||
(((x) > (max)) ? (max) :\
|
(((x) > (max)) ? (max) :\
|
||||||
|
@ -495,11 +497,12 @@ const int DEFAULT_REQUEST_LIMIT = 10;
|
||||||
int ResourceCache::_requestLimit = DEFAULT_REQUEST_LIMIT;
|
int ResourceCache::_requestLimit = DEFAULT_REQUEST_LIMIT;
|
||||||
int ResourceCache::_requestsActive = 0;
|
int ResourceCache::_requestsActive = 0;
|
||||||
|
|
||||||
|
static int requestID = 0;
|
||||||
|
|
||||||
Resource::Resource(const QUrl& url) :
|
Resource::Resource(const QUrl& url) :
|
||||||
_url(url),
|
_url(url),
|
||||||
_activeUrl(url),
|
_activeUrl(url),
|
||||||
_request(nullptr) {
|
_requestID(++requestID) {
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,20 +650,24 @@ void Resource::reinsert() {
|
||||||
|
|
||||||
void Resource::makeRequest() {
|
void Resource::makeRequest() {
|
||||||
if (_request) {
|
if (_request) {
|
||||||
|
PROFILE_ASYNC_END(resourceLog, "Resource:" + getType(), QString::number(_requestID));
|
||||||
_request->disconnect();
|
_request->disconnect();
|
||||||
_request->deleteLater();
|
_request->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROFILE_ASYNC_BEGIN(resourceLog, "Resource:" + getType(), QString::number(_requestID), { { "url", _url.toString() }, { "activeURL", _activeUrl.toString() } });
|
||||||
|
|
||||||
_request = ResourceManager::createResourceRequest(this, _activeUrl);
|
_request = ResourceManager::createResourceRequest(this, _activeUrl);
|
||||||
|
|
||||||
if (!_request) {
|
if (!_request) {
|
||||||
qCDebug(networking).noquote() << "Failed to get request for" << _url.toDisplayString();
|
qCDebug(networking).noquote() << "Failed to get request for" << _url.toDisplayString();
|
||||||
ResourceCache::requestCompleted(_self);
|
ResourceCache::requestCompleted(_self);
|
||||||
finishedLoading(false);
|
finishedLoading(false);
|
||||||
|
PROFILE_ASYNC_END(resourceLog, "Resource:" + getType(), QString::number(_requestID));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(networking).noquote() << "Starting request for:" << _url.toDisplayString();
|
qCDebug(resourceLog).noquote() << "Starting request for:" << _url.toDisplayString();
|
||||||
emit loading();
|
emit loading();
|
||||||
|
|
||||||
connect(_request, &ResourceRequest::progress, this, &Resource::onProgress);
|
connect(_request, &ResourceRequest::progress, this, &Resource::onProgress);
|
||||||
|
@ -681,6 +688,11 @@ void Resource::handleDownloadProgress(uint64_t bytesReceived, uint64_t bytesTota
|
||||||
void Resource::handleReplyFinished() {
|
void Resource::handleReplyFinished() {
|
||||||
Q_ASSERT_X(_request, "Resource::handleReplyFinished", "Request should not be null while in handleReplyFinished");
|
Q_ASSERT_X(_request, "Resource::handleReplyFinished", "Request should not be null while in handleReplyFinished");
|
||||||
|
|
||||||
|
PROFILE_ASYNC_END(resourceLog, "Resource:" + getType(), QString::number(_requestID), {
|
||||||
|
{ "from_cache", _request->loadedFromCache() },
|
||||||
|
{ "size_mb", _bytesTotal / 1000000.0 }
|
||||||
|
});
|
||||||
|
|
||||||
setSize(_bytesTotal);
|
setSize(_bytesTotal);
|
||||||
|
|
||||||
if (!_request || _request != sender()) {
|
if (!_request || _request != sender()) {
|
||||||
|
|
|
@ -342,6 +342,8 @@ public:
|
||||||
|
|
||||||
Resource(const QUrl& url);
|
Resource(const QUrl& url);
|
||||||
~Resource();
|
~Resource();
|
||||||
|
|
||||||
|
virtual QString getType() const { return "Resource"; }
|
||||||
|
|
||||||
/// Returns the key last used to identify this resource in the unused map.
|
/// Returns the key last used to identify this resource in the unused map.
|
||||||
int getLRUKey() const { return _lruKey; }
|
int getLRUKey() const { return _lruKey; }
|
||||||
|
@ -461,6 +463,7 @@ private:
|
||||||
bool isInScript() const { return _isInScript; }
|
bool isInScript() const { return _isInScript; }
|
||||||
void setInScript(bool isInScript) { _isInScript = isInScript; }
|
void setInScript(bool isInScript) { _isInScript = isInScript; }
|
||||||
|
|
||||||
|
int _requestID;
|
||||||
ResourceRequest* _request{ nullptr };
|
ResourceRequest* _request{ nullptr };
|
||||||
int _lruKey{ 0 };
|
int _lruKey{ 0 };
|
||||||
QTimer* _replyTimer{ nullptr };
|
QTimer* _replyTimer{ nullptr };
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "Packet.h"
|
#include "Packet.h"
|
||||||
#include "PacketList.h"
|
#include "PacketList.h"
|
||||||
#include "Socket.h"
|
#include "Socket.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
using namespace udt;
|
using namespace udt;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
using ControlPacketPointer = std::unique_ptr<ControlPacket>;
|
using ControlPacketPointer = std::unique_ptr<ControlPacket>;
|
||||||
|
|
||||||
Connection(Socket* parentSocket, HifiSockAddr destination, std::unique_ptr<CongestionControl> congestionControl);
|
Connection(Socket* parentSocket, HifiSockAddr destination, std::unique_ptr<CongestionControl> congestionControl);
|
||||||
~Connection();
|
virtual ~Connection();
|
||||||
|
|
||||||
void sendReliablePacket(std::unique_ptr<Packet> packet);
|
void sendReliablePacket(std::unique_ptr<Packet> packet);
|
||||||
void sendReliablePacketList(std::unique_ptr<PacketList> packet);
|
void sendReliablePacketList(std::unique_ptr<PacketList> packet);
|
||||||
|
|
|
@ -30,6 +30,8 @@
|
||||||
#include "PacketList.h"
|
#include "PacketList.h"
|
||||||
#include "../UserActivityLogger.h"
|
#include "../UserActivityLogger.h"
|
||||||
#include "Socket.h"
|
#include "Socket.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
#include <Profile.h>
|
||||||
|
|
||||||
using namespace udt;
|
using namespace udt;
|
||||||
using namespace std::chrono;
|
using namespace std::chrono;
|
||||||
|
@ -84,6 +86,7 @@ SendQueue::SendQueue(Socket* socket, HifiSockAddr dest) :
|
||||||
_socket(socket),
|
_socket(socket),
|
||||||
_destination(dest)
|
_destination(dest)
|
||||||
{
|
{
|
||||||
|
PROFILE_ASYNC_BEGIN(networking, "SendQueue", _destination.toString());
|
||||||
|
|
||||||
// setup psuedo-random number generation for all instances of SendQueue
|
// setup psuedo-random number generation for all instances of SendQueue
|
||||||
static std::random_device rd;
|
static std::random_device rd;
|
||||||
|
@ -102,6 +105,10 @@ SendQueue::SendQueue(Socket* socket, HifiSockAddr dest) :
|
||||||
_lastReceiverResponse = QDateTime::currentMSecsSinceEpoch();
|
_lastReceiverResponse = QDateTime::currentMSecsSinceEpoch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SendQueue::~SendQueue() {
|
||||||
|
PROFILE_ASYNC_END(networking, "SendQueue", _destination.toString());
|
||||||
|
}
|
||||||
|
|
||||||
void SendQueue::queuePacket(std::unique_ptr<Packet> packet) {
|
void SendQueue::queuePacket(std::unique_ptr<Packet> packet) {
|
||||||
_packets.queuePacket(std::move(packet));
|
_packets.queuePacket(std::move(packet));
|
||||||
|
|
||||||
|
@ -220,6 +227,7 @@ void SendQueue::sendHandshake() {
|
||||||
if (!_hasReceivedHandshakeACK) {
|
if (!_hasReceivedHandshakeACK) {
|
||||||
// we haven't received a handshake ACK from the client, send another now
|
// we haven't received a handshake ACK from the client, send another now
|
||||||
auto handshakePacket = ControlPacket::create(ControlPacket::Handshake, sizeof(SequenceNumber));
|
auto handshakePacket = ControlPacket::create(ControlPacket::Handshake, sizeof(SequenceNumber));
|
||||||
|
PROFILE_ASYNC_BEGIN(networking, "SendQueue:Handshake", _destination.toString());
|
||||||
|
|
||||||
handshakePacket->writePrimitive(_initialSequenceNumber);
|
handshakePacket->writePrimitive(_initialSequenceNumber);
|
||||||
_socket->writeBasePacket(*handshakePacket, _destination);
|
_socket->writeBasePacket(*handshakePacket, _destination);
|
||||||
|
@ -236,6 +244,7 @@ void SendQueue::handshakeACK(SequenceNumber initialSequenceNumber) {
|
||||||
std::lock_guard<std::mutex> locker { _handshakeMutex };
|
std::lock_guard<std::mutex> locker { _handshakeMutex };
|
||||||
_hasReceivedHandshakeACK = true;
|
_hasReceivedHandshakeACK = true;
|
||||||
}
|
}
|
||||||
|
PROFILE_ASYNC_END(networking, "SendQueue:Handshake", _destination.toString());
|
||||||
|
|
||||||
// Notify on the handshake ACK condition
|
// Notify on the handshake ACK condition
|
||||||
_handshakeACKCondition.notify_one();
|
_handshakeACKCondition.notify_one();
|
||||||
|
|
|
@ -51,6 +51,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::unique_ptr<SendQueue> create(Socket* socket, HifiSockAddr destination);
|
static std::unique_ptr<SendQueue> create(Socket* socket, HifiSockAddr destination);
|
||||||
|
|
||||||
|
virtual ~SendQueue();
|
||||||
|
|
||||||
void queuePacket(std::unique_ptr<Packet> packet);
|
void queuePacket(std::unique_ptr<Packet> packet);
|
||||||
void queuePacketList(std::unique_ptr<PacketList> packetList);
|
void queuePacketList(std::unique_ptr<PacketList> packetList);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "../NLPacket.h"
|
#include "../NLPacket.h"
|
||||||
#include "../NLPacketList.h"
|
#include "../NLPacketList.h"
|
||||||
#include "PacketList.h"
|
#include "PacketList.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
using namespace udt;
|
using namespace udt;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
#include <Profile.h>
|
||||||
|
|
||||||
#include <LogHandler.h>
|
#include <LogHandler.h>
|
||||||
#include <NodeList.h>
|
#include <NodeList.h>
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
@ -28,6 +30,7 @@
|
||||||
#include "OctreeLogging.h"
|
#include "OctreeLogging.h"
|
||||||
#include "OctreeUtils.h"
|
#include "OctreeUtils.h"
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
AtomicUIntStat OctreeElement::_octreeMemoryUsage { 0 };
|
AtomicUIntStat OctreeElement::_octreeMemoryUsage { 0 };
|
||||||
AtomicUIntStat OctreeElement::_octcodeMemoryUsage { 0 };
|
AtomicUIntStat OctreeElement::_octcodeMemoryUsage { 0 };
|
||||||
|
@ -389,6 +392,7 @@ OctreeElementPointer OctreeElement::addChildAtIndex(int childIndex) {
|
||||||
|
|
||||||
_isDirty = true;
|
_isDirty = true;
|
||||||
markWithChangedTime();
|
markWithChangedTime();
|
||||||
|
PROFILE_INSTANT(octree, "EntityAdd", "g");
|
||||||
}
|
}
|
||||||
return childAt;
|
return childAt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -793,7 +793,7 @@ void RenderDeferred::configure(const Config& config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& inputs) {
|
void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||||
PROFILE_RANGE("DeferredLighting");
|
PROFILE_RANGE(renderlogging, "DeferredLighting");
|
||||||
|
|
||||||
auto deferredTransform = inputs.get0();
|
auto deferredTransform = inputs.get0();
|
||||||
auto deferredFramebuffer = inputs.get1();
|
auto deferredFramebuffer = inputs.get1();
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "Model.h"
|
#include "Model.h"
|
||||||
|
|
||||||
#include "RenderUtilsLogging.h"
|
#include "RenderUtilsLogging.h"
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -280,7 +281,8 @@ void Model::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Model::updateGeometry() {
|
bool Model::updateGeometry() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(renderutils, __FUNCTION__);
|
||||||
|
PerformanceTimer perfTimer("Model::updateGeometry");
|
||||||
bool needFullUpdate = false;
|
bool needFullUpdate = false;
|
||||||
|
|
||||||
if (!isLoaded()) {
|
if (!isLoaded()) {
|
||||||
|
@ -474,7 +476,7 @@ bool Model::convexHullContains(glm::vec3 point) {
|
||||||
// entity-scripts to call. I think it would be best to do the picking once-per-frame (in cpu, or gpu if possible)
|
// entity-scripts to call. I think it would be best to do the picking once-per-frame (in cpu, or gpu if possible)
|
||||||
// and then the calls use the most recent such result.
|
// and then the calls use the most recent such result.
|
||||||
void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
|
void Model::recalculateMeshBoxes(bool pickAgainstTriangles) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(renderutils, __FUNCTION__);
|
||||||
bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid;
|
bool calculatedMeshTrianglesNeeded = pickAgainstTriangles && !_calculatedMeshTrianglesValid;
|
||||||
|
|
||||||
if (!_calculatedMeshBoxesValid || calculatedMeshTrianglesNeeded || (!_calculatedMeshPartBoxesValid && pickAgainstTriangles) ) {
|
if (!_calculatedMeshBoxesValid || calculatedMeshTrianglesNeeded || (!_calculatedMeshPartBoxesValid && pickAgainstTriangles) ) {
|
||||||
|
@ -967,7 +969,7 @@ Blender::Blender(ModelPointer model, int blendNumber, const Geometry::WeakPointe
|
||||||
}
|
}
|
||||||
|
|
||||||
void Blender::run() {
|
void Blender::run() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE_EX(renderutils, __FUNCTION__, 0xFFFF0000, 0, { { "url", _model->getURL().toString() } });
|
||||||
QVector<glm::vec3> vertices, normals;
|
QVector<glm::vec3> vertices, normals;
|
||||||
if (_model) {
|
if (_model) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
@ -1088,7 +1090,8 @@ void Model::snapToRegistrationPoint() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::simulate(float deltaTime, bool fullUpdate) {
|
void Model::simulate(float deltaTime, bool fullUpdate) {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(renderutils, __FUNCTION__);
|
||||||
|
PerformanceTimer perfTimer("Model::simulate");
|
||||||
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit)
|
fullUpdate = updateGeometry() || fullUpdate || (_scaleToFit && !_scaledToFit)
|
||||||
|| (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint);
|
|| (_snapModelToRegistrationPoint && !_snappedToRegistrationPoint);
|
||||||
|
|
||||||
|
|
11
libraries/render/src/render/Logging.cpp
Normal file
11
libraries/render/src/render/Logging.cpp
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016-12-14
|
||||||
|
// Copyright 2013-2016 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 "Logging.h"
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(renderlogging, "hifi.render")
|
16
libraries/render/src/render/Logging.h
Normal file
16
libraries/render/src/render/Logging.h
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016-12-14
|
||||||
|
// Copyright 2013-2016 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_render_Logging_h
|
||||||
|
#define hifi_render_Logging_h
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(renderlogging)
|
||||||
|
|
||||||
|
#endif // hifi_render_Engine_h
|
|
@ -11,7 +11,8 @@
|
||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
|
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
#include "gpu/Batch.h"
|
#include <gpu/Batch.h>
|
||||||
|
#include "Logging.h"
|
||||||
|
|
||||||
using namespace render;
|
using namespace render;
|
||||||
|
|
||||||
|
@ -77,7 +78,7 @@ void consolidateChangeQueue(PendingChangesQueue& queue, PendingChanges& singleBa
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::processPendingChangesQueue() {
|
void Scene::processPendingChangesQueue() {
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(renderlogging, __FUNCTION__);
|
||||||
_changeQueueMutex.lock();
|
_changeQueueMutex.lock();
|
||||||
PendingChanges consolidatedPendingChanges;
|
PendingChanges consolidatedPendingChanges;
|
||||||
consolidateChangeQueue(_changeQueue, consolidatedPendingChanges);
|
consolidateChangeQueue(_changeQueue, consolidatedPendingChanges);
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "SettingHandle.h"
|
#include "SettingHandle.h"
|
||||||
|
|
||||||
#include "Context.h"
|
#include "Context.h"
|
||||||
|
#include "Logging.h"
|
||||||
|
|
||||||
#include "gpu/Batch.h"
|
#include "gpu/Batch.h"
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
|
@ -571,7 +572,7 @@ public:
|
||||||
|
|
||||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
PerformanceTimer perfTimer(_name.c_str());
|
PerformanceTimer perfTimer(_name.c_str());
|
||||||
PROFILE_RANGE(_name.c_str());
|
PROFILE_RANGE(renderlogging, _name.c_str());
|
||||||
auto start = usecTimestampNow();
|
auto start = usecTimestampNow();
|
||||||
|
|
||||||
_concept->run(sceneContext, renderContext);
|
_concept->run(sceneContext, renderContext);
|
||||||
|
|
|
@ -3,6 +3,8 @@ set(TARGET_NAME shared)
|
||||||
# TODO: there isn't really a good reason to have Script linked here - let's get what is requiring it out (RegisteredMetaTypes.cpp)
|
# TODO: there isn't really a good reason to have Script linked here - let's get what is requiring it out (RegisteredMetaTypes.cpp)
|
||||||
setup_hifi_library(Gui Network Script Widgets)
|
setup_hifi_library(Gui Network Script Widgets)
|
||||||
|
|
||||||
|
target_include_directories(${TARGET_NAME} PRIVATE "${CMAKE_BINARY_DIR}/includes")
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
target_link_libraries(${TARGET_NAME} Wbemuuid.lib)
|
target_link_libraries(${TARGET_NAME} Wbemuuid.lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
72
libraries/shared/src/Profile.cpp
Normal file
72
libraries/shared/src/Profile.cpp
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 2016-12-14
|
||||||
|
// Copyright 2013-2016 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 "Profile.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(NSIGHT_FOUND)
|
||||||
|
#include "nvToolsExt.h"
|
||||||
|
#define NSIGHT_TRACING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Duration::Duration(const QLoggingCategory& category, const QString& name, uint32_t argbColor, uint64_t payload, QVariantMap args) : _name(name), _category(category) {
|
||||||
|
if (_category.isDebugEnabled()) {
|
||||||
|
args["nv_payload"] = QVariant::fromValue(payload);
|
||||||
|
tracing::traceEvent(_category, _name, tracing::DurationBegin, "", args);
|
||||||
|
|
||||||
|
#if defined(NSIGHT_TRACING)
|
||||||
|
nvtxEventAttributes_t eventAttrib { 0 };
|
||||||
|
eventAttrib.version = NVTX_VERSION;
|
||||||
|
eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
|
||||||
|
eventAttrib.colorType = NVTX_COLOR_ARGB;
|
||||||
|
eventAttrib.color = argbColor;
|
||||||
|
eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
|
||||||
|
eventAttrib.message.ascii = name.toUtf8().data();
|
||||||
|
eventAttrib.payload.llValue = payload;
|
||||||
|
eventAttrib.payloadType = NVTX_PAYLOAD_TYPE_UNSIGNED_INT64;
|
||||||
|
|
||||||
|
nvtxRangePushEx(&eventAttrib);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Duration::~Duration() {
|
||||||
|
if (_category.isDebugEnabled()) {
|
||||||
|
tracing::traceEvent(_category, _name, tracing::DurationEnd);
|
||||||
|
#ifdef NSIGHT_TRACING
|
||||||
|
nvtxRangePop();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
uint64_t Duration::beginRange(const QLoggingCategory& category, const char* name, uint32_t argbColor) {
|
||||||
|
#ifdef NSIGHT_TRACING
|
||||||
|
if (category.isDebugEnabled()) {
|
||||||
|
nvtxEventAttributes_t eventAttrib = { 0 };
|
||||||
|
eventAttrib.version = NVTX_VERSION;
|
||||||
|
eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
|
||||||
|
eventAttrib.colorType = NVTX_COLOR_ARGB;
|
||||||
|
eventAttrib.color = argbColor;
|
||||||
|
eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
|
||||||
|
eventAttrib.message.ascii = name;
|
||||||
|
return nvtxRangeStartEx(&eventAttrib);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME
|
||||||
|
void Duration::endRange(const QLoggingCategory& category, uint64_t rangeId) {
|
||||||
|
#ifdef NSIGHT_TRACING
|
||||||
|
if (category.isDebugEnabled()) {
|
||||||
|
nvtxRangeEnd(rangeId);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
63
libraries/shared/src/Profile.h
Normal file
63
libraries/shared/src/Profile.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 2016-12-14
|
||||||
|
// Copyright 2013-2016 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_PROFILE_
|
||||||
|
#define HIFI_PROFILE_
|
||||||
|
|
||||||
|
#include "Trace.h"
|
||||||
|
|
||||||
|
class Duration {
|
||||||
|
public:
|
||||||
|
Duration(const QLoggingCategory& category, const QString& name, uint32_t argbColor = 0xff0000ff, uint64_t payload = 0, QVariantMap args = QVariantMap());
|
||||||
|
~Duration();
|
||||||
|
|
||||||
|
static uint64_t beginRange(const QLoggingCategory& category, const char* name, uint32_t argbColor);
|
||||||
|
static void endRange(const QLoggingCategory& category, uint64_t rangeId);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString _name;
|
||||||
|
const QLoggingCategory& _category;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void asyncBegin(const QLoggingCategory& category, const QString& name, const QString& id, const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap()) {
|
||||||
|
if (category.isDebugEnabled()) {
|
||||||
|
tracing::traceEvent(category, name, tracing::AsyncNestableStart, id, args, extra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void asyncEnd(const QLoggingCategory& category, const QString& name, const QString& id, const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap()) {
|
||||||
|
if (category.isDebugEnabled()) {
|
||||||
|
tracing::traceEvent(category, name, tracing::AsyncNestableEnd, id, args, extra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void instant(const QLoggingCategory& category, const QString& name, const QString& scope = "t", const QVariantMap& args = QVariantMap(), QVariantMap extra = QVariantMap()) {
|
||||||
|
if (category.isDebugEnabled()) {
|
||||||
|
extra["s"] = scope;
|
||||||
|
tracing::traceEvent(category, name, tracing::Instant, "", args, extra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void counter(const QLoggingCategory& category, const QString& name, const QVariantMap& args, const QVariantMap& extra = QVariantMap()) {
|
||||||
|
if (category.isDebugEnabled()) {
|
||||||
|
tracing::traceEvent(category, name, tracing::Counter, "", args, extra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define PROFILE_RANGE(category, name) Duration profileRangeThis(category(), name);
|
||||||
|
#define PROFILE_RANGE_EX(category, name, argbColor, payload, ...) Duration profileRangeThis(category(), name, argbColor, (uint64_t)payload, ##__VA_ARGS__);
|
||||||
|
#define PROFILE_RANGE_BEGIN(category, rangeId, name, argbColor) rangeId = Duration::beginRange(category(), name, argbColor)
|
||||||
|
#define PROFILE_RANGE_END(category, rangeId) Duration::endRange(category(), rangeId)
|
||||||
|
#define PROFILE_ASYNC_BEGIN(category, name, id, ...) asyncBegin(category(), name, id, ##__VA_ARGS__);
|
||||||
|
#define PROFILE_ASYNC_END(category, name, id, ...) asyncEnd(category(), name, id, ##__VA_ARGS__);
|
||||||
|
#define PROFILE_COUNTER(category, name, ...) counter(category(), name, ##__VA_ARGS__);
|
||||||
|
#define PROFILE_INSTANT(category, name, ...) instant(category(), name, ##__VA_ARGS__);
|
||||||
|
|
||||||
|
#endif
|
34
libraries/shared/src/StatTracker.cpp
Normal file
34
libraries/shared/src/StatTracker.cpp
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 2016-12-14
|
||||||
|
// Copyright 2013-2016 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 "StatTracker.h"
|
||||||
|
|
||||||
|
StatTracker::StatTracker() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant StatTracker::getStat(QString name) {
|
||||||
|
std::lock_guard<std::mutex> lock(_statsLock);
|
||||||
|
return _stats[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatTracker::editStat(QString name, EditStatFunction fn) {
|
||||||
|
std::lock_guard<std::mutex> lock(_statsLock);
|
||||||
|
_stats[name] = fn(_stats[name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatTracker::incrementStat(QString name) {
|
||||||
|
std::lock_guard<std::mutex> lock(_statsLock);
|
||||||
|
QVariant stat = _stats[name];
|
||||||
|
_stats[name] = _stats[name].toInt() + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatTracker::decrementStat(QString name) {
|
||||||
|
std::lock_guard<std::mutex> lock(_statsLock);
|
||||||
|
_stats[name] = _stats[name].toInt() - 1;
|
||||||
|
}
|
42
libraries/shared/src/StatTracker.h
Normal file
42
libraries/shared/src/StatTracker.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 2016-12-14
|
||||||
|
// Copyright 2013-2016 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
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QVariantMap>
|
||||||
|
#include <mutex>
|
||||||
|
#include "DependencyManager.h"
|
||||||
|
#include "Trace.h"
|
||||||
|
|
||||||
|
using EditStatFunction = std::function<QVariant(QVariant currentValue)>;
|
||||||
|
|
||||||
|
class StatTracker : public Dependency {
|
||||||
|
public:
|
||||||
|
StatTracker();
|
||||||
|
QVariant getStat(QString name);
|
||||||
|
void editStat(QString name, EditStatFunction fn);
|
||||||
|
void incrementStat(QString name);
|
||||||
|
void decrementStat(QString name);
|
||||||
|
private:
|
||||||
|
std::mutex _statsLock;
|
||||||
|
QVariantMap _stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CounterStat {
|
||||||
|
public:
|
||||||
|
CounterStat(QString name) : _name(name) {
|
||||||
|
DependencyManager::get<StatTracker>()->incrementStat(_name);
|
||||||
|
}
|
||||||
|
~CounterStat() {
|
||||||
|
DependencyManager::get<StatTracker>()->decrementStat(_name);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
QString _name;
|
||||||
|
};
|
205
libraries/shared/src/Trace.cpp
Normal file
205
libraries/shared/src/Trace.cpp
Normal file
|
@ -0,0 +1,205 @@
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 2016-12-14
|
||||||
|
// Copyright 2013-2016 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 "Trace.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QCoreApplication>
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
|
||||||
|
#include <QtCore/QFile>
|
||||||
|
#include <QtCore/QFileInfo>
|
||||||
|
#include <QtCore/QTemporaryFile>
|
||||||
|
#include <QtCore/QDataStream>
|
||||||
|
#include <QtCore/QTextStream>
|
||||||
|
|
||||||
|
#include <QtCore/QJsonObject>
|
||||||
|
#include <QtCore/QJsonDocument>
|
||||||
|
|
||||||
|
#include <BuildInfo.h>
|
||||||
|
|
||||||
|
#include "Gzip.h"
|
||||||
|
#include "PortableHighResolutionClock.h"
|
||||||
|
#include "shared/GlobalAppProperties.h"
|
||||||
|
|
||||||
|
using namespace tracing;
|
||||||
|
|
||||||
|
bool tracing::enabled() {
|
||||||
|
return DependencyManager::get<Tracer>()->isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tracer::startTracing() {
|
||||||
|
std::lock_guard<std::mutex> guard(_eventsMutex);
|
||||||
|
if (_enabled) {
|
||||||
|
qWarning() << "Tried to enable tracer, but already enabled";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_events.clear();
|
||||||
|
_enabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tracer::stopTracing() {
|
||||||
|
std::lock_guard<std::mutex> guard(_eventsMutex);
|
||||||
|
if (!_enabled) {
|
||||||
|
qWarning() << "Cannot stop tracing, already disabled";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_enabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TraceEvent::writeJson(QTextStream& out) const {
|
||||||
|
#if 0
|
||||||
|
// FIXME QJsonObject serialization is very slow, so we should be using manual JSON serialization
|
||||||
|
out << "{";
|
||||||
|
out << "\"name\":\"" << name << "\",";
|
||||||
|
out << "\"cat\":\"" << category.categoryName() << "\",";
|
||||||
|
out << "\"ph\":\"" << QString(type) << "\",";
|
||||||
|
out << "\"ts\":\"" << timestamp << "\",";
|
||||||
|
out << "\"pid\":\"" << processID << "\",";
|
||||||
|
out << "\"tid\":\"" << threadID << "\"";
|
||||||
|
//if (!extra.empty()) {
|
||||||
|
// auto it = extra.begin();
|
||||||
|
// for (; it != extra.end(); it++) {
|
||||||
|
// ev[it.key()] = QJsonValue::fromVariant(it.value());
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//if (!args.empty()) {
|
||||||
|
// out << ",\"args\":'
|
||||||
|
//}
|
||||||
|
out << '}';
|
||||||
|
#else
|
||||||
|
QJsonObject ev {
|
||||||
|
{ "name", QJsonValue(name) },
|
||||||
|
{ "cat", category.categoryName() },
|
||||||
|
{ "ph", QString(type) },
|
||||||
|
{ "ts", timestamp },
|
||||||
|
{ "pid", processID },
|
||||||
|
{ "tid", threadID }
|
||||||
|
};
|
||||||
|
if (!id.isEmpty()) {
|
||||||
|
ev["id"] = id;
|
||||||
|
}
|
||||||
|
if (!args.empty()) {
|
||||||
|
ev["args"] = QJsonObject::fromVariantMap(args);
|
||||||
|
}
|
||||||
|
if (!extra.empty()) {
|
||||||
|
auto it = extra.begin();
|
||||||
|
for (; it != extra.end(); it++) {
|
||||||
|
ev[it.key()] = QJsonValue::fromVariant(it.value());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << QJsonDocument(ev).toJson(QJsonDocument::Compact);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tracer::serialize(const QString& path) {
|
||||||
|
std::list<TraceEvent> currentEvents;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> guard(_eventsMutex);
|
||||||
|
currentEvents.swap(_events);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the file exists and we can't remove it, fail early
|
||||||
|
if (QFileInfo(path).exists() && !QFile::remove(path)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we can't open a temp file for writing, fail early
|
||||||
|
QByteArray data;
|
||||||
|
{
|
||||||
|
QTextStream out(&data);
|
||||||
|
out << "[\n";
|
||||||
|
bool first = true;
|
||||||
|
for (const auto& event : currentEvents) {
|
||||||
|
if (first) {
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
out << ",\n";
|
||||||
|
}
|
||||||
|
event.writeJson(out);
|
||||||
|
}
|
||||||
|
out << "\n]";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.endsWith(".gz")) {
|
||||||
|
QByteArray compressed;
|
||||||
|
gzip(data, compressed);
|
||||||
|
data = compressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
QFile file(path);
|
||||||
|
if (!file.open(QIODevice::WriteOnly)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
file.write(data);
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
QByteArray data;
|
||||||
|
{
|
||||||
|
|
||||||
|
// "traceEvents":[
|
||||||
|
// {"args":{"nv_payload":0},"cat":"hifi.render","name":"render::Scene::processPendingChangesQueue","ph":"B","pid":14796,"tid":21636,"ts":68795933487}
|
||||||
|
|
||||||
|
QJsonArray traceEvents;
|
||||||
|
|
||||||
|
QJsonDocument document {
|
||||||
|
QJsonObject {
|
||||||
|
{ "traceEvents", traceEvents },
|
||||||
|
{ "otherData", QJsonObject {
|
||||||
|
{ "version", QString { "High Fidelity Interface v1.0" } +BuildInfo::VERSION }
|
||||||
|
} }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
data = document.toJson(QJsonDocument::Compact);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tracer::traceEvent(const QLoggingCategory& category,
|
||||||
|
const QString& name, EventType type,
|
||||||
|
qint64 timestamp, qint64 processID, qint64 threadID,
|
||||||
|
const QString& id,
|
||||||
|
const QVariantMap& args, const QVariantMap& extra) {
|
||||||
|
std::lock_guard<std::mutex> guard(_eventsMutex);
|
||||||
|
if (!_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_events.push_back({
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
timestamp,
|
||||||
|
processID,
|
||||||
|
threadID,
|
||||||
|
category,
|
||||||
|
args,
|
||||||
|
extra
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void Tracer::traceEvent(const QLoggingCategory& category,
|
||||||
|
const QString& name, EventType type, const QString& id,
|
||||||
|
const QVariantMap& args, const QVariantMap& extra) {
|
||||||
|
if (!_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto timestamp = std::chrono::duration_cast<std::chrono::microseconds>(p_high_resolution_clock::now().time_since_epoch()).count();
|
||||||
|
auto processID = QCoreApplication::applicationPid();
|
||||||
|
auto threadID = int64_t(QThread::currentThreadId());
|
||||||
|
|
||||||
|
traceEvent(category, name, type, timestamp, processID, threadID, id, args, extra);
|
||||||
|
}
|
115
libraries/shared/src/Trace.h
Normal file
115
libraries/shared/src/Trace.h
Normal file
|
@ -0,0 +1,115 @@
|
||||||
|
//
|
||||||
|
// Created by Ryan Huffman on 2016-12-14
|
||||||
|
// Copyright 2013-2016 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_Trace_h
|
||||||
|
#define hifi_Trace_h
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QVariantMap>
|
||||||
|
#include <QtCore/QHash>
|
||||||
|
#include <QtCore/QSet>
|
||||||
|
#include <QtCore/QLoggingCategory>
|
||||||
|
|
||||||
|
#include "DependencyManager.h"
|
||||||
|
|
||||||
|
#define TRACE_ENABLED
|
||||||
|
|
||||||
|
namespace tracing {
|
||||||
|
|
||||||
|
bool enabled();
|
||||||
|
|
||||||
|
using TraceTimestamp = uint64_t;
|
||||||
|
|
||||||
|
enum EventType : char {
|
||||||
|
DurationBegin = 'B',
|
||||||
|
DurationEnd = 'E',
|
||||||
|
|
||||||
|
Complete = 'X',
|
||||||
|
Instant = 'i',
|
||||||
|
Counter = 'C',
|
||||||
|
|
||||||
|
AsyncNestableStart = 'b',
|
||||||
|
AsyncNestableInstant = 'n',
|
||||||
|
AsyncNestableEnd = 'e',
|
||||||
|
|
||||||
|
FlowStart = 's',
|
||||||
|
FlowStep = 't',
|
||||||
|
FlowEnd = 'f',
|
||||||
|
|
||||||
|
Sample = 'P',
|
||||||
|
|
||||||
|
ObjectCreated = 'N',
|
||||||
|
ObjectSnapshot = 'O',
|
||||||
|
ObjectDestroyed = 'D',
|
||||||
|
|
||||||
|
Metadata = 'M',
|
||||||
|
|
||||||
|
MemoryDumpGlobal = 'V',
|
||||||
|
MemoryDumpProcess = 'v',
|
||||||
|
|
||||||
|
Mark = 'R',
|
||||||
|
|
||||||
|
ClockSync = 'c',
|
||||||
|
|
||||||
|
ContextEnter = '(',
|
||||||
|
ContextLeave = ')'
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TraceEvent {
|
||||||
|
QString id;
|
||||||
|
QString name;
|
||||||
|
EventType type;
|
||||||
|
qint64 timestamp;
|
||||||
|
qint64 processID;
|
||||||
|
qint64 threadID;
|
||||||
|
const QLoggingCategory& category;
|
||||||
|
QVariantMap args;
|
||||||
|
QVariantMap extra;
|
||||||
|
|
||||||
|
void writeJson(QTextStream& out) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Tracer : public Dependency {
|
||||||
|
public:
|
||||||
|
void traceEvent(const QLoggingCategory& category,
|
||||||
|
const QString& name, EventType type,
|
||||||
|
const QString& id = "",
|
||||||
|
const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap());
|
||||||
|
|
||||||
|
void startTracing();
|
||||||
|
void stopTracing();
|
||||||
|
void serialize(const QString& file);
|
||||||
|
bool isEnabled() const { return _enabled; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void traceEvent(const QLoggingCategory& category,
|
||||||
|
const QString& name, EventType type,
|
||||||
|
qint64 timestamp, qint64 processID, qint64 threadID,
|
||||||
|
const QString& id = "",
|
||||||
|
const QVariantMap& args = QVariantMap(), const QVariantMap& extra = QVariantMap());
|
||||||
|
|
||||||
|
bool _enabled { false };
|
||||||
|
std::list<TraceEvent> _events;
|
||||||
|
std::mutex _eventsMutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void traceEvent(const QLoggingCategory& category, const QString& name, EventType type, const QString& id = "", const QVariantMap& args = {}, const QVariantMap& extra = {}) {
|
||||||
|
DependencyManager::get<Tracer>()->traceEvent(category, name, type, id, args, extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void traceEvent(const QLoggingCategory& category, const QString& name, EventType type, int id, const QVariantMap& args = {}, const QVariantMap& extra = {}) {
|
||||||
|
traceEvent(category, name, type, QString::number(id), args, extra);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // hifi_Trace_h
|
|
@ -14,6 +14,7 @@ namespace hifi { namespace properties {
|
||||||
const char* STEAM = "com.highfidelity.launchedFromSteam";
|
const char* STEAM = "com.highfidelity.launchedFromSteam";
|
||||||
const char* LOGGER = "com.highfidelity.logger";
|
const char* LOGGER = "com.highfidelity.logger";
|
||||||
const char* TEST = "com.highfidelity.test";
|
const char* TEST = "com.highfidelity.test";
|
||||||
|
const char* TRACING = "com.highfidelity.tracing";
|
||||||
|
|
||||||
namespace gl {
|
namespace gl {
|
||||||
const char* BACKEND = "com.highfidelity.gl.backend";
|
const char* BACKEND = "com.highfidelity.gl.backend";
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace hifi { namespace properties {
|
||||||
extern const char* STEAM;
|
extern const char* STEAM;
|
||||||
extern const char* LOGGER;
|
extern const char* LOGGER;
|
||||||
extern const char* TEST;
|
extern const char* TEST;
|
||||||
|
extern const char* TRACING;
|
||||||
|
|
||||||
namespace gl {
|
namespace gl {
|
||||||
extern const char* BACKEND;
|
extern const char* BACKEND;
|
||||||
|
|
|
@ -21,49 +21,6 @@ bool nsightActive() {
|
||||||
return nsightLaunched;
|
return nsightLaunched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint64_t ProfileRange::beginRange(const char* name, uint32_t argbColor) {
|
|
||||||
nvtxEventAttributes_t eventAttrib = { 0 };
|
|
||||||
eventAttrib.version = NVTX_VERSION;
|
|
||||||
eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
|
|
||||||
eventAttrib.colorType = NVTX_COLOR_ARGB;
|
|
||||||
eventAttrib.color = argbColor;
|
|
||||||
eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
|
|
||||||
eventAttrib.message.ascii = name;
|
|
||||||
return nvtxRangeStartEx(&eventAttrib);
|
|
||||||
// return nvtxRangePushEx(&eventAttrib);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProfileRange::endRange(uint64_t rangeId) {
|
|
||||||
nvtxRangeEnd(rangeId);
|
|
||||||
// nvtxRangePop();
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfileRange::ProfileRange(const char *name) {
|
|
||||||
// _rangeId = nvtxRangeStart(name);
|
|
||||||
_rangeId = nvtxRangePush(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfileRange::ProfileRange(const char *name, uint32_t argbColor, uint64_t payload) {
|
|
||||||
nvtxEventAttributes_t eventAttrib = {0};
|
|
||||||
eventAttrib.version = NVTX_VERSION;
|
|
||||||
eventAttrib.size = NVTX_EVENT_ATTRIB_STRUCT_SIZE;
|
|
||||||
eventAttrib.colorType = NVTX_COLOR_ARGB;
|
|
||||||
eventAttrib.color = argbColor;
|
|
||||||
eventAttrib.messageType = NVTX_MESSAGE_TYPE_ASCII;
|
|
||||||
eventAttrib.message.ascii = name;
|
|
||||||
eventAttrib.payload.llValue = payload;
|
|
||||||
eventAttrib.payloadType = NVTX_PAYLOAD_TYPE_UNSIGNED_INT64;
|
|
||||||
|
|
||||||
//_rangeId = nvtxRangeStartEx(&eventAttrib);
|
|
||||||
_rangeId = nvtxRangePushEx(&eventAttrib);
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfileRange::~ProfileRange() {
|
|
||||||
// nvtxRangeEnd(_rangeId);
|
|
||||||
nvtxRangePop();
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
bool nsightActive() {
|
bool nsightActive() {
|
||||||
|
|
|
@ -11,35 +11,6 @@
|
||||||
|
|
||||||
bool nsightActive();
|
bool nsightActive();
|
||||||
|
|
||||||
#if defined(_WIN32) && defined(NSIGHT_FOUND)
|
#include "../Profile.h"
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
class ProfileRange {
|
|
||||||
public:
|
|
||||||
ProfileRange(const char *name);
|
|
||||||
ProfileRange(const char *name, uint32_t argbColor, uint64_t payload);
|
|
||||||
~ProfileRange();
|
|
||||||
|
|
||||||
static uint64_t beginRange(const char* name, uint32_t argbColor);
|
|
||||||
static void endRange(uint64_t rangeId);
|
|
||||||
private:
|
|
||||||
uint64_t _rangeId{ 0 };
|
|
||||||
};
|
|
||||||
|
|
||||||
#define PROFILE_RANGE(name) ProfileRange profileRangeThis(name);
|
|
||||||
#define PROFILE_RANGE_EX(name, argbColor, payload) ProfileRange profileRangeThis(name, argbColor, (uint64_t)payload);
|
|
||||||
|
|
||||||
#define PROFILE_RANGE_BEGIN(rangeId, name, argbColor) rangeId = ProfileRange::beginRange(name, argbColor)
|
|
||||||
#define PROFILE_RANGE_END(rangeId) ProfileRange::endRange(rangeId)
|
|
||||||
|
|
||||||
#else
|
|
||||||
#define PROFILE_RANGE(name)
|
|
||||||
#define PROFILE_RANGE_EX(name, argbColor, payload)
|
|
||||||
|
|
||||||
|
|
||||||
#define PROFILE_RANGE_BEGIN(rangeId, name, argbColor)
|
|
||||||
#define PROFILE_RANGE_END(rangeId)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -110,7 +110,7 @@ void OculusDisplayPlugin::hmdPresent() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentFrame->frameIndex)
|
PROFILE_RANGE_EX(displayplugins, __FUNCTION__, 0xff00ff00, (uint64_t)_currentFrame->frameIndex)
|
||||||
|
|
||||||
int curIndex;
|
int curIndex;
|
||||||
ovr_GetTextureSwapChainCurrentIndex(_session, _textureSwapChain, &curIndex);
|
ovr_GetTextureSwapChainCurrentIndex(_session, _textureSwapChain, &curIndex);
|
||||||
|
|
|
@ -11,7 +11,6 @@
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
#include <QtCore/QLoggingCategory>
|
|
||||||
#include <QtCore/QFile>
|
#include <QtCore/QFile>
|
||||||
#include <QtCore/QDir>
|
#include <QtCore/QDir>
|
||||||
#include <QtCore/QProcessEnvironment>
|
#include <QtCore/QProcessEnvironment>
|
||||||
|
@ -20,8 +19,8 @@
|
||||||
#include <controllers/Pose.h>
|
#include <controllers/Pose.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(oculus)
|
Q_LOGGING_CATEGORY(displayplugins, "hifi.plugins.display")
|
||||||
Q_LOGGING_CATEGORY(oculus, "hifi.plugins.oculus")
|
Q_LOGGING_CATEGORY(oculus, "hifi.plugins.display.oculus")
|
||||||
|
|
||||||
static std::atomic<uint32_t> refCount { 0 };
|
static std::atomic<uint32_t> refCount { 0 };
|
||||||
static ovrSession session { nullptr };
|
static ovrSession session { nullptr };
|
||||||
|
@ -194,15 +193,14 @@ controller::Pose ovrControllerPoseToHandPose(
|
||||||
|
|
||||||
static const glm::quat leftQuarterZ = glm::angleAxis(-PI_OVER_TWO, Vectors::UNIT_Z);
|
static const glm::quat leftQuarterZ = glm::angleAxis(-PI_OVER_TWO, Vectors::UNIT_Z);
|
||||||
static const glm::quat rightQuarterZ = glm::angleAxis(PI_OVER_TWO, Vectors::UNIT_Z);
|
static const glm::quat rightQuarterZ = glm::angleAxis(PI_OVER_TWO, Vectors::UNIT_Z);
|
||||||
static const glm::quat eighthX = glm::angleAxis(PI / 4.0f, Vectors::UNIT_X);
|
|
||||||
|
|
||||||
static const glm::quat leftRotationOffset = glm::inverse(leftQuarterZ * eighthX) * touchToHand;
|
static const glm::quat leftRotationOffset = glm::inverse(leftQuarterZ) * touchToHand;
|
||||||
static const glm::quat rightRotationOffset = glm::inverse(rightQuarterZ * eighthX) * touchToHand;
|
static const glm::quat rightRotationOffset = glm::inverse(rightQuarterZ) * touchToHand;
|
||||||
|
|
||||||
static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches
|
static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches
|
||||||
static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f,
|
static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f,
|
||||||
CONTROLLER_LENGTH_OFFSET / 2.0f,
|
-CONTROLLER_LENGTH_OFFSET / 2.0f,
|
||||||
CONTROLLER_LENGTH_OFFSET * 2.0f);
|
CONTROLLER_LENGTH_OFFSET * 1.5f);
|
||||||
static const glm::vec3 leftTranslationOffset = glm::vec3(-1.0f, 1.0f, 1.0f) * CONTROLLER_OFFSET;
|
static const glm::vec3 leftTranslationOffset = glm::vec3(-1.0f, 1.0f, 1.0f) * CONTROLLER_OFFSET;
|
||||||
static const glm::vec3 rightTranslationOffset = CONTROLLER_OFFSET;
|
static const glm::vec3 rightTranslationOffset = CONTROLLER_OFFSET;
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
#include <QtCore/QLoggingCategory>
|
||||||
|
|
||||||
#include <OVR_CAPI_GL.h>
|
#include <OVR_CAPI_GL.h>
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
@ -14,6 +17,9 @@
|
||||||
|
|
||||||
#include <controllers/Forward.h>
|
#include <controllers/Forward.h>
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(displayplugins)
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(oculus)
|
||||||
|
|
||||||
void logWarning(const char* what);
|
void logWarning(const char* what);
|
||||||
void logCritical(const char* what);
|
void logCritical(const char* what);
|
||||||
bool oculusAvailable();
|
bool oculusAvailable();
|
||||||
|
|
|
@ -529,7 +529,7 @@ static bool isBadPose(vr::HmdMatrix34_t* mat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenVrDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
bool OpenVrDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff7fff00, frameIndex)
|
PROFILE_RANGE_EX(displayplugins, __FUNCTION__, 0xff7fff00, frameIndex)
|
||||||
handleOpenVrEvents();
|
handleOpenVrEvents();
|
||||||
if (openVrQuitRequested()) {
|
if (openVrQuitRequested()) {
|
||||||
QMetaObject::invokeMethod(qApp, "quit");
|
QMetaObject::invokeMethod(qApp, "quit");
|
||||||
|
@ -633,7 +633,7 @@ void OpenVrDisplayPlugin::compositeLayers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenVrDisplayPlugin::hmdPresent() {
|
void OpenVrDisplayPlugin::hmdPresent() {
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentFrame->frameIndex)
|
PROFILE_RANGE_EX(displayplugins, __FUNCTION__, 0xff00ff00, (uint64_t)_currentFrame->frameIndex)
|
||||||
|
|
||||||
if (_threadedSubmit) {
|
if (_threadedSubmit) {
|
||||||
_submitThread->waitForPresent();
|
_submitThread->waitForPresent();
|
||||||
|
@ -654,7 +654,7 @@ void OpenVrDisplayPlugin::hmdPresent() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenVrDisplayPlugin::postPreview() {
|
void OpenVrDisplayPlugin::postPreview() {
|
||||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentFrame->frameIndex)
|
PROFILE_RANGE_EX(displayplugins, __FUNCTION__, 0xff00ff00, (uint64_t)_currentFrame->frameIndex)
|
||||||
PoseData nextRender, nextSim;
|
PoseData nextRender, nextSim;
|
||||||
nextRender.frameIndex = presentCount();
|
nextRender.frameIndex = presentCount();
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,19 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
print("Fooooo");
|
|
||||||
|
|
||||||
Script.setTimeout(function() {
|
Script.setTimeout(function() {
|
||||||
|
var loggingRules = "" +
|
||||||
|
"*.debug=false\n" +
|
||||||
|
"hifi.render.debug=true\n" +
|
||||||
|
"hifi.interface.debug=true\n" +
|
||||||
|
"";
|
||||||
|
Test.startTracing(loggingRules);
|
||||||
|
}, 1 * 1000);
|
||||||
|
|
||||||
|
|
||||||
|
Script.setTimeout(function() {
|
||||||
|
Test.stopTracing("h:/testScriptTrace.json.gz");
|
||||||
Test.quit();
|
Test.quit();
|
||||||
}, 10 * 1000);
|
}, 10 * 1000);
|
||||||
|
|
||||||
|
|
161
scripts/system/assets/images/tools/people.svg
Normal file
161
scripts/system/assets/images/tools/people.svg
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 19.2.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
viewBox="0 0 50 200.1" style="enable-background:new 0 0 50 200.1;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.st0{fill:#414042;}
|
||||||
|
.st1{fill:#FFFFFF;}
|
||||||
|
.st2{fill:#1E1E1E;}
|
||||||
|
.st3{fill:#333333;}
|
||||||
|
</style>
|
||||||
|
<g id="Layer_2">
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M50.1,146.1c0,2.2-1.8,4-4,4h-42c-2.2,0-4-1.8-4-4v-42c0-2.2,1.8-4,4-4h42c2.2,0,4,1.8,4,4V146.1z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="st0" d="M50,196.1c0,2.2-1.8,4-4,4H4c-2.2,0-4-1.8-4-4v-42c0-2.2,1.8-4,4-4h42c2.2,0,4,1.8,4,4V196.1z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<g>
|
||||||
|
<path class="st1" d="M50,46c0,2.2-1.8,4-4,4H4c-2.2,0-4-1.8-4-4V4c0-2.2,1.8-4,4-4h42c2.2,0,4,1.8,4,4V46z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st2" d="M50,96.1c0,2.2-1.8,4-4,4H4c-2.2,0-4-1.8-4-4v-42c0-2.2,1.8-4,4-4h42c2.2,0,4,1.8,4,4V96.1z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<g id="Layer_3">
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st1" d="M8.1,92.5v-6.4h2.7c0.3,0,0.6,0.1,0.8,0.2s0.5,0.3,0.6,0.5c0.2,0.2,0.3,0.4,0.4,0.7c0.1,0.3,0.2,0.5,0.2,0.8
|
||||||
|
c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.7c-0.2,0.2-0.4,0.4-0.6,0.5c-0.2,0.1-0.5,0.2-0.8,0.2H9.3v2.1H8.1z M9.3,89.2h1.4
|
||||||
|
c0.2,0,0.4-0.1,0.6-0.3c0.2-0.2,0.2-0.4,0.2-0.8c0-0.2,0-0.3-0.1-0.4c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.3-0.2
|
||||||
|
c-0.1,0-0.2-0.1-0.3-0.1H9.3V89.2z"/>
|
||||||
|
<path class="st1" d="M18.3,91.4v1.1h-4.4v-6.4h4.4v1.1h-3.1v1.5h2.7v1h-2.7v1.7H18.3z"/>
|
||||||
|
<path class="st1" d="M22.1,92.5c-0.5,0-0.9-0.1-1.2-0.3s-0.7-0.4-1-0.7c-0.3-0.3-0.5-0.6-0.6-1c-0.1-0.4-0.2-0.8-0.2-1.2
|
||||||
|
c0-0.4,0.1-0.8,0.2-1.2s0.4-0.7,0.6-1c0.3-0.3,0.6-0.5,1-0.7s0.8-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3s0.7,0.4,1,0.7
|
||||||
|
c0.3,0.3,0.5,0.7,0.6,1c0.1,0.4,0.2,0.8,0.2,1.2c0,0.4-0.1,0.8-0.2,1.2c-0.2,0.4-0.4,0.7-0.6,1c-0.3,0.3-0.6,0.5-1,0.7
|
||||||
|
C22.9,92.4,22.5,92.5,22.1,92.5z M20.3,89.3c0,0.3,0,0.5,0.1,0.8c0.1,0.3,0.2,0.5,0.4,0.7c0.2,0.2,0.3,0.4,0.6,0.5s0.5,0.2,0.8,0.2
|
||||||
|
c0.3,0,0.5-0.1,0.8-0.2s0.4-0.3,0.6-0.5c0.1-0.2,0.3-0.4,0.3-0.7s0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8c-0.1-0.3-0.2-0.5-0.4-0.7
|
||||||
|
c-0.2-0.2-0.3-0.4-0.6-0.5c-0.2-0.1-0.5-0.2-0.7-0.2c-0.3,0-0.5,0.1-0.8,0.2s-0.4,0.3-0.6,0.5c-0.2,0.2-0.3,0.4-0.3,0.7
|
||||||
|
C20.4,88.7,20.3,89,20.3,89.3z"/>
|
||||||
|
<path class="st1" d="M26.3,92.5v-6.4H29c0.3,0,0.6,0.1,0.8,0.2s0.5,0.3,0.6,0.5c0.2,0.2,0.3,0.4,0.4,0.7c0.1,0.3,0.2,0.5,0.2,0.8
|
||||||
|
c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.7c-0.2,0.2-0.4,0.4-0.6,0.5c-0.2,0.1-0.5,0.2-0.8,0.2h-1.5v2.1H26.3z M27.6,89.2H29
|
||||||
|
c0.2,0,0.4-0.1,0.6-0.3c0.2-0.2,0.2-0.4,0.2-0.8c0-0.2,0-0.3-0.1-0.4c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.3-0.2
|
||||||
|
c-0.1,0-0.2-0.1-0.3-0.1h-1.4V89.2z"/>
|
||||||
|
<path class="st1" d="M32.1,92.5v-6.4h1.2v5.3h3.3v1.1H32.1z"/>
|
||||||
|
<path class="st1" d="M42.1,91.4v1.1h-4.4v-6.4H42v1.1h-3.1v1.5h2.7v1h-2.7v1.7H42.1z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<circle class="st1" cx="25" cy="64" r="4.5"/>
|
||||||
|
<path class="st1" d="M28.2,70.9h-6.1c-2.6,0-4.6,2.2-4.6,4.7V78c2.1,1.6,4.5,2.5,7.3,2.5c3.1,0,5.9-1.2,8-3.1v-1.8
|
||||||
|
C32.8,73,30.8,70.9,28.2,70.9z"/>
|
||||||
|
<circle class="st1" cx="34" cy="65.3" r="2"/>
|
||||||
|
<path class="st1" d="M35.2,69.1h-2.3c-0.5,0-0.9,0.2-1.3,0.5c0.7,0.3,1.3,0.9,1.7,1.4c0.6,0.7,0.9,1.5,0.9,2.4
|
||||||
|
c0.2,0.5,0.2,1,0.1,1.6v0.3c0.9-1.2,1.8-3.3,2.2-4.6v-0.2C36.7,70.1,36,69.1,35.2,69.1z"/>
|
||||||
|
<circle class="st1" cx="16" cy="65.8" r="2"/>
|
||||||
|
<path class="st1" d="M15.4,75.8c-0.1-0.4-0.1-0.8,0-1.2l0-0.1c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3
|
||||||
|
c0.1-1.2,0.9-2.5,1.8-3.2c0.2-0.2,0.5-0.3,0.8-0.5c-0.3-0.3-0.7-0.4-1.1-0.4h-2.3c-0.8,0-1.5,1-1.4,1.5v0.2
|
||||||
|
C13.5,72.4,14.5,74.5,15.4,75.8z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st1" d="M8.1,142.5v-6.4h2.7c0.3,0,0.6,0.1,0.8,0.2s0.5,0.3,0.6,0.5c0.2,0.2,0.3,0.4,0.4,0.7c0.1,0.3,0.2,0.5,0.2,0.8
|
||||||
|
c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.7c-0.2,0.2-0.4,0.4-0.6,0.5c-0.2,0.1-0.5,0.2-0.8,0.2H9.3v2.1H8.1z M9.3,139.2h1.4
|
||||||
|
c0.2,0,0.4-0.1,0.6-0.3c0.2-0.2,0.2-0.4,0.2-0.8c0-0.2,0-0.3-0.1-0.4c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.3-0.2
|
||||||
|
c-0.1,0-0.2-0.1-0.3-0.1H9.3V139.2z"/>
|
||||||
|
<path class="st1" d="M18.3,141.4v1.1h-4.4v-6.4h4.4v1.1h-3.1v1.5h2.7v1h-2.7v1.7H18.3z"/>
|
||||||
|
<path class="st1" d="M22.1,142.5c-0.5,0-0.9-0.1-1.2-0.3s-0.7-0.4-1-0.7c-0.3-0.3-0.5-0.6-0.6-1c-0.1-0.4-0.2-0.8-0.2-1.2
|
||||||
|
c0-0.4,0.1-0.8,0.2-1.2s0.4-0.7,0.6-1c0.3-0.3,0.6-0.5,1-0.7s0.8-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3s0.7,0.4,1,0.7
|
||||||
|
c0.3,0.3,0.5,0.7,0.6,1c0.1,0.4,0.2,0.8,0.2,1.2c0,0.4-0.1,0.8-0.2,1.2c-0.2,0.4-0.4,0.7-0.6,1c-0.3,0.3-0.6,0.5-1,0.7
|
||||||
|
C22.9,142.4,22.5,142.5,22.1,142.5z M20.3,139.3c0,0.3,0,0.5,0.1,0.8c0.1,0.3,0.2,0.5,0.4,0.7c0.2,0.2,0.3,0.4,0.6,0.5
|
||||||
|
s0.5,0.2,0.8,0.2c0.3,0,0.5-0.1,0.8-0.2s0.4-0.3,0.6-0.5c0.1-0.2,0.3-0.4,0.3-0.7s0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8
|
||||||
|
c-0.1-0.3-0.2-0.5-0.4-0.7c-0.2-0.2-0.3-0.4-0.6-0.5c-0.2-0.1-0.5-0.2-0.7-0.2c-0.3,0-0.5,0.1-0.8,0.2s-0.4,0.3-0.6,0.5
|
||||||
|
c-0.2,0.2-0.3,0.4-0.3,0.7C20.4,138.7,20.3,139,20.3,139.3z"/>
|
||||||
|
<path class="st1" d="M26.3,142.5v-6.4H29c0.3,0,0.6,0.1,0.8,0.2s0.5,0.3,0.6,0.5c0.2,0.2,0.3,0.4,0.4,0.7c0.1,0.3,0.2,0.5,0.2,0.8
|
||||||
|
c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.7c-0.2,0.2-0.4,0.4-0.6,0.5c-0.2,0.1-0.5,0.2-0.8,0.2h-1.5v2.1H26.3z M27.6,139.2H29
|
||||||
|
c0.2,0,0.4-0.1,0.6-0.3c0.2-0.2,0.2-0.4,0.2-0.8c0-0.2,0-0.3-0.1-0.4c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.3-0.2
|
||||||
|
c-0.1,0-0.2-0.1-0.3-0.1h-1.4V139.2z"/>
|
||||||
|
<path class="st1" d="M32.1,142.5v-6.4h1.2v5.3h3.3v1.1H32.1z"/>
|
||||||
|
<path class="st1" d="M42.1,141.4v1.1h-4.4v-6.4H42v1.1h-3.1v1.5h2.7v1h-2.7v1.7H42.1z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<circle class="st1" cx="25" cy="114" r="4.5"/>
|
||||||
|
<path class="st1" d="M28.2,120.9h-6.1c-2.6,0-4.6,2.2-4.6,4.7v2.4c2.1,1.6,4.5,2.5,7.3,2.5c3.1,0,5.9-1.2,8-3.1v-1.8
|
||||||
|
C32.8,123,30.8,120.9,28.2,120.9z"/>
|
||||||
|
<circle class="st1" cx="34" cy="115.3" r="2"/>
|
||||||
|
<path class="st1" d="M35.2,119.1h-2.3c-0.5,0-0.9,0.2-1.3,0.5c0.7,0.3,1.3,0.9,1.7,1.4c0.6,0.7,0.9,1.5,0.9,2.4
|
||||||
|
c0.2,0.5,0.2,1,0.1,1.6v0.3c0.9-1.2,1.8-3.3,2.2-4.6v-0.2C36.7,120.1,36,119.1,35.2,119.1z"/>
|
||||||
|
<circle class="st1" cx="16" cy="115.8" r="2"/>
|
||||||
|
<path class="st1" d="M15.4,125.8c-0.1-0.4-0.1-0.8,0-1.2l0-0.1c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3
|
||||||
|
c0.1-1.2,0.9-2.5,1.8-3.2c0.2-0.2,0.5-0.3,0.8-0.5c-0.3-0.3-0.7-0.4-1.1-0.4h-2.3c-0.8,0-1.5,1-1.4,1.5v0.2
|
||||||
|
C13.5,122.4,14.5,124.5,15.4,125.8z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st3" d="M8.1,42.5v-6.4h2.7c0.3,0,0.6,0.1,0.8,0.2s0.5,0.3,0.6,0.5c0.2,0.2,0.3,0.4,0.4,0.7c0.1,0.3,0.2,0.5,0.2,0.8
|
||||||
|
c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.7c-0.2,0.2-0.4,0.4-0.6,0.5c-0.2,0.1-0.5,0.2-0.8,0.2H9.3v2.1H8.1z M9.3,39.2h1.4
|
||||||
|
c0.2,0,0.4-0.1,0.6-0.3c0.2-0.2,0.2-0.4,0.2-0.8c0-0.2,0-0.3-0.1-0.4c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.3-0.2
|
||||||
|
c-0.1,0-0.2-0.1-0.3-0.1H9.3V39.2z"/>
|
||||||
|
<path class="st3" d="M18.3,41.4v1.1h-4.4v-6.4h4.4v1.1h-3.1v1.5h2.7v1h-2.7v1.7H18.3z"/>
|
||||||
|
<path class="st3" d="M22.1,42.5c-0.5,0-0.9-0.1-1.2-0.3s-0.7-0.4-1-0.7c-0.3-0.3-0.5-0.6-0.6-1c-0.1-0.4-0.2-0.8-0.2-1.2
|
||||||
|
c0-0.4,0.1-0.8,0.2-1.2s0.4-0.7,0.6-1c0.3-0.3,0.6-0.5,1-0.7s0.8-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3s0.7,0.4,1,0.7
|
||||||
|
c0.3,0.3,0.5,0.7,0.6,1c0.1,0.4,0.2,0.8,0.2,1.2c0,0.4-0.1,0.8-0.2,1.2c-0.2,0.4-0.4,0.7-0.6,1c-0.3,0.3-0.6,0.5-1,0.7
|
||||||
|
C22.9,42.4,22.5,42.5,22.1,42.5z M20.3,39.3c0,0.3,0,0.5,0.1,0.8c0.1,0.3,0.2,0.5,0.4,0.7c0.2,0.2,0.3,0.4,0.6,0.5s0.5,0.2,0.8,0.2
|
||||||
|
c0.3,0,0.5-0.1,0.8-0.2s0.4-0.3,0.6-0.5c0.1-0.2,0.3-0.4,0.3-0.7s0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8c-0.1-0.3-0.2-0.5-0.4-0.7
|
||||||
|
c-0.2-0.2-0.3-0.4-0.6-0.5c-0.2-0.1-0.5-0.2-0.7-0.2c-0.3,0-0.5,0.1-0.8,0.2s-0.4,0.3-0.6,0.5c-0.2,0.2-0.3,0.4-0.3,0.7
|
||||||
|
C20.4,38.7,20.3,39,20.3,39.3z"/>
|
||||||
|
<path class="st3" d="M26.3,42.5v-6.4H29c0.3,0,0.6,0.1,0.8,0.2s0.5,0.3,0.6,0.5c0.2,0.2,0.3,0.4,0.4,0.7c0.1,0.3,0.2,0.5,0.2,0.8
|
||||||
|
c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.7c-0.2,0.2-0.4,0.4-0.6,0.5c-0.2,0.1-0.5,0.2-0.8,0.2h-1.5v2.1H26.3z M27.6,39.2H29
|
||||||
|
c0.2,0,0.4-0.1,0.6-0.3c0.2-0.2,0.2-0.4,0.2-0.8c0-0.2,0-0.3-0.1-0.4c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.3-0.2
|
||||||
|
c-0.1,0-0.2-0.1-0.3-0.1h-1.4V39.2z"/>
|
||||||
|
<path class="st3" d="M32.1,42.5v-6.4h1.2v5.3h3.3v1.1H32.1z"/>
|
||||||
|
<path class="st3" d="M42.1,41.4v1.1h-4.4v-6.4H42v1.1h-3.1v1.5h2.7v1h-2.7v1.7H42.1z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<circle class="st3" cx="25" cy="14" r="4.5"/>
|
||||||
|
<path class="st3" d="M28.2,20.9h-6.1c-2.6,0-4.6,2.2-4.6,4.7V28c2.1,1.6,4.5,2.5,7.3,2.5c3.1,0,5.9-1.2,8-3.1v-1.8
|
||||||
|
C32.8,23,30.8,20.9,28.2,20.9z"/>
|
||||||
|
<circle class="st3" cx="34" cy="15.3" r="2"/>
|
||||||
|
<path class="st3" d="M35.2,19.1h-2.3c-0.5,0-0.9,0.2-1.3,0.5c0.7,0.3,1.3,0.9,1.7,1.4c0.6,0.7,0.9,1.5,0.9,2.4
|
||||||
|
c0.2,0.5,0.2,1,0.1,1.6v0.3c0.9-1.2,1.8-3.3,2.2-4.6v-0.2C36.7,20.1,36,19.1,35.2,19.1z"/>
|
||||||
|
<circle class="st3" cx="16" cy="15.8" r="2"/>
|
||||||
|
<path class="st3" d="M15.4,25.8c-0.1-0.4-0.1-0.8,0-1.2l0-0.1c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3
|
||||||
|
c0.1-1.2,0.9-2.5,1.8-3.2c0.2-0.2,0.5-0.3,0.8-0.5c-0.3-0.3-0.7-0.4-1.1-0.4h-2.3c-0.8,0-1.5,1-1.4,1.5v0.2
|
||||||
|
C13.5,22.4,14.5,24.5,15.4,25.8z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<path class="st1" d="M8.1,192.6v-6.4h2.7c0.3,0,0.6,0.1,0.8,0.2s0.5,0.3,0.6,0.5c0.2,0.2,0.3,0.4,0.4,0.7c0.1,0.3,0.2,0.5,0.2,0.8
|
||||||
|
c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.7c-0.2,0.2-0.4,0.4-0.6,0.5c-0.2,0.1-0.5,0.2-0.8,0.2H9.3v2.1H8.1z M9.3,189.3h1.4
|
||||||
|
c0.2,0,0.4-0.1,0.6-0.3c0.2-0.2,0.2-0.4,0.2-0.8c0-0.2,0-0.3-0.1-0.4c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.3-0.2
|
||||||
|
c-0.1,0-0.2-0.1-0.3-0.1H9.3V189.3z"/>
|
||||||
|
<path class="st1" d="M18.3,191.5v1.1h-4.4v-6.4h4.4v1.1h-3.1v1.5h2.7v1h-2.7v1.7H18.3z"/>
|
||||||
|
<path class="st1" d="M22.1,192.6c-0.5,0-0.9-0.1-1.2-0.3s-0.7-0.4-1-0.7c-0.3-0.3-0.5-0.6-0.6-1c-0.1-0.4-0.2-0.8-0.2-1.2
|
||||||
|
c0-0.4,0.1-0.8,0.2-1.2s0.4-0.7,0.6-1c0.3-0.3,0.6-0.5,1-0.7s0.8-0.3,1.2-0.3c0.5,0,0.9,0.1,1.2,0.3s0.7,0.4,1,0.7
|
||||||
|
c0.3,0.3,0.5,0.7,0.6,1c0.1,0.4,0.2,0.8,0.2,1.2c0,0.4-0.1,0.8-0.2,1.2c-0.2,0.4-0.4,0.7-0.6,1c-0.3,0.3-0.6,0.5-1,0.7
|
||||||
|
C22.9,192.5,22.5,192.6,22.1,192.6z M20.3,189.4c0,0.3,0,0.5,0.1,0.8c0.1,0.3,0.2,0.5,0.4,0.7c0.2,0.2,0.3,0.4,0.6,0.5
|
||||||
|
s0.5,0.2,0.8,0.2c0.3,0,0.5-0.1,0.8-0.2s0.4-0.3,0.6-0.5c0.1-0.2,0.3-0.4,0.3-0.7s0.1-0.5,0.1-0.8c0-0.3,0-0.5-0.1-0.8
|
||||||
|
c-0.1-0.3-0.2-0.5-0.4-0.7c-0.2-0.2-0.3-0.4-0.6-0.5c-0.2-0.1-0.5-0.2-0.7-0.2c-0.3,0-0.5,0.1-0.8,0.2s-0.4,0.3-0.6,0.5
|
||||||
|
c-0.2,0.2-0.3,0.4-0.3,0.7C20.4,188.8,20.3,189.1,20.3,189.4z"/>
|
||||||
|
<path class="st1" d="M26.3,192.6v-6.4H29c0.3,0,0.6,0.1,0.8,0.2s0.5,0.3,0.6,0.5c0.2,0.2,0.3,0.4,0.4,0.7c0.1,0.3,0.2,0.5,0.2,0.8
|
||||||
|
c0,0.3,0,0.5-0.1,0.8c-0.1,0.3-0.2,0.5-0.4,0.7c-0.2,0.2-0.4,0.4-0.6,0.5c-0.2,0.1-0.5,0.2-0.8,0.2h-1.5v2.1H26.3z M27.6,189.3H29
|
||||||
|
c0.2,0,0.4-0.1,0.6-0.3c0.2-0.2,0.2-0.4,0.2-0.8c0-0.2,0-0.3-0.1-0.4c0-0.1-0.1-0.2-0.2-0.3c-0.1-0.1-0.2-0.2-0.3-0.2
|
||||||
|
c-0.1,0-0.2-0.1-0.3-0.1h-1.4V189.3z"/>
|
||||||
|
<path class="st1" d="M32.1,192.6v-6.4h1.2v5.3h3.3v1.1H32.1z"/>
|
||||||
|
<path class="st1" d="M42.1,191.5v1.1h-4.4v-6.4H42v1.1h-3.1v1.5h2.7v1h-2.7v1.7H42.1z"/>
|
||||||
|
</g>
|
||||||
|
<g>
|
||||||
|
<circle class="st1" cx="25" cy="164.2" r="4.5"/>
|
||||||
|
<path class="st1" d="M28.2,171h-6.1c-2.6,0-4.6,2.2-4.6,4.7v2.4c2.1,1.6,4.5,2.5,7.3,2.5c3.1,0,5.9-1.2,8-3.1v-1.8
|
||||||
|
C32.8,173.1,30.8,171,28.2,171z"/>
|
||||||
|
<circle class="st1" cx="34" cy="165.4" r="2"/>
|
||||||
|
<path class="st1" d="M35.2,169.2h-2.3c-0.5,0-0.9,0.2-1.3,0.5c0.7,0.3,1.3,0.9,1.7,1.4c0.6,0.7,0.9,1.5,0.9,2.4
|
||||||
|
c0.2,0.5,0.2,1,0.1,1.6v0.3c0.9-1.2,1.8-3.3,2.2-4.6v-0.2C36.7,170.2,36,169.2,35.2,169.2z"/>
|
||||||
|
<circle class="st1" cx="16" cy="165.9" r="2"/>
|
||||||
|
<path class="st1" d="M15.4,175.9c-0.1-0.4-0.1-0.8,0-1.2l0-0.1c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3c0-0.1,0-0.2,0-0.3
|
||||||
|
c0.1-1.2,0.9-2.5,1.8-3.2c0.2-0.2,0.5-0.3,0.8-0.5c-0.3-0.3-0.7-0.4-1.1-0.4h-2.3c-0.8,0-1.5,1-1.4,1.5v0.2
|
||||||
|
C13.5,172.5,14.5,174.6,15.4,175.9z"/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 11 KiB |
|
@ -703,6 +703,8 @@ function MyController(hand) {
|
||||||
this.autoUnequipCounter = 0;
|
this.autoUnequipCounter = 0;
|
||||||
this.grabPointIntersectsEntity = false;
|
this.grabPointIntersectsEntity = false;
|
||||||
|
|
||||||
|
this.shouldScale = false;
|
||||||
|
|
||||||
// handPosition is where the avatar's hand appears to be, in-world.
|
// handPosition is where the avatar's hand appears to be, in-world.
|
||||||
this.getHandPosition = function () {
|
this.getHandPosition = function () {
|
||||||
if (this.hand === RIGHT_HAND) {
|
if (this.hand === RIGHT_HAND) {
|
||||||
|
@ -771,6 +773,11 @@ function MyController(hand) {
|
||||||
|
|
||||||
this.updateSmoothedTrigger();
|
this.updateSmoothedTrigger();
|
||||||
|
|
||||||
|
// If both trigger and grip buttons squeezed and nothing is held, rescale my avatar!
|
||||||
|
if (this.hand === RIGHT_HAND && this.state === STATE_SEARCHING && this.getOtherHandController().state === STATE_SEARCHING) {
|
||||||
|
this.maybeScaleMyAvatar();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.ignoreInput()) {
|
if (this.ignoreInput()) {
|
||||||
this.turnOffVisualizations();
|
this.turnOffVisualizations();
|
||||||
return;
|
return;
|
||||||
|
@ -1614,6 +1621,8 @@ function MyController(hand) {
|
||||||
this.clearEquipHaptics();
|
this.clearEquipHaptics();
|
||||||
this.grabPointSphereOff();
|
this.grabPointSphereOff();
|
||||||
|
|
||||||
|
this.shouldScale = false;
|
||||||
|
|
||||||
var worldControllerPosition = getControllerWorldLocation(this.handToController(), true).position;
|
var worldControllerPosition = getControllerWorldLocation(this.handToController(), true).position;
|
||||||
|
|
||||||
// transform the position into room space
|
// transform the position into room space
|
||||||
|
@ -1773,6 +1782,7 @@ function MyController(hand) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.maybeScale(grabbedProperties);
|
||||||
// visualizations
|
// visualizations
|
||||||
|
|
||||||
var rayPickInfo = this.calcRayPickInfo(this.hand);
|
var rayPickInfo = this.calcRayPickInfo(this.hand);
|
||||||
|
@ -1882,6 +1892,8 @@ function MyController(hand) {
|
||||||
this.dropGestureReset();
|
this.dropGestureReset();
|
||||||
this.clearEquipHaptics();
|
this.clearEquipHaptics();
|
||||||
|
|
||||||
|
this.shouldScale = false;
|
||||||
|
|
||||||
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
|
Controller.triggerHapticPulse(HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, this.hand);
|
||||||
|
|
||||||
if (this.entityActivated) {
|
if (this.entityActivated) {
|
||||||
|
@ -2151,6 +2163,10 @@ function MyController(hand) {
|
||||||
this.callEntityMethodOnGrabbed("continueNearGrab");
|
this.callEntityMethodOnGrabbed("continueNearGrab");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.state == STATE_NEAR_GRABBING) {
|
||||||
|
this.maybeScale(props);
|
||||||
|
}
|
||||||
|
|
||||||
if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSECS_PER_SEC) {
|
if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSECS_PER_SEC) {
|
||||||
// if less than a 5 seconds left, refresh the actions ttl
|
// if less than a 5 seconds left, refresh the actions ttl
|
||||||
var success = Entities.updateAction(this.grabbedEntity, this.actionID, {
|
var success = Entities.updateAction(this.grabbedEntity, this.actionID, {
|
||||||
|
@ -2173,6 +2189,43 @@ function MyController(hand) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.maybeScale = function(props) {
|
||||||
|
if (!this.shouldScale) {
|
||||||
|
// If both secondary triggers squeezed, and the non-holding hand is empty, start scaling
|
||||||
|
if (this.secondarySqueezed() && this.getOtherHandController().secondarySqueezed() && this.getOtherHandController().state === STATE_OFF) {
|
||||||
|
this.scalingStartDistance = Vec3.length(Vec3.subtract(this.getHandPosition(), this.getOtherHandController().getHandPosition()));
|
||||||
|
this.scalingStartDimensions = props.dimensions;
|
||||||
|
this.shouldScale = true;
|
||||||
|
}
|
||||||
|
} else if (!this.secondarySqueezed() || !this.getOtherHandController().secondarySqueezed()) {
|
||||||
|
this.shouldScale = false;
|
||||||
|
}
|
||||||
|
if (this.shouldScale) {
|
||||||
|
var scalingCurrentDistance = Vec3.length(Vec3.subtract(this.getHandPosition(), this.getOtherHandController().getHandPosition()));
|
||||||
|
var currentRescale = scalingCurrentDistance / this.scalingStartDistance;
|
||||||
|
var newDimensions = Vec3.multiply(currentRescale, this.scalingStartDimensions);
|
||||||
|
Entities.editEntity(this.grabbedEntity, { dimensions: newDimensions })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.maybeScaleMyAvatar = function() {
|
||||||
|
if (!this.shouldScale) {
|
||||||
|
// If both secondary triggers squeezed, start scaling
|
||||||
|
if (this.secondarySqueezed() && this.getOtherHandController().secondarySqueezed()) {
|
||||||
|
this.scalingStartDistance = Vec3.length(Vec3.subtract(this.getHandPosition(), this.getOtherHandController().getHandPosition()));
|
||||||
|
this.scalingStartAvatarScale = MyAvatar.scale;
|
||||||
|
this.shouldScale = true;
|
||||||
|
}
|
||||||
|
} else if (!this.secondarySqueezed() || !this.getOtherHandController().secondarySqueezed()) {
|
||||||
|
this.shouldScale = false;
|
||||||
|
}
|
||||||
|
if (this.shouldScale) {
|
||||||
|
var scalingCurrentDistance = Vec3.length(Vec3.subtract(this.getHandPosition(), this.getOtherHandController().getHandPosition()));
|
||||||
|
var newAvatarScale = (scalingCurrentDistance / this.scalingStartDistance) * this.scalingStartAvatarScale;
|
||||||
|
MyAvatar.scale = newAvatarScale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.nearTriggerEnter = function() {
|
this.nearTriggerEnter = function() {
|
||||||
this.clearEquipHaptics();
|
this.clearEquipHaptics();
|
||||||
this.grabPointSphereOff();
|
this.grabPointSphereOff();
|
||||||
|
|
265
scripts/system/pal.js
Normal file
265
scripts/system/pal.js
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
"use strict";
|
||||||
|
/*jslint vars: true, plusplus: true, forin: true*/
|
||||||
|
/*globals Script, AvatarList, Camera, Overlays, OverlayWindow, Toolbars, Vec3, Quat, Controller, print, getControllerWorldLocation */
|
||||||
|
//
|
||||||
|
// pal.js
|
||||||
|
//
|
||||||
|
// Created by Howard Stearns on December 9, 2016
|
||||||
|
// Copyright 2016 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
|
||||||
|
//
|
||||||
|
|
||||||
|
// FIXME when we make this a defaultScript: (function() { // BEGIN LOCAL_SCOPE
|
||||||
|
|
||||||
|
Script.include("/~/system/libraries/controllers.js");
|
||||||
|
|
||||||
|
//
|
||||||
|
// Overlays.
|
||||||
|
//
|
||||||
|
var overlays = {}; // Keeps track of all our extended overlay data objects, keyed by target identifier.
|
||||||
|
function ExtendedOverlay(key, type, properties, selected) { // A wrapper around overlays to store the key it is associated with.
|
||||||
|
overlays[key] = this;
|
||||||
|
this.key = key;
|
||||||
|
this.selected = selected || false; // not undefined
|
||||||
|
this.activeOverlay = Overlays.addOverlay(type, properties); // We could use different overlays for (un)selected...
|
||||||
|
}
|
||||||
|
// Instance methods:
|
||||||
|
ExtendedOverlay.prototype.deleteOverlay = function () { // remove display and data of this overlay
|
||||||
|
Overlays.deleteOverlay(this.activeOverlay);
|
||||||
|
delete overlays[this.key];
|
||||||
|
};
|
||||||
|
|
||||||
|
ExtendedOverlay.prototype.editOverlay = function (properties) { // change display of this overlay
|
||||||
|
Overlays.editOverlay(this.activeOverlay, properties);
|
||||||
|
};
|
||||||
|
const UNSELECTED_COLOR = {red: 20, green: 250, blue: 20};
|
||||||
|
const SELECTED_COLOR = {red: 250, green: 20, blue: 20};
|
||||||
|
function color(selected) { return selected ? SELECTED_COLOR : UNSELECTED_COLOR; }
|
||||||
|
ExtendedOverlay.prototype.select = function (selected) {
|
||||||
|
if (this.selected === selected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.editOverlay({color: color(selected)});
|
||||||
|
this.selected = selected;
|
||||||
|
};
|
||||||
|
// Class methods:
|
||||||
|
var selectedIds = [];
|
||||||
|
ExtendedOverlay.isSelected = function (id) {
|
||||||
|
return -1 !== selectedIds.indexOf(id);
|
||||||
|
}
|
||||||
|
ExtendedOverlay.get = function (key) { // answer the extended overlay data object associated with the given avatar identifier
|
||||||
|
return overlays[key];
|
||||||
|
};
|
||||||
|
ExtendedOverlay.some = function (iterator) { // Bails early as soon as iterator returns truthy.
|
||||||
|
var key;
|
||||||
|
for (key in overlays) {
|
||||||
|
if (iterator(ExtendedOverlay.get(key))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ExtendedOverlay.applyPickRay = function (pickRay, cb) { // cb(overlay) on the one overlay intersected by pickRay, if any.
|
||||||
|
var pickedOverlay = Overlays.findRayIntersection(pickRay); // Depends on nearer coverOverlays to extend closer to us than farther ones.
|
||||||
|
if (!pickedOverlay.intersects) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ExtendedOverlay.some(function (overlay) { // See if pickedOverlay is one of ours.
|
||||||
|
if ((overlay.activeOverlay) === pickedOverlay.overlayID) {
|
||||||
|
cb(overlay);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// The qml window and communications.
|
||||||
|
//
|
||||||
|
var pal = new OverlayWindow({
|
||||||
|
title: 'People Action List',
|
||||||
|
source: 'hifi/Pal.qml',
|
||||||
|
width: 480,
|
||||||
|
height: 640,
|
||||||
|
visible: false
|
||||||
|
});
|
||||||
|
pal.fromQml.connect(function (message) { // messages are {method, params}, like json-rpc. See also sendToQml.
|
||||||
|
print('From PAL QML:', JSON.stringify(message));
|
||||||
|
switch (message.method) {
|
||||||
|
case 'selected':
|
||||||
|
selectedIds = message.params;
|
||||||
|
ExtendedOverlay.some(function (overlay) {
|
||||||
|
var id = overlay.key;
|
||||||
|
var selected = ExtendedOverlay.isSelected(id);
|
||||||
|
overlay.select(selected);
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print('Unrecognized message from Pal.qml:', JSON.stringify(message));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// Main operations.
|
||||||
|
//
|
||||||
|
function addAvatarNode(id) {
|
||||||
|
var selected = ExtendedOverlay.isSelected(id);
|
||||||
|
return new ExtendedOverlay(id, "sphere", { // 3d so we don't go cross-eyed looking at it, but on top of everything
|
||||||
|
solid: true,
|
||||||
|
alpha: 0.8,
|
||||||
|
color: color(selected),
|
||||||
|
drawInFront: true
|
||||||
|
}, selected);
|
||||||
|
}
|
||||||
|
function populateUserList() {
|
||||||
|
var data = [];
|
||||||
|
var counter = 1;
|
||||||
|
AvatarList.getAvatarIdentifiers().sort().forEach(function (id) { // sorting the identifiers is just an aid for debugging
|
||||||
|
var avatar = AvatarList.getAvatar(id);
|
||||||
|
var avatarPalDatum = {
|
||||||
|
displayName: avatar.displayName || ('anonymous ' + counter++),
|
||||||
|
userName: "fakeAcct" + (id || "Me"),
|
||||||
|
sessionId: id || ''
|
||||||
|
};
|
||||||
|
data.push(avatarPalDatum);
|
||||||
|
if (id) { // No overlay for ourself.
|
||||||
|
addAvatarNode(id);
|
||||||
|
}
|
||||||
|
print('PAL data:', JSON.stringify(avatarPalDatum));
|
||||||
|
});
|
||||||
|
pal.sendToQml({method: 'users', params: data});
|
||||||
|
}
|
||||||
|
var pingPong = true;
|
||||||
|
function updateOverlays() {
|
||||||
|
var eye = Camera.position;
|
||||||
|
AvatarList.getAvatarIdentifiers().forEach(function (id) {
|
||||||
|
if (!id) {
|
||||||
|
return; // don't update ourself
|
||||||
|
}
|
||||||
|
var overlay = ExtendedOverlay.get(id);
|
||||||
|
if (!overlay) { // For now, we're treating this as a temporary loss, as from the personal space bubble. Add it back.
|
||||||
|
print('Adding non-PAL avatar node', id);
|
||||||
|
overlay = addAvatarNode(id);
|
||||||
|
}
|
||||||
|
var avatar = AvatarList.getAvatar(id);
|
||||||
|
var target = avatar.position;
|
||||||
|
var distance = Vec3.distance(target, eye);
|
||||||
|
overlay.ping = pingPong;
|
||||||
|
overlay.editOverlay({
|
||||||
|
position: target,
|
||||||
|
dimensions: 0.05 * distance // constant apparent size
|
||||||
|
});
|
||||||
|
});
|
||||||
|
pingPong = !pingPong;
|
||||||
|
ExtendedOverlay.some(function (overlay) { // Remove any that weren't updated. (User is gone.)
|
||||||
|
if (overlay.ping === pingPong) {
|
||||||
|
overlay.deleteOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// We could re-populateUserList if anything added or removed, but not for now.
|
||||||
|
}
|
||||||
|
function removeOverlays() {
|
||||||
|
selectedIds = [];
|
||||||
|
ExtendedOverlay.some(function (overlay) { overlay.deleteOverlay(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Clicks.
|
||||||
|
//
|
||||||
|
function handleClick(pickRay) {
|
||||||
|
ExtendedOverlay.applyPickRay(pickRay, function (overlay) {
|
||||||
|
// Don't select directly. Tell qml, who will give us back a list of ids.
|
||||||
|
var message = {method: 'select', params: [overlay.key, !overlay.selected]};
|
||||||
|
pal.sendToQml(message);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function handleMouseEvent(mousePressEvent) { // handleClick if we get one.
|
||||||
|
if (!mousePressEvent.isLeftButton) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handleClick(Camera.computePickRay(mousePressEvent.x, mousePressEvent.y));
|
||||||
|
}
|
||||||
|
// We get mouseMoveEvents from the handControllers, via handControllerPointer.
|
||||||
|
// But we don't get mousePressEvents.
|
||||||
|
var triggerMapping = Controller.newMapping(Script.resolvePath('') + '-click');
|
||||||
|
function controllerComputePickRay(hand) {
|
||||||
|
var controllerPose = getControllerWorldLocation(hand, true);
|
||||||
|
if (controllerPose.valid) {
|
||||||
|
return { origin: controllerPose.position, direction: Quat.getUp(controllerPose.orientation) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function makeClickHandler(hand) {
|
||||||
|
return function (clicked) {
|
||||||
|
if (clicked > 0.85) {
|
||||||
|
var pickRay = controllerComputePickRay(hand);
|
||||||
|
handleClick(pickRay);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
triggerMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand));
|
||||||
|
triggerMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
|
||||||
|
|
||||||
|
//
|
||||||
|
// Manage the connection between the button and the window.
|
||||||
|
//
|
||||||
|
var toolBar = Toolbars.getToolbar("com.highfidelity.interface.toolbar.system");
|
||||||
|
var buttonName = "pal";
|
||||||
|
var button = toolBar.addButton({
|
||||||
|
objectName: buttonName,
|
||||||
|
imageURL: Script.resolvePath("assets/images/tools/people.svg"),
|
||||||
|
visible: true,
|
||||||
|
hoverState: 2,
|
||||||
|
defaultState: 1,
|
||||||
|
buttonState: 1,
|
||||||
|
alpha: 0.9
|
||||||
|
});
|
||||||
|
var isWired = false;
|
||||||
|
function off() {
|
||||||
|
if (isWired) { // It is not ok to disconnect these twice, hence guard.
|
||||||
|
Script.update.disconnect(updateOverlays);
|
||||||
|
Controller.mousePressEvent.disconnect(handleMouseEvent);
|
||||||
|
isWired = false;
|
||||||
|
}
|
||||||
|
triggerMapping.disable(); // It's ok if we disable twice.
|
||||||
|
removeOverlays();
|
||||||
|
}
|
||||||
|
function onClicked() {
|
||||||
|
if (!pal.visible) {
|
||||||
|
populateUserList();
|
||||||
|
pal.raise();
|
||||||
|
isWired = true;
|
||||||
|
Script.update.connect(updateOverlays);
|
||||||
|
Controller.mousePressEvent.connect(handleMouseEvent);
|
||||||
|
triggerMapping.enable();
|
||||||
|
} else {
|
||||||
|
off();
|
||||||
|
}
|
||||||
|
pal.setVisible(!pal.visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Button state.
|
||||||
|
//
|
||||||
|
function onVisibileChanged() {
|
||||||
|
button.writeProperty('buttonState', pal.visible ? 0 : 1);
|
||||||
|
button.writeProperty('defaultState', pal.visible ? 0 : 1);
|
||||||
|
button.writeProperty('hoverState', pal.visible ? 2 : 3);
|
||||||
|
}
|
||||||
|
button.clicked.connect(onClicked);
|
||||||
|
pal.visibleChanged.connect(onVisibileChanged);
|
||||||
|
pal.closed.connect(off);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cleanup.
|
||||||
|
//
|
||||||
|
Script.scriptEnding.connect(function () {
|
||||||
|
button.clicked.disconnect(onClicked);
|
||||||
|
toolBar.removeButton(buttonName);
|
||||||
|
pal.visibleChanged.disconnect(onVisibileChanged);
|
||||||
|
pal.closed.disconnect(off);
|
||||||
|
off();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// FIXME: }()); // END LOCAL_SCOPE
|
|
@ -70,6 +70,8 @@
|
||||||
|
|
||||||
#include "Camera.hpp"
|
#include "Camera.hpp"
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(renderperflogging)
|
||||||
|
Q_LOGGING_CATEGORY(renderperflogging, "hifi.render_perf")
|
||||||
|
|
||||||
static const QString LAST_SCENE_KEY = "lastSceneFile";
|
static const QString LAST_SCENE_KEY = "lastSceneFile";
|
||||||
static const QString LAST_LOCATION_KEY = "lastLocation";
|
static const QString LAST_LOCATION_KEY = "lastLocation";
|
||||||
|
@ -856,7 +858,6 @@ private:
|
||||||
EntityUpdateOperator updateOperator(now);
|
EntityUpdateOperator updateOperator(now);
|
||||||
//getEntities()->getTree()->recurseTreeWithOperator(&updateOperator);
|
//getEntities()->getTree()->recurseTreeWithOperator(&updateOperator);
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX("PreRenderLambdas", 0xffff0000, (uint64_t)0);
|
|
||||||
for (auto& iter : _postUpdateLambdas) {
|
for (auto& iter : _postUpdateLambdas) {
|
||||||
iter.second();
|
iter.second();
|
||||||
}
|
}
|
||||||
|
@ -899,7 +900,7 @@ private:
|
||||||
gpu::doInBatch(gpuContext, [&](gpu::Batch& batch) {
|
gpu::doInBatch(gpuContext, [&](gpu::Batch& batch) {
|
||||||
batch.resetStages();
|
batch.resetStages();
|
||||||
});
|
});
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
PROFILE_RANGE(renderperflogging, __FUNCTION__);
|
||||||
PerformanceTimer perfTimer("draw");
|
PerformanceTimer perfTimer("draw");
|
||||||
// The pending changes collecting the changes here
|
// The pending changes collecting the changes here
|
||||||
render::PendingChanges pendingChanges;
|
render::PendingChanges pendingChanges;
|
||||||
|
|
|
@ -563,7 +563,6 @@ private:
|
||||||
gpu::doInBatch(gpuContext, [&](gpu::Batch& batch) {
|
gpu::doInBatch(gpuContext, [&](gpu::Batch& batch) {
|
||||||
batch.resetStages();
|
batch.resetStages();
|
||||||
});
|
});
|
||||||
PROFILE_RANGE(__FUNCTION__);
|
|
||||||
auto framebuffer = DependencyManager::get<FramebufferCache>()->getFramebuffer();
|
auto framebuffer = DependencyManager::get<FramebufferCache>()->getFramebuffer();
|
||||||
|
|
||||||
gpu::doInBatch(gpuContext, [&](gpu::Batch& batch) {
|
gpu::doInBatch(gpuContext, [&](gpu::Batch& batch) {
|
||||||
|
|
45
tests/shared/src/TraceTests.cpp
Normal file
45
tests/shared/src/TraceTests.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/12/15
|
||||||
|
// Copyright 2013-2016 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 "TraceTests.h"
|
||||||
|
|
||||||
|
#include <QtTest/QtTest>
|
||||||
|
#include <Trace.h>
|
||||||
|
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
#include <NumericalConstants.h>
|
||||||
|
#include <../QTestExtensions.h>
|
||||||
|
|
||||||
|
QTEST_MAIN(TraceTests)
|
||||||
|
Q_LOGGING_CATEGORY(tracertestlogging, "hifi.tracer.test")
|
||||||
|
|
||||||
|
void TraceTests::testTraceSerialization() {
|
||||||
|
auto tracer = DependencyManager::set<tracing::Tracer>();
|
||||||
|
tracer->startTracing();
|
||||||
|
tracer->traceEvent(tracertestlogging(), "TestEvent", tracing::DurationBegin);
|
||||||
|
{
|
||||||
|
auto start = usecTimestampNow();
|
||||||
|
for (size_t i = 0; i < 10000; ++i) {
|
||||||
|
tracer->traceEvent(tracertestlogging(), "TestCounter", tracing::Counter, "", { { "i", i } });
|
||||||
|
}
|
||||||
|
auto duration = usecTimestampNow() - start;
|
||||||
|
duration /= USECS_PER_MSEC;
|
||||||
|
qDebug() << "Recording took " << duration << "ms";
|
||||||
|
}
|
||||||
|
tracer->traceEvent(tracertestlogging(), "TestEvent", tracing::DurationEnd);
|
||||||
|
tracer->stopTracing();
|
||||||
|
{
|
||||||
|
auto start = usecTimestampNow();
|
||||||
|
tracer->serialize("testTrace.json.gz");
|
||||||
|
auto duration = usecTimestampNow() - start;
|
||||||
|
duration /= USECS_PER_MSEC;
|
||||||
|
qDebug() << "Serialization took " << duration << "ms";
|
||||||
|
}
|
||||||
|
qDebug() << "Done";
|
||||||
|
}
|
||||||
|
|
20
tests/shared/src/TraceTests.h
Normal file
20
tests/shared/src/TraceTests.h
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 2016/12/15
|
||||||
|
// Copyright 2013-2016 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_TraceTests_h
|
||||||
|
#define hifi_TraceTests_h
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
class TraceTests : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
private slots:
|
||||||
|
void testTraceSerialization();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_TraceTests_h
|
Loading…
Reference in a new issue