Merge pull request #1227 from ZappoMan/new_voxel_scene_stats

New voxel scene stats
This commit is contained in:
Philip Rosedale 2013-11-07 18:06:57 -08:00
commit 5c219697bc
10 changed files with 344 additions and 131 deletions

View file

@ -3396,20 +3396,91 @@ void Application::displayStats() {
sprintf(avatarStats, "Avatar: pos %.3f, %.3f, %.3f, vel %.1f, yaw = %.2f", avatarPos.x, avatarPos.y, avatarPos.z, glm::length(_myAvatar.getVelocity()), _myAvatar.getBodyYaw());
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarStats);
QLocale locale(QLocale::English);
Node* avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
char avatarMixerStats[200];
if (avatarMixer) {
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
roundf(avatarMixer->getAverageKilobitsPerSecond()),
roundf(avatarMixer->getAveragePacketsPerSecond()));
} else {
sprintf(avatarMixerStats, "No Avatar Mixer");
}
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarMixerStats);
// Used for formatting voxel stats details
statsVerticalOffset += PELS_PER_LINE; // skip a line for voxels
QLocale locale(QLocale::English);
std::stringstream voxelStats;
voxelStats.precision(4);
voxelStats << "Voxels " <<
"Max: " << _voxels.getMaxVoxels() / 1000.f << "K " <<
"Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " <<
"Written: " << _voxels.getVoxelsWritten() / 1000.f << "K " <<
"Abandoned: " << _voxels.getAbandonedVoxels() / 1000.f << "K " <<
"Updated: " << _voxels.getVoxelsUpdated() / 1000.f << "K ";
// iterate all the current voxel stats, and list their sending modes, and total voxel counts
std::stringstream sendingMode("");
sendingMode << "Voxel Sending Mode: [";
int serverCount = 0;
int movingServerCount = 0;
unsigned long totalNodes = 0;
unsigned long totalInternal = 0;
unsigned long totalLeaves = 0;
for(NodeToVoxelSceneStatsIterator i = _voxelServerSceneStats.begin(); i != _voxelServerSceneStats.end(); i++) {
//const QUuid& uuid = i->first;
VoxelSceneStats& stats = i->second;
serverCount++;
if (serverCount > 1) {
sendingMode << ",";
}
if (stats.isMoving()) {
sendingMode << "M";
movingServerCount++;
} else {
sendingMode << "S";
}
// calculate server node totals
totalNodes += stats.getTotalVoxels();
totalInternal += stats.getTotalInternal();
totalLeaves += stats.getTotalLeaves();
}
if (serverCount == 0) {
sendingMode << "---";
}
sendingMode << "] " << serverCount << " servers";
if (movingServerCount > 0) {
sendingMode << " <SCENE NOT STABLE>";
} else {
sendingMode << " <SCENE STABLE>";
}
QString serversTotalString = locale.toString((uint)totalNodes); // consider adding: .rightJustified(10, ' ');
QString serversInternalString = locale.toString((uint)totalInternal);
QString serversLeavesString = locale.toString((uint)totalLeaves);
// Server Voxels
voxelStats.str("");
voxelStats <<
"Server Voxels Total: " << serversTotalString.toLocal8Bit().constData() << " / " <<
"Internal: " << serversInternalString.toLocal8Bit().constData() << " / " <<
"Leaves: " << serversLeavesString.toLocal8Bit().constData() << "";
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
unsigned long localTotal = VoxelNode::getNodeCount();
unsigned long localInternal = VoxelNode::getInternalNodeCount();
unsigned long localLeaves = VoxelNode::getLeafNodeCount();
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
QString localInternalString = locale.toString((uint)localInternal);
QString localLeavesString = locale.toString((uint)localLeaves);
// Local Voxels
voxelStats.str("");
voxelStats <<
"Local Voxels Total: " << localTotalString.toLocal8Bit().constData() << " / " <<
"Internal: " << localInternalString.toLocal8Bit().constData() << " / " <<
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
// Local Voxel Memory Usage
voxelStats.str("");
voxelStats <<
"Voxels Memory Nodes: " << VoxelNode::getTotalMemoryUsage() / 1000000.f << "MB "
@ -3421,51 +3492,25 @@ void Application::displayStats() {
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
unsigned long localTotal = VoxelNode::getNodeCount();
unsigned long localInternal = VoxelNode::getInternalNodeCount();
unsigned long localLeaves = VoxelNode::getLeafNodeCount();
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
QString localInternalString = locale.toString((uint)localInternal);
QString localLeavesString = locale.toString((uint)localLeaves);
// Voxel Rendering
voxelStats.str("");
voxelStats <<
"Local Voxels Total: " << localTotalString.toLocal8Bit().constData() << " / " <<
"Internal: " << localInternalString.toLocal8Bit().constData() << " / " <<
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
voxelStats.precision(4);
voxelStats << "Voxel Rendering Slots" <<
"Max: " << _voxels.getMaxVoxels() / 1000.f << "K " <<
"Drawn: " << _voxels.getVoxelsWritten() / 1000.f << "K " <<
"Abandoned: " << _voxels.getAbandonedVoxels() / 1000.f << "K ";
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
voxelStats.str("");
char* voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_VOXELS);
voxelStats << "Voxels Sent from Server: " << voxelDetails;
// draw Sending mode AFTER server node stats
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
voxelStats.str("");
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ELAPSED);
voxelStats << "Scene Send Time from Server: " << voxelDetails;
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
voxelStats.str("");
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ENCODE);
voxelStats << "Encode Time on Server: " << voxelDetails;
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
voxelStats.str("");
voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_MODE);
voxelStats << "Sending Mode: " << voxelDetails;
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)sendingMode.str().c_str());
// Incoming packets
voxelStats.str("");
int voxelPacketsToProcess = _voxelProcessor.packetsToProcessCount();
QString packetsString = locale.toString((int)voxelPacketsToProcess);
QString maxString = locale.toString((int)_recentMaxPackets);
voxelStats << "Voxel Packets to Process: " << packetsString.toLocal8Bit().constData()
<< " [Recent Max: " << maxString.toLocal8Bit().constData() << "]";
@ -3483,19 +3528,8 @@ void Application::displayStats() {
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)voxelStats.str().c_str());
Node *avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER);
char avatarMixerStats[200];
if (avatarMixer) {
sprintf(avatarMixerStats, "Avatar Mixer: %.f kbps, %.f pps",
roundf(avatarMixer->getAverageKilobitsPerSecond()),
roundf(avatarMixer->getAveragePacketsPerSecond()));
} else {
sprintf(avatarMixerStats, "No Avatar Mixer");
}
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarMixerStats);
// Leap data
statsVerticalOffset += PELS_PER_LINE;
drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char*)LeapManager::statusString().c_str());
@ -4075,6 +4109,10 @@ void Application::domainChanged(QString domain) {
// reset the environment so that we don't erroneously end up with multiple
_environment.resetToDefault();
// reset our node to stats and node to jurisdiction maps... since these must be changing...
_voxelServerJurisdictions.clear();
_voxelServerSceneStats.clear();
}
void Application::nodeAdded(Node* node) {
@ -4101,6 +4139,14 @@ void Application::nodeKilled(Node* node) {
fade.voxelDetails.s = fade.voxelDetails.s * slightly_smaller;
_voxelFades.push_back(fade);
}
// If the voxel server is going away, remove it from our jurisdiction map so we don't send voxels to a dead server
_voxelServerJurisdictions.erase(nodeUUID);
}
// also clean up scene stats for that server
if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) {
_voxelServerSceneStats.erase(nodeUUID);
}
} else if (node->getLinkedData() == _lookatTargetAvatar) {
_lookatTargetAvatar = NULL;
@ -4109,19 +4155,43 @@ void Application::nodeKilled(Node* node) {
int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress) {
// parse the incoming stats data, and stick it into our averaging stats object for now... even though this
// means mixing in stats from potentially multiple servers.
int statsMessageLength = _voxelSceneStats.unpackFromMessage(messageData, messageLength);
// But, also identify the sender, and keep track of the contained jurisdiction root for this server
Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress);
// parse the incoming stats datas stick it in a temporary object for now, while we
// determine which server it belongs to
VoxelSceneStats temp;
int statsMessageLength = temp.unpackFromMessage(messageData, messageLength);
// quick fix for crash... why would voxelServer be NULL?
if (voxelServer) {
QUuid nodeUUID = voxelServer->getUUID();
// now that we know the node ID, let's add these stats to the stats for that node...
if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) {
VoxelSceneStats& oldStats = _voxelServerSceneStats[nodeUUID];
// this if construct is a little strange because we aren't quite using it yet. But
// we want to keep this logic in here for now because we plan to use it soon to determine
// additional network optimization states and better rate control
if (!oldStats.isMoving() && temp.isMoving()) {
// we think we are starting to move
_voxelServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength);
} else if (oldStats.isMoving() && !temp.isMoving()) {
// we think we are done moving
_voxelServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength);
} else if (!oldStats.isMoving() && !temp.isMoving()) {
// we think we are still not moving
} else {
// we think we are still moving
}
} else {
_voxelServerSceneStats[nodeUUID] = temp;
}
VoxelPositionSize rootDetails;
voxelDetailsForCode(_voxelSceneStats.getJurisdictionRoot(), rootDetails);
voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails);
// see if this is the first we've heard of this node...
if (_voxelServerJurisdictions.find(nodeUUID) == _voxelServerJurisdictions.end()) {
@ -4142,7 +4212,7 @@ int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLeng
// but VoxelSceneStats thinks it's just returning a reference to it's contents. So we need to make a copy of the
// details from the VoxelSceneStats to construct the JurisdictionMap
JurisdictionMap jurisdictionMap;
jurisdictionMap.copyContents(_voxelSceneStats.getJurisdictionRoot(), _voxelSceneStats.getJurisdictionEndNodes());
jurisdictionMap.copyContents(temp.getJurisdictionRoot(), temp.getJurisdictionEndNodes());
_voxelServerJurisdictions[nodeUUID] = jurisdictionMap;
}
return statsMessageLength;

