Working on overlays and stats

This commit is contained in:
Brad Davis 2015-06-17 02:00:13 -07:00
parent 4762e1a00c
commit 2bf53b625e
6 changed files with 306 additions and 251 deletions

View file

@ -11,19 +11,22 @@ Hifi.Stats {
readonly property int sTATS_PING_MIN_WIDTH: 190
readonly property int sTATS_GEO_MIN_WIDTH: 240
readonly property int sTATS_OCTREE_MIN_WIDTH: 410
readonly property int fontSize: 12
readonly property string fontColor: "white"
readonly property string bgColor: "#99333333"
onParentChanged: {
root.x = parent.width - root.width;
}
Row {
z: 100
id: row
spacing: 8
Rectangle {
width: generalCol.width + 8;
height: generalCol.height + 8;
color: "#99333333";
color: root.bgColor;
MouseArea {
anchors.fill: parent
@ -34,18 +37,38 @@ Hifi.Stats {
id: generalCol
spacing: 4; x: 4; y: 4;
width: sTATS_GENERAL_MIN_WIDTH
Text { color: "white"; text: "Servers: " + root.serverCount }
Text { color: "white"; text: "Avatars: " + root.avatarCount }
Text { color: "white"; text: "Framerate: " + root.framerate }
Text { color: "white"; text: "Packets In/Out: " + root.packetInCount + "/" + root.packetOutCount }
Text { color: "white"; text: "Mbps In/Out: " + root.mbpsIn.toFixed(2) + "/" + root.mbpsOut.toFixed(2) }
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
text: "Servers: " + root.serverCount
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
text: "Avatars: " + root.avatarCount
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
text: "Framerate: " + root.framerate
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
text: "Packets In/Out: " + root.packetInCount + "/" + root.packetOutCount
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
text: "Mbps In/Out: " + root.mbpsIn.toFixed(2) + "/" + root.mbpsOut.toFixed(2)
}
}
}
Rectangle {
width: pingCol.width + 8
height: pingCol.height + 8
color: "#99333333"
color: root.bgColor;
visible: root.audioPing != -2
MouseArea {
anchors.fill: parent
@ -55,45 +78,68 @@ Hifi.Stats {
id: pingCol
spacing: 4; x: 4; y: 4;
width: sTATS_PING_MIN_WIDTH
Text { color: "white"; text: "Audio ping: " + root.audioPing }
Text { color: "white"; text: "Avatar ping: " + root.avatarPing }
Text { color: "white"; text: "Entities avg ping: " + root.entitiesPing }
Text { color: "white"; text: "Voxel max ping: " + 0; visible: root.expanded; }
Text {
color: root.fontColor
font.pixelSize: root.fontSize
text: "Audio ping: " + root.audioPing
}
Text {
color: root.fontColor
font.pixelSize: root.fontSize
text: "Avatar ping: " + root.avatarPing
}
Text {
color: root.fontColor
font.pixelSize: root.fontSize
text: "Entities avg ping: " + root.entitiesPing
}
Text {
color: root.fontColor
font.pixelSize: root.fontSize
visible: root.expanded;
text: "Voxel max ping: " + 0
}
}
}
Rectangle {
width: geoCol.width
height: geoCol.height
color: "#99333333"
width: geoCol.width + 8
height: geoCol.height + 8
color: root.bgColor;
MouseArea {
anchors.fill: parent
onClicked: { root.expanded = !root.expanded; }
}
Column {
spacing: 4
id: geoCol
spacing: 4; x: 4; y: 4;
width: sTATS_GEO_MIN_WIDTH
Text {
color: "white";
color: root.fontColor;
font.pixelSize: root.fontSize
text: "Position: " + root.position.x.toFixed(1) + ", " +
root.position.y.toFixed(1) + ", " + root.position.z.toFixed(1)
}
Text {
color: "white";
color: root.fontColor;
font.pixelSize: root.fontSize
text: "Velocity: " + root.velocity.toFixed(1)
}
Text {
color: "white";
color: root.fontColor;
font.pixelSize: root.fontSize
text: "Yaw: " + root.yaw.toFixed(1)
}
Text {
color: "white";
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded;
text: "Avatar Mixer: " + root.avatarMixerKbps + " kbps, " +
root.avatarMixerPps + "pps";
}
Text {
color: "white";
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded;
text: "Downloads: ";
}
@ -102,7 +148,7 @@ Hifi.Stats {
Rectangle {
width: octreeCol.width + 8
height: octreeCol.height + 8
color: "#99333333"
color: root.bgColor;
MouseArea {
anchors.fill: parent
onClicked: { root.expanded = !root.expanded; }
@ -112,31 +158,93 @@ Hifi.Stats {
spacing: 4; x: 4; y: 4;
width: sTATS_OCTREE_MIN_WIDTH
Text {
color: "white";
color: root.fontColor;
font.pixelSize: root.fontSize
text: "Triangles: " + root.triangles +
" / Quads: " + root.quads + " / Material Switches: " + root.materialSwitches
}
Text {
color: "white";
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded;
text: "\tMesh Parts Rendered Opaque: " + root.meshOpaque +
" / Translucent: " + root.meshTranslucent;
}
Text {
color: "white";
visible: root.expanded;
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded;
text: "\tOpaque considered: " + root.opaqueConsidered +
" / Out of view: " + root.opaqueOutOfView + " / Too small: " + root.opaqueTooSmall;
}
Text {
color: "white";
color: root.fontColor;
font.pixelSize: root.fontSize
visible: !root.expanded
text: "Octree Elements Server: ";
text: "Octree Elements Server: " + root.serverElements +
" Local: " + root.localElements;
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded
text: "Octree Sending Mode: " + root.sendingMode;
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded
text: "Octree Packets to Process: " + root.packetStats;
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded
text: "Octree Elements - ";
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded
text: "\tServer: " + root.serverElements +
" Internal: " + root.serverInternal +
" Leaves: " + root.serverLeaves;
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded
text: "\tLocal: " + root.localElements +
" Internal: " + root.localInternal +
" Leaves: " + root.localLeaves;
}
Text {
color: root.fontColor;
font.pixelSize: root.fontSize
visible: root.expanded
text: "LOD: " + root.lodStatus;
}
}
}
}
Rectangle {
y: 250
width: perfText.width + 8
height: perfText.height + 8
color: root.bgColor;
anchors.top: row.bottom + 16
Text {
x: 4; y: 4
id: perfText
color: root.fontColor
font.family: "Lucida Console"
text: "-------------------------------------------------------- Function " +
"------------------------------------------------------- --msecs- -calls--\n" +
root.timingStats;
}
}
Connections {
target: root.parent
onWidthChanged: {

View file

@ -1817,6 +1817,7 @@ void Application::idle() {
targetFramePeriod = 1000.0 / targetFramerate;
}
double timeSinceLastUpdate = (double)_lastTimeUpdated.nsecsElapsed() / 1000000.0;
//if (true) {
if (timeSinceLastUpdate > targetFramePeriod) {
_lastTimeUpdated.start();
{
@ -1843,7 +1844,7 @@ void Application::idle() {
}
// After finishing all of the above work, restart the idle timer, allowing 2ms to process events.
idleTimer->start(2);
idleTimer->start(0);
}
}

View file

@ -87,7 +87,6 @@ ApplicationOverlay::~ApplicationOverlay() {
void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "ApplicationOverlay::displayOverlay()");
Stats::getInstance()->updateStats();
glm::vec2 size = qApp->getCanvasSize();
// TODO Handle fading and deactivation/activation of UI
@ -104,8 +103,7 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
//renderOverlays(renderArgs);
//renderAudioMeter(renderArgs);
//renderCameraToggle(renderArgs);
//renderStatsAndLogs(renderArgs);
renderStatsAndLogs(renderArgs);
renderDomainConnectionStatusBorder(renderArgs);
renderQmlUi(renderArgs);
@ -370,14 +368,9 @@ void ApplicationOverlay::renderStatsAndLogs(RenderArgs* renderArgs) {
// Display stats and log text onscreen
// Determine whether to compute timing details
bool shouldDisplayTimingDetail = Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails) &&
Menu::getInstance()->isOptionChecked(MenuOption::Stats); //&&
// Stats::getInstance()->isExpanded();
if (shouldDisplayTimingDetail != PerformanceTimer::isActive()) {
PerformanceTimer::setActive(shouldDisplayTimingDetail);
}
Stats::getInstance()->updateStats();
/*
// Show on-screen msec timer
if (Menu::getInstance()->isOptionChecked(MenuOption::FrameTimer)) {
auto canvasSize = qApp->getCanvasSize();
@ -401,6 +394,7 @@ void ApplicationOverlay::renderStatsAndLogs(RenderArgs* renderArgs) {
glEnable(GL_LIGHTING);
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
*/
}
void ApplicationOverlay::renderDomainConnectionStatusBorder(RenderArgs* renderArgs) {

View file

@ -13,6 +13,8 @@
#include "Stats.h"
#include <sstream>
#include <glm/glm.hpp>
#include <glm/gtx/component_wise.hpp>
#include <glm/gtx/quaternion.hpp>
@ -41,7 +43,6 @@ Stats* Stats::getInstance() {
if (!INSTANCE) {
Stats::registerType();
Stats::show();
//Stats::toggle();
Q_ASSERT(INSTANCE);
}
return INSTANCE;
@ -104,6 +105,13 @@ void Stats::updateStats() {
}
}
bool shouldDisplayTimingDetail = Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails) &&
Menu::getInstance()->isOptionChecked(MenuOption::Stats) && isExpanded();
if (shouldDisplayTimingDetail != PerformanceTimer::isActive()) {
PerformanceTimer::setActive(shouldDisplayTimingDetail);
}
auto nodeList = DependencyManager::get<NodeList>();
auto avatarManager = DependencyManager::get<AvatarManager>();
// we need to take one avatar out so we don't include ourselves
@ -144,7 +152,7 @@ void Stats::updateStats() {
pingVoxel = totalPingOctree / octreeServerCount;
}
STAT_UPDATE(entitiesPing, pingVoxel);
//STAT_UPDATE(entitiesPing, pingVoxel);
//if (_expanded) {
// QString voxelMaxPing;
// if (pingVoxel >= 0) { // Average is only meaningful if pingVoxel is valid.
@ -202,22 +210,137 @@ void Stats::updateStats() {
} // expanded avatar column
// Fourth column, octree stats
int serverCount = 0;
int movingServerCount = 0;
unsigned long totalNodes = 0;
unsigned long totalInternal = 0;
unsigned long totalLeaves = 0;
std::stringstream sendingModeStream("");
sendingModeStream << "[";
NodeToOctreeSceneStats* octreeServerSceneStats = Application::getInstance()->getOcteeSceneStats();
for (NodeToOctreeSceneStatsIterator i = octreeServerSceneStats->begin(); i != octreeServerSceneStats->end(); i++) {
//const QUuid& uuid = i->first;
OctreeSceneStats& stats = i->second;
serverCount++;
if (_expanded) {
if (serverCount > 1) {
sendingModeStream << ",";
}
if (stats.isMoving()) {
sendingModeStream << "M";
movingServerCount++;
} else {
sendingModeStream << "S";
}
}
// calculate server node totals
totalNodes += stats.getTotalElements();
if (_expanded) {
totalInternal += stats.getTotalInternal();
totalLeaves += stats.getTotalLeaves();
}
}
if (_expanded) {
if (serverCount == 0) {
sendingModeStream << "---";
}
sendingModeStream << "] " << serverCount << " servers";
if (movingServerCount > 0) {
sendingModeStream << " <SCENE NOT STABLE>";
} else {
sendingModeStream << " <SCENE STABLE>";
}
QString sendingModeResult = sendingModeStream.str().c_str();
STAT_UPDATE(sendingMode, sendingModeResult);
}
// Incoming packets
QLocale locale(QLocale::English);
auto voxelPacketsToProcess = qApp->getOctreePacketProcessor().packetsToProcessCount();
if (_expanded) {
std::stringstream octreeStats;
QString packetsString = locale.toString((int)voxelPacketsToProcess);
QString maxString = locale.toString((int)_recentMaxPackets);
octreeStats << "Octree Packets to Process: " << qPrintable(packetsString)
<< " [Recent Max: " << qPrintable(maxString) << "]";
QString str = octreeStats.str().c_str();
STAT_UPDATE(packetStats, str);
// drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
}
if (_resetRecentMaxPacketsSoon && voxelPacketsToProcess > 0) {
_recentMaxPackets = 0;
_resetRecentMaxPacketsSoon = false;
}
if (voxelPacketsToProcess == 0) {
_resetRecentMaxPacketsSoon = true;
} else if (voxelPacketsToProcess > _recentMaxPackets) {
_recentMaxPackets = voxelPacketsToProcess;
}
// Server Octree Elements
STAT_UPDATE(serverElements, totalNodes);
STAT_UPDATE(localElements, OctreeElement::getNodeCount());
if (_expanded) {
STAT_UPDATE(serverInternal, totalInternal);
STAT_UPDATE(serverLeaves, totalLeaves);
// Local Voxels
STAT_UPDATE(localInternal, OctreeElement::getInternalNodeCount());
STAT_UPDATE(localLeaves, OctreeElement::getLeafNodeCount());
// LOD Details
STAT_UPDATE(lodStatus, "You can see " + DependencyManager::get<LODManager>()->getLODFeedbackText());
}
bool performanceTimerIsActive = PerformanceTimer::isActive();
bool displayPerf = _expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails);
if (displayPerf && performanceTimerIsActive) {
PerformanceTimer::tallyAllTimerRecords(); // do this even if we're not displaying them, so they don't stack up
// we will also include room for 1 line per timing record and a header of 4 lines
// Timing details...
// First iterate all the records, and for the ones that should be included, insert them into
// a new Map sorted by average time...
bool onlyDisplayTopTen = Menu::getInstance()->isOptionChecked(MenuOption::OnlyDisplayTopTen);
QMap<float, QString> sortedRecords;
const QMap<QString, PerformanceTimerRecord>& allRecords = PerformanceTimer::getAllTimerRecords();
QMapIterator<QString, PerformanceTimerRecord> i(allRecords);
while (i.hasNext()) {
i.next();
if (includeTimingRecord(i.key())) {
float averageTime = (float)i.value().getMovingAverage() / (float)USECS_PER_MSEC;
sortedRecords.insertMulti(averageTime, i.key());
}
}
int linesDisplayed = 0;
QMapIterator<float, QString> j(sortedRecords);
j.toBack();
QString perfLines;
while (j.hasPrevious()) {
j.previous();
static const QChar noBreakingSpace = QChar::Nbsp;
QString functionName = j.value();
const PerformanceTimerRecord& record = allRecords.value(functionName);
perfLines += QString("%1: %2 [%3]\n").
arg(QString(qPrintable(functionName)), 120, noBreakingSpace).
arg((float)record.getMovingAverage() / (float)USECS_PER_MSEC, 8, 'f', 3, noBreakingSpace).
arg((int)record.getCount(), 6, 10, noBreakingSpace);
linesDisplayed++;
if (onlyDisplayTopTen && linesDisplayed == 10) {
break;
}
}
_timingStats = perfLines;
emit timingStatsChanged();
}
}
void Stats::setRenderDetails(const RenderDetails& details) {
//STATS_PROPERTY(int, triangles, 0)
//STATS_PROPERTY(int, quads, 0)
//STATS_PROPERTY(int, materialSwitches, 0)
//STATS_PROPERTY(int, meshOpaque, 0)
//STATS_PROPERTY(int, meshTranslucent, 0)
//STATS_PROPERTY(int, opaqueConsidered, 0)
//STATS_PROPERTY(int, opaqueOutOfView, 0)
//STATS_PROPERTY(int, opaqueTooSmall, 0)
//STATS_PROPERTY(int, translucentConsidered, 0)
//STATS_PROPERTY(int, translucentOutOfView, 0)
//STATS_PROPERTY(int, translucentTooSmall, 0)
//STATS_PROPERTY(int, octreeElementsServer, 0)
//STATS_PROPERTY(int, octreeElementsLocal, 0)
STAT_UPDATE(triangles, details._trianglesRendered);
STAT_UPDATE(quads, details._quadsRendered);
STAT_UPDATE(materialSwitches, details._materialSwitches);
@ -240,200 +363,8 @@ void Stats::display(
int voxelPacketsToProcess)
{
// iterate all the current voxel stats, and list their sending modes, and total voxel counts
std::stringstream sendingMode("");
sendingMode << "Octree Sending Mode: [";
int serverCount = 0;
int movingServerCount = 0;
unsigned long totalNodes = 0;
unsigned long totalInternal = 0;
unsigned long totalLeaves = 0;
NodeToOctreeSceneStats* octreeServerSceneStats = Application::getInstance()->getOcteeSceneStats();
for(NodeToOctreeSceneStatsIterator i = octreeServerSceneStats->begin(); i != octreeServerSceneStats->end(); i++) {
//const QUuid& uuid = i->first;
OctreeSceneStats& stats = i->second;
serverCount++;
if (_expanded) {
if (serverCount > 1) {
sendingMode << ",";
}
if (stats.isMoving()) {
sendingMode << "M";
movingServerCount++;
} else {
sendingMode << "S";
}
}
// calculate server node totals
totalNodes += stats.getTotalElements();
if (_expanded) {
totalInternal += stats.getTotalInternal();
totalLeaves += stats.getTotalLeaves();
}
}
if (_expanded) {
if (serverCount == 0) {
sendingMode << "---";
}
sendingMode << "] " << serverCount << " servers";
if (movingServerCount > 0) {
sendingMode << " <SCENE NOT STABLE>";
} else {
sendingMode << " <SCENE STABLE>";
}
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)sendingMode.str().c_str(), color);
}
// Incoming packets
if (_expanded) {
octreeStats.str("");
QString packetsString = locale.toString((int)voxelPacketsToProcess);
QString maxString = locale.toString((int)_recentMaxPackets);
octreeStats << "Octree Packets to Process: " << qPrintable(packetsString)
<< " [Recent Max: " << qPrintable(maxString) << "]";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
}
if (_resetRecentMaxPacketsSoon && voxelPacketsToProcess > 0) {
_recentMaxPackets = 0;
_resetRecentMaxPacketsSoon = false;
}
if (voxelPacketsToProcess == 0) {
_resetRecentMaxPacketsSoon = true;
} else {
if (voxelPacketsToProcess > _recentMaxPackets) {
_recentMaxPackets = voxelPacketsToProcess;
}
}
QString serversTotalString = locale.toString((uint)totalNodes); // consider adding: .rightJustified(10, ' ');
unsigned long localTotal = OctreeElement::getNodeCount();
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
// Server Octree Elements
if (!_expanded) {
octreeStats.str("");
octreeStats << "Octree Elements Server: " << qPrintable(serversTotalString)
<< " Local:" << qPrintable(localTotalString);
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
}
if (_expanded) {
octreeStats.str("");
octreeStats << "Octree Elements -";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
QString serversInternalString = locale.toString((uint)totalInternal);
QString serversLeavesString = locale.toString((uint)totalLeaves);
octreeStats.str("");
octreeStats << " Server: " << qPrintable(serversTotalString) <<
" Internal: " << qPrintable(serversInternalString) <<
" Leaves: " << qPrintable(serversLeavesString);
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
// Local Voxels
unsigned long localInternal = OctreeElement::getInternalNodeCount();
unsigned long localLeaves = OctreeElement::getLeafNodeCount();
QString localInternalString = locale.toString((uint)localInternal);
QString localLeavesString = locale.toString((uint)localLeaves);
octreeStats.str("");
octreeStats << " Local: " << qPrintable(serversTotalString) <<
" Internal: " << qPrintable(localInternalString) <<
" Leaves: " << qPrintable(localLeavesString) << "";
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
}
// LOD Details
octreeStats.str("");
QString displayLODDetails = DependencyManager::get<LODManager>()->getLODFeedbackText();
octreeStats << "LOD: You can see " << qPrintable(displayLODDetails.trimmed());
verticalOffset += STATS_PELS_PER_LINE;
drawText(horizontalOffset, verticalOffset, scale, rotation, font, (char*)octreeStats.str().c_str(), color);
}
//// Performance timer
bool performanceTimerIsActive = PerformanceTimer::isActive();
bool displayPerf = _expanded && Menu::getInstance()->isOptionChecked(MenuOption::DisplayDebugTimingDetails);
if (displayPerf && performanceTimerIsActive) {
PerformanceTimer::tallyAllTimerRecords(); // do this even if we're not displaying them, so they don't stack up
columnOneWidth = _generalStatsWidth + _pingStatsWidth + _geoStatsWidth; // 3 columns wide...
// we will also include room for 1 line per timing record and a header of 4 lines
lines += 4;
const QMap<QString, PerformanceTimerRecord>& allRecords = PerformanceTimer::getAllTimerRecords();
QMapIterator<QString, PerformanceTimerRecord> i(allRecords);
bool onlyDisplayTopTen = Menu::getInstance()->isOptionChecked(MenuOption::OnlyDisplayTopTen);
int statsLines = 0;
while (i.hasNext()) {
i.next();
if (includeTimingRecord(i.key())) {
lines++;
statsLines++;
if (onlyDisplayTopTen && statsLines == 10) {
break;
}
}
}
}
// TODO: the display of these timing details should all be moved to JavaScript
if (displayPerf && performanceTimerIsActive) {
bool onlyDisplayTopTen = Menu::getInstance()->isOptionChecked(MenuOption::OnlyDisplayTopTen);
// Timing details...
verticalOffset += STATS_PELS_PER_LINE * 4; // skip 3 lines to be under the other columns
drawText(columnOneHorizontalOffset, verticalOffset, scale, rotation, font,
"-------------------------------------------------------- Function "
"------------------------------------------------------- --msecs- -calls--", color);
// First iterate all the records, and for the ones that should be included, insert them into
// a new Map sorted by average time...
QMap<float, QString> sortedRecords;
const QMap<QString, PerformanceTimerRecord>& allRecords = PerformanceTimer::getAllTimerRecords();
QMapIterator<QString, PerformanceTimerRecord> i(allRecords);
while (i.hasNext()) {
i.next();
if (includeTimingRecord(i.key())) {
float averageTime = (float)i.value().getMovingAverage() / (float)USECS_PER_MSEC;
sortedRecords.insertMulti(averageTime, i.key());
}
}
int linesDisplayed = 0;
QMapIterator<float, QString> j(sortedRecords);
j.toBack();
while (j.hasPrevious()) {
j.previous();
QChar noBreakingSpace = QChar::Nbsp;
QString functionName = j.value();
const PerformanceTimerRecord& record = allRecords.value(functionName);
QString perfLine = QString("%1: %2 [%3]").
arg(QString(qPrintable(functionName)), 120, noBreakingSpace).
arg((float)record.getMovingAverage() / (float)USECS_PER_MSEC, 8, 'f', 3, noBreakingSpace).
arg((int)record.getCount(), 6, 10, noBreakingSpace);
verticalOffset += STATS_PELS_PER_LINE;
drawText(columnOneHorizontalOffset, verticalOffset, scale, rotation, font, perfLine.toUtf8().constData(), color);
linesDisplayed++;
if (onlyDisplayTopTen && linesDisplayed == 10) {
break;
}
}
}
*/

View file

@ -30,7 +30,7 @@ private: \
class Stats : public QQuickItem {
Q_OBJECT
HIFI_QML_DECL
Q_PROPERTY(bool expanded READ isExpanded NOTIFY expandedChanged)
Q_PROPERTY(bool expanded READ isExpanded WRITE setExpanded NOTIFY expandedChanged)
STATS_PROPERTY(int, serverCount, 0)
STATS_PROPERTY(int, framerate, 0)
STATS_PROPERTY(int, avatarCount, 0)
@ -61,8 +61,16 @@ class Stats : public QQuickItem {
STATS_PROPERTY(int, translucentConsidered, 0)
STATS_PROPERTY(int, translucentOutOfView, 0)
STATS_PROPERTY(int, translucentTooSmall, 0)
STATS_PROPERTY(int, octreeElementsServer, 0)
STATS_PROPERTY(int, octreeElementsLocal, 0)
STATS_PROPERTY(QString, sendingMode, QString())
STATS_PROPERTY(QString, packetStats, QString())
STATS_PROPERTY(QString, lodStatus, QString())
STATS_PROPERTY(QString, timingStats, QString())
STATS_PROPERTY(int, serverElements, 0)
STATS_PROPERTY(int, serverInternal, 0)
STATS_PROPERTY(int, serverLeaves, 0)
STATS_PROPERTY(int, localElements, 0)
STATS_PROPERTY(int, localInternal, 0)
STATS_PROPERTY(int, localLeaves, 0)
public:
static Stats* getInstance();
@ -76,8 +84,9 @@ public:
bool isExpanded() { return _expanded; }
void setExpanded(bool expanded) {
if (expanded != _expanded) {
if (_expanded != expanded) {
_expanded = expanded;
emit expandedChanged();
}
}
@ -113,8 +122,16 @@ signals:
void translucentConsideredChanged();
void translucentOutOfViewChanged();
void translucentTooSmallChanged();
void octreeElementsServerChanged();
void octreeElementsLocalChanged();
void sendingModeChanged();
void packetStatsChanged();
void lodStatusChanged();
void serverElementsChanged();
void serverInternalChanged();
void serverLeavesChanged();
void localElementsChanged();
void localInternalChanged();
void localLeavesChanged();
void timingStatsChanged();
private:
int _recentMaxPackets{ 0 } ; // recent max incoming voxel packets to process

View file

@ -11,6 +11,9 @@
#include <QOpenGLDebugLogger>
#include <QGLWidget>
#include <QtQml>
#include <PerfStat.h>
#include "AbstractViewStateInterface.h"
Q_DECLARE_LOGGING_CATEGORY(offscreenFocus)
@ -212,6 +215,7 @@ QObject* OffscreenQmlSurface::finishQmlLoad(std::function<void(QQmlContext*, QOb
void OffscreenQmlSurface::updateQuick() {
PerformanceTimer perfTimer("qmlUpdate");
if (_paused) {
return;
}