Merge branch 'master' of https://github.com/worklist/hifi into sicksense

This commit is contained in:
Andrzej Kapolka 2013-11-21 11:00:09 -08:00
commit 7bc65136c7
10 changed files with 189 additions and 36 deletions

View file

@ -4199,9 +4199,11 @@ void Application::nodeKilled(Node* node) {
}
// also clean up scene stats for that server
_voxelSceneStatsLock.lockForWrite();
if (_voxelServerSceneStats.find(nodeUUID) != _voxelServerSceneStats.end()) {
_voxelServerSceneStats.erase(nodeUUID);
}
_voxelSceneStatsLock.unlock();
} else if (node->getLinkedData() == _lookatTargetAvatar) {
_lookatTargetAvatar = NULL;
}
@ -4222,27 +4224,13 @@ int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLeng
QUuid nodeUUID = voxelServer->getUUID();
// now that we know the node ID, let's add these stats to the stats for that node...
_voxelSceneStatsLock.lockForWrite();
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
}
_voxelServerSceneStats[nodeUUID].unpackFromMessage(messageData, messageLength);
} else {
_voxelServerSceneStats[nodeUUID] = temp;
}
_voxelSceneStatsLock.unlock();
VoxelPositionSize rootDetails;
voxelDetailsForCode(temp.getJurisdictionRoot(), rootDetails);

View file

@ -137,6 +137,8 @@ public:
Swatch* getSwatch() { return &_swatch; }
QMainWindow* getWindow() { return _window; }
NodeToVoxelSceneStats* getVoxelSceneStats() { return &_voxelServerSceneStats; }
void lockVoxelSceneStats() { _voxelSceneStatsLock.lockForRead(); }
void unlockVoxelSceneStats() { _voxelSceneStatsLock.unlock(); }
QNetworkAccessManager* getNetworkAccessManager() { return _networkAccessManager; }
GeometryCache* getGeometryCache() { return &_geometryCache; }
@ -458,6 +460,7 @@ private:
NodeToJurisdictionMap _voxelServerJurisdictions;
NodeToVoxelSceneStats _voxelServerSceneStats;
QReadWriteLock _voxelSceneStatsLock;
std::vector<VoxelFade> _voxelFades;
};

View file