View file

@ -135,7 +135,7 @@ public:
QSettings* getSettings() { return _settings; }
Swatch* getSwatch() { return &_swatch; }
QMainWindow* getWindow() { return _window; }
VoxelSceneStats* getVoxelSceneStats() { return &_voxelSceneStats; }
NodeToVoxelSceneStats* getVoxelSceneStats() { return &_voxelServerSceneStats; }
QNetworkAccessManager* getNetworkAccessManager() { return _networkAccessManager; }
GeometryCache* getGeometryCache() { return &_geometryCache; }
@ -448,10 +448,10 @@ private:
PieMenu _pieMenu;
VoxelSceneStats _voxelSceneStats;
int parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress);
NodeToJurisdictionMap _voxelServerJurisdictions;
NodeToVoxelSceneStats _voxelServerSceneStats;
std::vector<VoxelFade> _voxelFades;
};

View file

@ -13,8 +13,6 @@
#include <QLabel>
#include <QSlider>
#include <VoxelSceneStats.h>
class LodToolsDialog : public QDialog {
Q_OBJECT
public:

View file

@ -14,46 +14,72 @@
#include <VoxelSceneStats.h>
#include "Application.h"
#include "ui/VoxelStatsDialog.h"
VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model) :
VoxelStatsDialog::VoxelStatsDialog(QWidget* parent, NodeToVoxelSceneStats* model) :
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint),
_model(model) {
_statCount = 0;
char strBuf[64];
for (int i = 0; i < MAX_STATS; i++) {
_labels[i] = NULL;
}
this->setWindowTitle("Voxel Statistics");
// Create layouter
QFormLayout* form = new QFormLayout();
this->QDialog::setLayout(form);
_form = new QFormLayout();
this->QDialog::setLayout(_form);
// Setup labels
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; i++) {
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
VoxelSceneStats::ItemInfo& itemInfo = _model->getItemInfo(item);
QLabel* label = _labels[item] = new QLabel();
// Setup stat items
_serverVoxels = AddStatItem("Voxels on Servers", GREENISH);
_localVoxels = AddStatItem("Local Voxels", YELLOWISH);
_localVoxelsMemory = AddStatItem("Voxels Memory", GREYISH);
_voxelsRendered = AddStatItem("Voxels Rendered", GREENISH);
_sendingMode = AddStatItem("Sending Mode", YELLOWISH);
// Set foreground color to 62.5% brightness of the meter (otherwise will be hard to read on the bright background)
QPalette palette = label->palette();
unsigned rgb = itemInfo.colorRGBA >> 8;
const unsigned colorpart1 = 0xfefefeu;
const unsigned colorpart2 = 0xf8f8f8;
rgb = ((rgb & colorpart1) >> 1) + ((rgb & colorpart2) >> 3);
palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb));
label->setPalette(palette);
const int STATS_LABEL_WIDTH = 550;
label->setFixedWidth(STATS_LABEL_WIDTH);
/** NOT YET READY
VoxelSceneStats temp;
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; i++) {
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
VoxelSceneStats::ItemInfo& itemInfo = temp.getItemInfo(item);
AddStatItem(itemInfo.caption, itemInfo.colorRGBA);
}
**/
}
snprintf(strBuf, sizeof(strBuf), " %s:", itemInfo.caption);
form->addRow(strBuf, label);
}
int VoxelStatsDialog::AddStatItem(const char* caption, unsigned colorRGBA) {
char strBuf[64];
const int STATS_LABEL_WIDTH = 550;
_statCount++; // increment our current stat count
QLabel* label = _labels[_statCount] = new QLabel();
// Set foreground color to 62.5% brightness of the meter (otherwise will be hard to read on the bright background)
QPalette palette = label->palette();
// This goofiness came from the bandwidth meter code, it basically stores a color in an unsigned and extracts it
unsigned rgb = colorRGBA >> 8;
const unsigned colorpart1 = 0xfefefeu;
const unsigned colorpart2 = 0xf8f8f8;
rgb = ((rgb & colorpart1) >> 1) + ((rgb & colorpart2) >> 3);
palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb));
label->setPalette(palette);
label->setFixedWidth(STATS_LABEL_WIDTH);
snprintf(strBuf, sizeof(strBuf), " %s:", caption);
_form->addRow(strBuf, label);
return _statCount;
}
VoxelStatsDialog::~VoxelStatsDialog() {
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; ++i) {
for (int i = 0; i < _statCount; i++) {
delete _labels[i];
}
}
@ -61,16 +87,104 @@ VoxelStatsDialog::~VoxelStatsDialog() {
void VoxelStatsDialog::paintEvent(QPaintEvent* event) {
// Update labels
char strBuf[256];
for (int i = 0; i < VoxelSceneStats::ITEM_COUNT; i++) {
VoxelSceneStats::Item item = (VoxelSceneStats::Item)(i);
QLabel* label = _labels[item];
snprintf(strBuf, sizeof(strBuf), "%s", _model->getItemValue(item));
label->setText(strBuf);
VoxelSystem* voxels = Application::getInstance()->getVoxels();
QLabel* label;
QLocale locale(QLocale::English);
std::stringstream statsValue;
statsValue.precision(4);
// Voxels Rendered
label = _labels[_voxelsRendered];
statsValue << "Max: " << voxels->getMaxVoxels() / 1000.f << "K " <<
"Drawn: " << voxels->getVoxelsWritten() / 1000.f << "K " <<
"Abandoned: " << voxels->getAbandonedVoxels() / 1000.f << "K " <<
"ReadBuffer: " << voxels->getVoxelsRendered() / 1000.f << "K " <<
"Changed: " << voxels->getVoxelsUpdated() / 1000.f << "K ";
label->setText(statsValue.str().c_str());
// Voxels Memory Usage
label = _labels[_localVoxelsMemory];
statsValue.str("");
statsValue <<
"Nodes RAM: " << VoxelNode::getTotalMemoryUsage() / 1000000.f << "MB "
"Geometry RAM: " << voxels->getVoxelMemoryUsageRAM() / 1000000.f << "MB " <<
"VBO: " << voxels->getVoxelMemoryUsageVBO() / 1000000.f << "MB ";
if (voxels->hasVoxelMemoryUsageGPU()) {
statsValue << "GPU: " << voxels->getVoxelMemoryUsageGPU() / 1000000.f << "MB ";
}
label->setText(statsValue.str().c_str());
// Local Voxels
label = _labels[_localVoxels];
unsigned long localTotal = VoxelNode::getNodeCount();
unsigned long localInternal = VoxelNode::getInternalNodeCount();
unsigned long localLeaves = VoxelNode::getLeafNodeCount();
QString localTotalString = locale.toString((uint)localTotal); // consider adding: .rightJustified(10, ' ');
QString localInternalString = locale.toString((uint)localInternal);
QString localLeavesString = locale.toString((uint)localLeaves);
statsValue.str("");
statsValue <<
"Total: " << localTotalString.toLocal8Bit().constData() << " / " <<
"Internal: " << localInternalString.toLocal8Bit().constData() << " / " <<
"Leaves: " << localLeavesString.toLocal8Bit().constData() << "";
label->setText(statsValue.str().c_str());
// iterate all the current voxel stats, and list their sending modes, total their voxels, etc...
std::stringstream sendingMode("");
int serverCount = 0;
int movingServerCount = 0;
unsigned long totalNodes = 0;
unsigned long totalInternal = 0;
unsigned long totalLeaves = 0;
NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getVoxelSceneStats();
for(NodeToVoxelSceneStatsIterator i = sceneStats->begin(); i != sceneStats->end(); i++) {
//const QUuid& uuid = i->first;
VoxelSceneStats& stats = i->second;
serverCount++;
// calculate server node totals
totalNodes += stats.getTotalVoxels();
totalInternal += stats.getTotalInternal();
totalLeaves += stats.getTotalLeaves();
// Sending mode
if (serverCount > 1) {
sendingMode << ",";
}
if (stats.isMoving()) {
sendingMode << "M";
movingServerCount++;
} else {
sendingMode << "S";
}
}
sendingMode << " - " << serverCount << " servers";
if (movingServerCount > 0) {
sendingMode << " <SCENE NOT STABLE>";
} else {
sendingMode << " <SCENE STABLE>";
}
label = _labels[_sendingMode];
label->setText(sendingMode.str().c_str());
// Server Voxels
QString serversTotalString = locale.toString((uint)totalNodes); // consider adding: .rightJustified(10, ' ');
QString serversInternalString = locale.toString((uint)totalInternal);
QString serversLeavesString = locale.toString((uint)totalLeaves);
label = _labels[_serverVoxels];
statsValue.str("");
statsValue <<
"Total: " << serversTotalString.toLocal8Bit().constData() << " / " <<
"Internal: " << serversInternalString.toLocal8Bit().constData() << " / " <<
"Leaves: " << serversLeavesString.toLocal8Bit().constData() << "";
label->setText(statsValue.str().c_str());
this->QDialog::paintEvent(event);
this->setFixedSize(this->width(), this->height());
//this->setFixedSize(this->width(), this->height());
}
void VoxelStatsDialog::reject() {

View file

@ -10,15 +10,18 @@
#define __hifi__VoxelStatsDialog__
#include <QDialog>
#include <QFormLayout>
#include <QLabel>
#include <VoxelSceneStats.h>
#define MAX_STATS 40
class VoxelStatsDialog : public QDialog {
Q_OBJECT
public:
// Sets up the UI
VoxelStatsDialog(QWidget* parent, VoxelSceneStats* model);
VoxelStatsDialog(QWidget* parent, NodeToVoxelSceneStats* model);
~VoxelStatsDialog();
signals:
@ -34,9 +37,19 @@ protected:
// Emits a 'closed' signal when this dialog is closed.
void closeEvent(QCloseEvent*);
int AddStatItem(const char* caption, unsigned colorRGBA);
private:
QLabel* _labels[VoxelSceneStats::ITEM_COUNT];
VoxelSceneStats* _model;
QFormLayout* _form;
QLabel* _labels[MAX_STATS];
NodeToVoxelSceneStats* _model;
int _statCount;
int _sendingMode;
int _serverVoxels;
int _localVoxels;
int _localVoxelsMemory;
int _voxelsRendered;
};
#endif /* defined(__interface__VoxelStatsDialog__) */

View file

@ -15,7 +15,7 @@
class SimpleMovingAverage {
public:
SimpleMovingAverage(int numSamplesToAverage);
SimpleMovingAverage(int numSamplesToAverage = 100);
int updateAverage(float sample);
void reset();
@ -30,8 +30,8 @@ private:
float _average;
float _eventDeltaAverage;
const float WEIGHTING;
const float ONE_MINUS_WEIGHTING;
float WEIGHTING;
float ONE_MINUS_WEIGHTING;
};
#endif /* defined(__hifi__Stats__) */

View file

@ -103,6 +103,7 @@ void VoxelNodeData::resetVoxelPacket() {
// the clients requested color state.
_currentPacketIsColor = (LOW_RES_MONO && getWantLowResMoving() && _viewFrustumChanging) ? false : getWantColor();
PACKET_TYPE voxelPacketType = _currentPacketIsColor ? PACKET_TYPE_VOXEL_DATA : PACKET_TYPE_VOXEL_DATA_MONOCHROME;
int numBytesPacketHeader = populateTypeAndVersion(_voxelPacket, voxelPacketType);
_voxelPacketAt = _voxelPacket + numBytesPacketHeader;
_voxelPacketAvailableBytes = MAX_VOXEL_PACKET_SIZE - numBytesPacketHeader;

View file

@ -107,6 +107,7 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int&
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(),
nodeData->getPacket(), nodeData->getPacketLength());
}
nodeData->stats.markAsSent();
} else {
// just send the voxel packet
NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(),

View file

@ -7,6 +7,9 @@
//
//
#include <QString>
#include <QStringList>
#include <PacketHeaders.h>
#include <SharedUtil.h>
@ -521,30 +524,26 @@ void VoxelSceneStats::printDebugDetails() {
qDebug(" trees removed : %lu\n", _treesRemoved );
}
const unsigned greenish = 0x40ff40d0;
const unsigned yellowish = 0xffef40c0;
const unsigned greyish = 0xd0d0d0a0;
VoxelSceneStats::ItemInfo VoxelSceneStats::_ITEMS[] = {
{ "Elapsed" , greenish },
{ "Encode" , yellowish },
{ "Network" , greyish },
{ "Voxels on Server" , greenish },
{ "Voxels Sent" , yellowish },
{ "Colors Sent" , greyish },
{ "Bitmasks Sent" , greenish },
{ "Traversed" , yellowish },
{ "Skipped - Total" , greyish },
{ "Skipped - Distance" , greenish },
{ "Skipped - Out of View", yellowish },
{ "Skipped - Was in View", greyish },
{ "Skipped - No Change" , greenish },
{ "Skipped - Occluded" , yellowish },
{ "Didn't fit in packet" , greyish },
{ "Mode" , greenish },
{ "Elapsed" , GREENISH , 2 , "Elapsed,fps" },
{ "Encode" , YELLOWISH , 2 , "Time,fps" },
{ "Network" , GREYISH , 3 , "Packets,Bytes,KBPS" },
{ "Voxels on Server" , GREENISH , 3 , "Total,Internal,Leaves" },
{ "Voxels Sent" , YELLOWISH , 5 , "Total,Bits/Voxel,Avg Bits/Voxel,Internal,Leaves" },
{ "Colors Sent" , GREYISH , 3 , "Total,Internal,Leaves" },
{ "Bitmasks Sent" , GREENISH , 3 , "Colors,Exists,In Packets" },
{ "Traversed" , YELLOWISH , 3 , "Total,Internal,Leaves" },
{ "Skipped - Total" , GREYISH , 3 , "Total,Internal,Leaves" },
{ "Skipped - Distance" , GREENISH , 3 , "Total,Internal,Leaves" },
{ "Skipped - Out of View", YELLOWISH , 3 , "Total,Internal,Leaves" },
{ "Skipped - Was in View", GREYISH , 3 , "Total,Internal,Leaves" },
{ "Skipped - No Change" , GREENISH , 3 , "Total,Internal,Leaves" },
{ "Skipped - Occluded" , YELLOWISH , 3 , "Total,Internal,Leaves" },
{ "Didn't fit in packet" , GREYISH , 4 , "Total,Internal,Leaves,Removed" },
{ "Mode" , GREENISH , 4 , "Moving,Stationary,Partial,Full" },
};
char* VoxelSceneStats::getItemValue(Item item) {
const char* VoxelSceneStats::getItemValue(Item item) {
const uint64_t USECS_PER_SECOND = 1000 * 1000;
int calcFPS, calcAverageFPS, calculatedKBPS;
switch(item) {
@ -651,3 +650,4 @@ char* VoxelSceneStats::getItemValue(Item item) {
return _itemValueBuffer;
}

View file

@ -14,6 +14,10 @@
#include <NodeList.h>
#include "JurisdictionMap.h"
#define GREENISH 0x40ff40d0
#define YELLOWISH 0xffef40c0
#define GREYISH 0xd0d0d0a0
class VoxelNode;
/// Collects statistics for calculating and sending a scene from a voxel server to an interface client
@ -114,8 +118,10 @@ public:
/// Meta information about each stats item
struct ItemInfo {
char const* const caption;
unsigned colorRGBA;
char const* const caption;
unsigned colorRGBA;
int detailsCount;
const char* detailsLabels;
};
/// Returns details about items tracked by VoxelSceneStats
@ -124,14 +130,19 @@ public:
/// Returns a UI formatted value of an item tracked by VoxelSceneStats
/// \param Item item The item from the stats you're interested in.
char* getItemValue(Item item);
const char* getItemValue(Item item);
/// Returns OctCode for root node of the jurisdiction of this particular voxel server
unsigned char* getJurisdictionRoot() const { return _jurisdictionRoot; }
/// Returns list of OctCodes for end nodes of the jurisdiction of this particular voxel server
const std::vector<unsigned char*>& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; }
bool isMoving() const { return _isMoving; };
unsigned long getTotalVoxels() const { return _totalVoxels; }
unsigned long getTotalInternal() const { return _totalInternal; }
unsigned long getTotalLeaves() const { return _totalLeaves; }
private:
bool _isReadyToSend;
unsigned char _statsMessage[MAX_PACKET_SIZE];
@ -224,4 +235,9 @@ private:
std::vector<unsigned char*> _jurisdictionEndNodes;
};
/// Map between node IDs and their reported VoxelSceneStats. Typically used by classes that need to know which nodes sent
/// which voxel stats
typedef std::map<QUuid, VoxelSceneStats> NodeToVoxelSceneStats;
typedef std::map<QUuid, VoxelSceneStats>::iterator NodeToVoxelSceneStatsIterator;
#endif /* defined(__hifi__VoxelSceneStats__) */