@ -72,7 +72,8 @@ Menu::Menu() :
MenuOption::AboutApp,
0,
this,
SLOT(aboutApp()));
SLOT(aboutApp()),
QAction::AboutRole);
#endif
(addActionToQMenuAndActionHash(fileMenu,
@ -120,7 +121,9 @@ Menu::Menu() :
MenuOption::Quit,
Qt::CTRL | Qt::Key_Q,
appInstance,
SLOT(quit()));
SLOT(quit()),
QAction::QuitRole);
QMenu* editMenu = addMenu("Edit");
@ -128,7 +131,8 @@ Menu::Menu() :
MenuOption::Preferences,
Qt::CTRL | Qt::Key_Comma,
this,
SLOT(editPreferences()));
SLOT(editPreferences()),
QAction::PreferencesRole);
addDisabledActionAndSeparator(editMenu, "Voxels");
@ -681,7 +685,8 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString actionName,
const QKeySequence& shortcut,
const QObject* receiver,
const char* member) {
const char* member,
QAction::MenuRole role) {
QAction* action;
if (receiver && member) {
@ -690,6 +695,7 @@ QAction* Menu::addActionToQMenuAndActionHash(QMenu* destinationMenu,
action = destinationMenu->addAction(actionName);
action->setShortcut(shortcut);
}
action->setMenuRole(role);
_actionHash.insert(actionName, action);

View file

@ -113,7 +113,9 @@ private:
const QString actionName,
const QKeySequence& shortcut = 0,
const QObject* receiver = NULL,
const char* member = NULL);
const char* member = NULL,
QAction::MenuRole role = QAction::NoRole);
QAction* addCheckableActionToQMenuAndActionHash(QMenu* destinationMenu,
const QString actionName,
const QKeySequence& shortcut = 0,

View file

@ -154,6 +154,8 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) {
unsigned long totalNodes = 0;
unsigned long totalInternal = 0;
unsigned long totalLeaves = 0;
Application::getInstance()->lockVoxelSceneStats();
NodeToVoxelSceneStats* sceneStats = Application::getInstance()->getVoxelSceneStats();
for(NodeToVoxelSceneStatsIterator i = sceneStats->begin(); i != sceneStats->end(); i++) {
//const QUuid& uuid = i->first;
@ -176,6 +178,7 @@ void VoxelStatsDialog::paintEvent(QPaintEvent* event) {
sendingMode << "S";
}
}
Application::getInstance()->unlockVoxelSceneStats();
sendingMode << " - " << serverCount << " servers";
if (movingServerCount > 0) {
sendingMode << " <SCENE NOT STABLE>";

View file

@ -189,17 +189,22 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) {
// display voxel file load time
if (theServer->isInitialLoadComplete()) {
tm* voxelsLoadedAtLocal = localtime(theServer->getLoadCompleted());
const int MAX_TIME_LENGTH = 128;
char buffer[MAX_TIME_LENGTH];
strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", voxelsLoadedAtLocal);
mg_printf(connection, "Voxels Loaded At: %s", buffer);
time_t* loadCompleted = theServer->getLoadCompleted();
if (loadCompleted) {
tm* voxelsLoadedAtLocal = localtime(loadCompleted);
const int MAX_TIME_LENGTH = 128;
char buffer[MAX_TIME_LENGTH];
strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", voxelsLoadedAtLocal);
mg_printf(connection, "Voxels Loaded At: %s", buffer);
// Convert now to tm struct for UTC
tm* voxelsLoadedAtUTM = gmtime(theServer->getLoadCompleted());
if (gmtm != NULL) {
strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", voxelsLoadedAtUTM);
mg_printf(connection, " [%s UTM] ", buffer);
// Convert now to tm struct for UTC
tm* voxelsLoadedAtUTM = gmtime(theServer->getLoadCompleted());
if (gmtm != NULL) {
strftime(buffer, MAX_TIME_LENGTH, "%m/%d/%Y %X", voxelsLoadedAtUTM);
mg_printf(connection, " [%s UTM] ", buffer);
}
} else {
mg_printf(connection, "%s", "Voxel Persist Disabled...\r\n");
}
mg_printf(connection, "%s", "\r\n");
@ -259,7 +264,7 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) {
// display inbound packet stats
mg_printf(connection, "%s", "<b>Voxel Edit Statistics... <a href='/resetStats'>[RESET]</a></b>\r\n");
uint64_t averageTransitTimePerPacket = theServer->_voxelServerPacketProcessor->getAverateTransitTimePerPacket();
uint64_t averageTransitTimePerPacket = theServer->_voxelServerPacketProcessor->getAverageTransitTimePerPacket();
uint64_t averageProcessTimePerPacket = theServer->_voxelServerPacketProcessor->getAverageProcessTimePerPacket();
uint64_t averageLockWaitTimePerPacket = theServer->_voxelServerPacketProcessor->getAverageLockWaitTimePerPacket();
uint64_t averageProcessTimePerVoxel = theServer->_voxelServerPacketProcessor->getAverageProcessTimePerVoxel();
@ -297,7 +302,7 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) {
mg_printf(connection, "\r\n Stats for sender %d uuid: %s\r\n", senderNumber,
senderID.toString().toLocal8Bit().constData());
averageTransitTimePerPacket = senderStats.getAverateTransitTimePerPacket();
averageTransitTimePerPacket = senderStats.getAverageTransitTimePerPacket();
averageProcessTimePerPacket = senderStats.getAverageProcessTimePerPacket();
averageLockWaitTimePerPacket = senderStats.getAverageLockWaitTimePerPacket();
averageProcessTimePerVoxel = senderStats.getAverageProcessTimePerVoxel();
@ -305,6 +310,8 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) {
totalVoxelsProcessed = senderStats.getTotalVoxelsProcessed();
totalPacketsProcessed = senderStats.getTotalPacketsProcessed();
averageVoxelsPerPacket = totalPacketsProcessed == 0 ? 0 : totalVoxelsProcessed / totalPacketsProcessed;
mg_printf(connection, " Total Inbound Packets: %s packets\r\n",
locale.toString((uint)totalPacketsProcessed).rightJustified(COLUMN_WIDTH, ' ').toLocal8Bit().constData());
mg_printf(connection, " Total Inbound Voxels: %s voxels\r\n",

View file

@ -20,7 +20,7 @@ class SingleSenderStats {
public:
SingleSenderStats();
uint64_t getAverateTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
uint64_t getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
uint64_t getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
uint64_t getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
uint64_t getTotalVoxelsProcessed() const { return _totalVoxelsInPacket; }
@ -48,7 +48,7 @@ class VoxelServerPacketProcessor : public ReceivedPacketProcessor {
public:
VoxelServerPacketProcessor(VoxelServer* myServer);
uint64_t getAverateTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
uint64_t getAverageTransitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalTransitTime / _totalPackets; }
uint64_t getAverageProcessTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalProcessTime / _totalPackets; }
uint64_t getAverageLockWaitTimePerPacket() const { return _totalPackets == 0 ? 0 : _totalLockWaitTime / _totalPackets; }
uint64_t getTotalVoxelsProcessed() const { return _totalVoxelsInPacket; }

View file

@ -28,6 +28,97 @@ VoxelSceneStats::VoxelSceneStats() :
_isStarted = false;
}
// copy constructor
VoxelSceneStats::VoxelSceneStats(const VoxelSceneStats& other) :
_jurisdictionRoot(NULL) {
copyFromOther(other);
}
// copy assignment
VoxelSceneStats& VoxelSceneStats::operator=(const VoxelSceneStats& other) {
copyFromOther(other);
return *this;
}
void VoxelSceneStats::copyFromOther(const VoxelSceneStats& other) {
_totalEncodeTime = other._totalEncodeTime;
_encodeStart = other._encodeStart;
_packets = other._packets;
_bytes = other._bytes;
_passes = other._passes;
_totalVoxels = other._totalVoxels;
_totalInternal = other._totalInternal;
_totalLeaves = other._totalLeaves;
_traversed = other._traversed;
_internal = other._internal;
_leaves = other._leaves;
_skippedDistance = other._skippedDistance;
_internalSkippedDistance = other._internalSkippedDistance;
_leavesSkippedDistance = other._leavesSkippedDistance;
_skippedOutOfView = other._skippedOutOfView;
_internalSkippedOutOfView = other._internalSkippedOutOfView;
_leavesSkippedOutOfView = other._leavesSkippedOutOfView;
_skippedWasInView = other._skippedWasInView;
_internalSkippedWasInView = other._internalSkippedWasInView;
_leavesSkippedWasInView = other._leavesSkippedWasInView;
_skippedNoChange = other._skippedNoChange;
_internalSkippedNoChange = other._internalSkippedNoChange;
_leavesSkippedNoChange = other._leavesSkippedNoChange;
_skippedOccluded = other._skippedOccluded;
_internalSkippedOccluded = other._internalSkippedOccluded;
_leavesSkippedOccluded = other._leavesSkippedOccluded;
_colorSent = other._colorSent;
_internalColorSent = other._internalColorSent;
_leavesColorSent = other._leavesColorSent;
_didntFit = other._didntFit;
_internalDidntFit = other._internalDidntFit;
_leavesDidntFit = other._leavesDidntFit;
_colorBitsWritten = other._colorBitsWritten;
_existsBitsWritten = other._existsBitsWritten;
_existsInPacketBitsWritten = other._existsInPacketBitsWritten;
_treesRemoved = other._treesRemoved;
// before copying the jurisdictions, delete any current values...
if (_jurisdictionRoot) {
delete[] _jurisdictionRoot;
_jurisdictionRoot = NULL;
}
for (int i=0; i < _jurisdictionEndNodes.size(); i++) {
if (_jurisdictionEndNodes[i]) {
delete[] _jurisdictionEndNodes[i];
}
}
_jurisdictionEndNodes.clear();
// Now copy the values from the other
if (other._jurisdictionRoot) {
int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(other._jurisdictionRoot));
_jurisdictionRoot = new unsigned char[bytes];
memcpy(_jurisdictionRoot, other._jurisdictionRoot, bytes);
}
for (int i=0; i < other._jurisdictionEndNodes.size(); i++) {
unsigned char* endNodeCode = other._jurisdictionEndNodes[i];
if (endNodeCode) {
int bytes = bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(endNodeCode));
unsigned char* endNodeCodeCopy = new unsigned char[bytes];
memcpy(endNodeCodeCopy, endNodeCode, bytes);
_jurisdictionEndNodes.push_back(endNodeCodeCopy);
}
}
}
VoxelSceneStats::~VoxelSceneStats() {
reset();
}
@ -48,6 +139,15 @@ void VoxelSceneStats::sceneStarted(bool isFullScene, bool isMoving, VoxelNode* r
delete[] _jurisdictionRoot;
_jurisdictionRoot = NULL;
}
// clear existing endNodes before copying new ones...
for (int i=0; i < _jurisdictionEndNodes.size(); i++) {
if (_jurisdictionEndNodes[i]) {
delete[] _jurisdictionEndNodes[i];
}
}
_jurisdictionEndNodes.clear();
// setup jurisdictions
if (jurisdictionMap) {
unsigned char* jurisdictionRoot = jurisdictionMap->getRootOctalCode();
if (jurisdictionRoot) {
@ -56,6 +156,7 @@ void VoxelSceneStats::sceneStarted(bool isFullScene, bool isMoving, VoxelNode* r
memcpy(_jurisdictionRoot, jurisdictionRoot, bytes);
}
// copy new endNodes...
for (int i=0; i < jurisdictionMap->getEndNodeCount(); i++) {
unsigned char* endNodeCode = jurisdictionMap->getEndNodeOctalCode(i);
if (endNodeCode) {
@ -436,6 +537,20 @@ int VoxelSceneStats::unpackFromMessage(unsigned char* sourceBuffer, int availabl
memcpy(&_treesRemoved, sourceBuffer, sizeof(_treesRemoved));
sourceBuffer += sizeof(_treesRemoved);
// before allocating new juridiction, clean up existing ones
if (_jurisdictionRoot) {
delete[] _jurisdictionRoot;
_jurisdictionRoot = NULL;
}
// clear existing endNodes before copying new ones...
for (int i=0; i < _jurisdictionEndNodes.size(); i++) {
if (_jurisdictionEndNodes[i]) {
delete[] _jurisdictionEndNodes[i];
}
}
_jurisdictionEndNodes.clear();
// read the root jurisdiction
int bytes = 0;
memcpy(&bytes, sourceBuffer, sizeof(bytes));

View file

@ -27,6 +27,9 @@ public:
~VoxelSceneStats();
void reset();
VoxelSceneStats(const VoxelSceneStats& other); // copy constructor
VoxelSceneStats& operator= (const VoxelSceneStats& other); // copy assignment
/// Call when beginning the computation of a scene. Initializes internal structures
void sceneStarted(bool fullScene, bool moving, VoxelNode* root, JurisdictionMap* jurisdictionMap);
@ -144,6 +147,9 @@ public:
unsigned long getTotalLeaves() const { return _totalLeaves; }
private:
void copyFromOther(const VoxelSceneStats& other);
bool _isReadyToSend;
unsigned char _statsMessage[MAX_PACKET_SIZE];
int _statsMessageLength;

View file

@ -272,7 +272,30 @@ int main(int argc, const char * argv[])
} else {
qDebug() << "Unexpected number of parameters for getOctCode\n";
}
return 0;
}
const char* DECODE_OCTCODE = "--decodeOctCode";
const char* decodeParam = getCmdOption(argc, argv, DECODE_OCTCODE);
if (decodeParam) {
QString decodeParamsString(decodeParam);
unsigned char* octalCodeToDecode = hexStringToOctalCode(decodeParamsString);
VoxelPositionSize details;
voxelDetailsForCode(octalCodeToDecode, details);
delete[] octalCodeToDecode;
qDebug() << "octal code to decode: " << decodeParamsString << "\n";
qDebug() << "Details for Octal Code:\n";
qDebug() << " x:" << details.x << "[" << details.x * TREE_SCALE << "]" << "\n";
qDebug() << " y:" << details.y << "[" << details.y * TREE_SCALE << "]" << "\n";
qDebug() << " z:" << details.z << "[" << details.z * TREE_SCALE << "]" << "\n";
qDebug() << " s:" << details.s << "[" << details.s * TREE_SCALE << "]" << "\n";
return 0;
}
// Handles taking and SVO and splitting it into multiple SVOs based on
// jurisdiction details