From 6f9fdfba2fc001a175cf271adee235a50fc78da4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 14 Oct 2013 11:39:48 -0700 Subject: [PATCH 1/6] make mouse cursor hiding more aware of focused window and bounds --- interface/src/Application.cpp | 24 ++++++++++++++++++------ interface/src/Application.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9afb269f1b..81e40cc109 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -107,6 +107,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _mouseY(0), _lastMouseMove(usecTimestampNow()), _mouseHidden(false), + _seenMouseMove(false), _touchAvgX(0.0f), _touchAvgY(0.0f), _isTouchPressed(false), @@ -988,6 +989,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) { if (_mouseHidden) { getGLWidget()->setCursor(Qt::ArrowCursor); _mouseHidden = false; + _seenMouseMove = true; } if (activeWindow() == _window) { @@ -2133,12 +2135,22 @@ void Application::update(float deltaTime) { #endif // watch mouse position, if it hasn't moved, hide the cursor - uint64_t now = usecTimestampNow(); - int elapsed = now - _lastMouseMove; - const int HIDE_CURSOR_TIMEOUT = 1 * 1000 * 1000; // 1 second - if (elapsed > HIDE_CURSOR_TIMEOUT) { - getGLWidget()->setCursor(Qt::BlankCursor); - _mouseHidden = true; + bool underMouse = _glWidget->underMouse(); + if (!_mouseHidden) { + uint64_t now = usecTimestampNow(); + int elapsed = now - _lastMouseMove; + const int HIDE_CURSOR_TIMEOUT = 1 * 1000 * 1000; // 1 second + if (elapsed > HIDE_CURSOR_TIMEOUT && (underMouse || !_seenMouseMove)) { + getGLWidget()->setCursor(Qt::BlankCursor); + _mouseHidden = true; + } + } else { + // if the mouse is hidden, but we're not inside our window, then consider ourselves to be moving + if (!underMouse && _seenMouseMove) { + _lastMouseMove = usecTimestampNow(); + getGLWidget()->setCursor(Qt::ArrowCursor); + _mouseHidden = false; + } } } diff --git a/interface/src/Application.h b/interface/src/Application.h index cb3a3ca73d..595f337bf5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -307,6 +307,7 @@ private: int _mouseDragStartedY; uint64_t _lastMouseMove; bool _mouseHidden; + bool _seenMouseMove; float _touchAvgX; float _touchAvgY; From 342568511948ddabd4ce0ca58efc510b6c02904b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 14 Oct 2013 12:09:44 -0700 Subject: [PATCH 2/6] first cut at added voxel node memory usage debugging to client and server --- interface/src/Application.cpp | 5 +- libraries/voxel-server-library/CMakeLists.txt | 5 ++ .../voxel-server-library/src/VoxelServer.cpp | 46 +++++++++++++++++++ .../voxel-server-library/src/VoxelServer.h | 7 +++ libraries/voxels/src/VoxelNode.cpp | 8 ++++ libraries/voxels/src/VoxelNode.h | 3 ++ 6 files changed, 72 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 81e40cc109..070062f164 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2993,14 +2993,15 @@ void Application::displayStats() { drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); - voxelStats << "Voxels Memory RAM: " << _voxels.getVoxelMemoryUsageRAM() / 1000000.f << "MB " << + voxelStats << "Voxels Memory Nodes: " << VoxelNode::getVoxelMemoryUsage() / 1000000.f << "MB " + "Geometry RAM: " << _voxels.getVoxelMemoryUsageRAM() / 1000000.f << "MB " << "VBO: " << _voxels.getVoxelMemoryUsageVBO() / 1000000.f << "MB "; if (_voxels.hasVoxelMemoryUsageGPU()) { voxelStats << "GPU: " << _voxels.getVoxelMemoryUsageGPU() / 1000000.f << "MB "; } drawtext(10, statsVerticalOffset + 250, 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; diff --git a/libraries/voxel-server-library/CMakeLists.txt b/libraries/voxel-server-library/CMakeLists.txt index 9eabb95508..1298ef1bae 100644 --- a/libraries/voxel-server-library/CMakeLists.txt +++ b/libraries/voxel-server-library/CMakeLists.txt @@ -18,6 +18,11 @@ qt5_use_modules(${TARGET_NAME} Widgets) include(${MACRO_DIR}/IncludeGLM.cmake) include_glm(${TARGET_NAME} ${ROOT_DIR}) +# setup a library for civetweb and link it to the voxel-server-library +# this assumes that the domain-server cmake has already correctly set up the civetweb library +include_directories(../../domain-server/external/civetweb/include) +target_link_libraries(${TARGET_NAME} civetweb) + include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index aeda7cf277..07a0b65c57 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -70,6 +70,7 @@ VoxelServer::VoxelServer(Assignment::Command command, Assignment::Location locat _parsedArgV = NULL; } + VoxelServer::VoxelServer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes), _serverTree(true) { _argc = 0; @@ -101,6 +102,43 @@ VoxelServer::~VoxelServer() { } } +void VoxelServer::initMongoose(int port) { + // setup the mongoose web server + struct mg_callbacks callbacks = {}; + + QString documentRoot = QString("%1/resources/web").arg(QCoreApplication::applicationDirPath()); + QString listenPort = QString("%1").arg(port); + + + // list of options. Last element must be NULL. + const char* options[] = { + "listening_ports", listenPort.toLocal8Bit().constData(), + "document_root", documentRoot.toLocal8Bit().constData(), + NULL }; + + callbacks.begin_request = civetwebRequestHandler; + + // Start the web server. + mg_start(&callbacks, NULL, options); +} + +int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { + const struct mg_request_info* ri = mg_get_request_info(connection); + + if (strcmp(ri->uri, "/") == 0 && strcmp(ri->request_method, "GET") == 0) { + // return a 200 + mg_printf(connection, "%s", "HTTP/1.0 200 OK\r\n\r\n"); + mg_printf(connection, "%s", "Your Voxel Server is running.\r\n"); + mg_printf(connection, "%s", "Current Statistics\r\n"); + mg_printf(connection, "Voxel Node Memory Usage: %f MB\r\n", VoxelNode::getVoxelMemoryUsage() / 1000000.f); + return 1; + } else { + // have mongoose process this request from the document_root + return 0; + } +} + + void VoxelServer::setArguments(int argc, char** argv) { _argc = argc; _argv = const_cast(argv); @@ -157,6 +195,14 @@ void VoxelServer::run() { qInstallMessageHandler(Logging::verboseMessageHandler); + const char* STATUS_PORT = "--statusPort"; + const char* statusPort = getCmdOption(_argc, _argv, STATUS_PORT); + if (statusPort) { + int statusPortNumber = atoi(statusPort); + initMongoose(statusPortNumber); + } + + const char* JURISDICTION_FILE = "--jurisdictionFile"; const char* jurisdictionFile = getCmdOption(_argc, _argv, JURISDICTION_FILE); if (jurisdictionFile) { diff --git a/libraries/voxel-server-library/src/VoxelServer.h b/libraries/voxel-server-library/src/VoxelServer.h index 464938706e..c05a2037c1 100644 --- a/libraries/voxel-server-library/src/VoxelServer.h +++ b/libraries/voxel-server-library/src/VoxelServer.h @@ -10,7 +10,10 @@ #ifndef __voxel_server__VoxelServer__ #define __voxel_server__VoxelServer__ +#include "../../domain-server/external/civetweb/include/civetweb.h" + #include +#include #include #include @@ -82,6 +85,10 @@ private: NodeWatcher _nodeWatcher; // used to cleanup AGENT data when agents are killed void parsePayload(); + + void initMongoose(int port); + + static int civetwebRequestHandler(struct mg_connection *connection); }; #endif // __voxel_server__VoxelServer__ diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index a7675f4609..154d573836 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -21,6 +21,8 @@ #include "VoxelNode.h" #include "VoxelTree.h" +uint64_t VoxelNode::_voxelMemoryUsage = 0; + VoxelNode::VoxelNode() { unsigned char* rootCode = new unsigned char[1]; *rootCode = 0; @@ -56,11 +58,17 @@ void VoxelNode::init(unsigned char * octalCode) { _sourceID = UNKNOWN_NODE_ID; calculateAABox(); markWithChangedTime(); + + _voxelMemoryUsage += sizeof(VoxelNode); + _voxelMemoryUsage += bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_octalCode)); } VoxelNode::~VoxelNode() { notifyDeleteHooks(); + _voxelMemoryUsage -= sizeof(VoxelNode); + _voxelMemoryUsage -= bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_octalCode)); + delete[] _octalCode; // delete all of this node's children diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index 9664b33a29..6a92ab1e42 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -127,6 +127,8 @@ public: unsigned long getSubTreeInternalNodeCount() const { return _subtreeNodeCount - _subtreeLeafNodeCount; } unsigned long getSubTreeLeafNodeCount() const { return _subtreeLeafNodeCount; } + static uint64_t getVoxelMemoryUsage() { return _voxelMemoryUsage; } + private: void calculateAABox(); void init(unsigned char * octalCode); @@ -154,6 +156,7 @@ private: static std::vector _deleteHooks; static std::vector _updateHooks; + static uint64_t _voxelMemoryUsage; }; #endif /* defined(__hifi__VoxelNode__) */ From 1513003ecd2ab6a72cf876051c219843e3565e88 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 14 Oct 2013 12:20:50 -0700 Subject: [PATCH 3/6] added more stats to voxel server status --- .../voxel-server-library/src/VoxelServer.cpp | 17 +++++++++++++++++ .../voxel-server-library/src/VoxelServer.h | 5 +++++ 2 files changed, 22 insertions(+) diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index 07a0b65c57..8aa88420d2 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -47,6 +47,8 @@ void attachVoxelNodeDataToNode(Node* newNode) { } } +VoxelServer* VoxelServer::_theInstance = NULL; + VoxelServer::VoxelServer(Assignment::Command command, Assignment::Location location) : Assignment(command, Assignment::VoxelServerType, location), _serverTree(true) { @@ -68,6 +70,8 @@ VoxelServer::VoxelServer(Assignment::Command command, Assignment::Location locat _voxelServerPacketProcessor = NULL; _voxelPersistThread = NULL; _parsedArgV = NULL; + + _theInstance = this; } @@ -91,6 +95,8 @@ VoxelServer::VoxelServer(const unsigned char* dataBuffer, int numBytes) : Assign _voxelServerPacketProcessor = NULL; _voxelPersistThread = NULL; _parsedArgV = NULL; + + _theInstance = this; } VoxelServer::~VoxelServer() { @@ -131,6 +137,17 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { mg_printf(connection, "%s", "Your Voxel Server is running.\r\n"); mg_printf(connection, "%s", "Current Statistics\r\n"); mg_printf(connection, "Voxel Node Memory Usage: %f MB\r\n", VoxelNode::getVoxelMemoryUsage() / 1000000.f); + + VoxelTree* theTree = VoxelServer::GetInstance()->getTree(); + unsigned long nodeCount = theTree->rootNode->getSubTreeNodeCount(); + unsigned long internalNodeCount = theTree->rootNode->getSubTreeInternalNodeCount(); + unsigned long leafNodeCount = theTree->rootNode->getSubTreeLeafNodeCount(); + + mg_printf(connection, "%s", "Current Nodes in scene\r\n"); + mg_printf(connection, " Total Nodes: %lu nodes\r\n", nodeCount); + mg_printf(connection, " Internal Nodes: %lu nodes\r\n", internalNodeCount); + mg_printf(connection, " Leaf Nodes: %lu leaves\r\n", leafNodeCount); + return 1; } else { // have mongoose process this request from the document_root diff --git a/libraries/voxel-server-library/src/VoxelServer.h b/libraries/voxel-server-library/src/VoxelServer.h index c05a2037c1..a52abaec07 100644 --- a/libraries/voxel-server-library/src/VoxelServer.h +++ b/libraries/voxel-server-library/src/VoxelServer.h @@ -52,12 +52,15 @@ public: void lockTree() { pthread_mutex_lock(&_treeLock); } void unlockTree() { pthread_mutex_unlock(&_treeLock); } + VoxelTree* getTree() { return &_serverTree; } int getPacketsPerClientPerInterval() const { return _packetsPerClientPerInterval; } bool getSendMinimalEnvironment() const { return _sendMinimalEnvironment; } EnvironmentData* getEnvironmentData(int i) { return &_environmentData[i]; } int getEnvironmentDataCount() const { return sizeof(_environmentData)/sizeof(EnvironmentData); } + static VoxelServer* GetInstance() { return _theInstance; } + private: int _argc; const char** _argv; @@ -89,6 +92,8 @@ private: void initMongoose(int port); static int civetwebRequestHandler(struct mg_connection *connection); + static VoxelServer* _theInstance; + }; #endif // __voxel_server__VoxelServer__ From f0fc973db12030aee369b2c985047b7e7b08224d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 14 Oct 2013 12:42:15 -0700 Subject: [PATCH 4/6] move loading of voxel file to the persist thread so that assignment client will load voxel server faster --- .../src/VoxelPersistThread.cpp | 31 +++++++++++++++++-- .../src/VoxelPersistThread.h | 1 + .../voxel-server-library/src/VoxelServer.cpp | 24 +++----------- 3 files changed, 33 insertions(+), 23 deletions(-) diff --git a/libraries/voxel-server-library/src/VoxelPersistThread.cpp b/libraries/voxel-server-library/src/VoxelPersistThread.cpp index ca40316d28..8ad2bfaa4d 100644 --- a/libraries/voxel-server-library/src/VoxelPersistThread.cpp +++ b/libraries/voxel-server-library/src/VoxelPersistThread.cpp @@ -8,7 +8,9 @@ // Threaded or non-threaded voxel persistence // +#include #include +#include #include #include "VoxelPersistThread.h" @@ -17,20 +19,43 @@ VoxelPersistThread::VoxelPersistThread(VoxelTree* tree, const char* filename, int persistInterval) : _tree(tree), _filename(filename), - _persistInterval(persistInterval) { + _persistInterval(persistInterval), + _initialLoad(false) { } bool VoxelPersistThread::process() { + + if (!_initialLoad) { + _initialLoad = true; + qDebug("loading voxels from file: %s...\n", _filename); + + bool persistantFileRead = _tree->readFromSVOFile(_filename); + if (persistantFileRead) { + PerformanceWarning warn(true, "reaverageVoxelColors()", true); + + // after done inserting all these voxels, then reaverage colors + _tree->reaverageVoxelColors(_tree->rootNode); + qDebug("Voxels reAveraged\n"); + } + + _tree->clearDirtyBit(); // the tree is clean since we just loaded it + qDebug("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead)); + unsigned long nodeCount = _tree->rootNode->getSubTreeNodeCount(); + unsigned long internalNodeCount = _tree->rootNode->getSubTreeInternalNodeCount(); + unsigned long leafNodeCount = _tree->rootNode->getSubTreeLeafNodeCount(); + qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount); + } + uint64_t MSECS_TO_USECS = 1000; usleep(_persistInterval * MSECS_TO_USECS); // check the dirty bit and persist here... if (_tree->isDirty()) { - printf("saving voxels to file %s...\n",_filename); + qDebug("saving voxels to file %s...\n",_filename); _tree->writeToSVOFile(_filename); _tree->clearDirtyBit(); // tree is clean after saving - printf("DONE saving voxels to file...\n"); + qDebug("DONE saving voxels to file...\n"); } return isStillRunning(); // keep running till they terminate us diff --git a/libraries/voxel-server-library/src/VoxelPersistThread.h b/libraries/voxel-server-library/src/VoxelPersistThread.h index 68487da182..3219633702 100644 --- a/libraries/voxel-server-library/src/VoxelPersistThread.h +++ b/libraries/voxel-server-library/src/VoxelPersistThread.h @@ -28,6 +28,7 @@ private: VoxelTree* _tree; const char* _filename; int _persistInterval; + bool _initialLoad; }; #endif // __voxel_server__VoxelPersistThread__ diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index 8aa88420d2..e4517672a0 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -300,8 +300,7 @@ void VoxelServer::run() { } qDebug("wantVoxelPersist=%s\n", debug::valueOf(_wantVoxelPersist)); - // if we want Voxel Persistence, load the local file now... - bool persistantFileRead = false; + // if we want Voxel Persistence, set up the local file and persist thread if (_wantVoxelPersist) { // Check to see if the user passed in a command line option for setting packet send rate @@ -314,25 +313,8 @@ void VoxelServer::run() { strcpy(_voxelPersistFilename, LOCAL_VOXELS_PERSIST_FILE); } - qDebug("loading voxels from file: %s...\n", _voxelPersistFilename); + qDebug("voxelPersistFilename=%s\n", _voxelPersistFilename); - persistantFileRead = _serverTree.readFromSVOFile(_voxelPersistFilename); - if (persistantFileRead) { - PerformanceWarning warn(_shouldShowAnimationDebug, - "persistVoxelsWhenDirty() - reaverageVoxelColors()", _shouldShowAnimationDebug); - - // after done inserting all these voxels, then reaverage colors - _serverTree.reaverageVoxelColors(_serverTree.rootNode); - qDebug("Voxels reAveraged\n"); - } - - _serverTree.clearDirtyBit(); // the tree is clean since we just loaded it - qDebug("DONE loading voxels from file... fileRead=%s\n", debug::valueOf(persistantFileRead)); - unsigned long nodeCount = _serverTree.rootNode->getSubTreeNodeCount(); - unsigned long internalNodeCount = _serverTree.rootNode->getSubTreeInternalNodeCount(); - unsigned long leafNodeCount = _serverTree.rootNode->getSubTreeLeafNodeCount(); - qDebug("Nodes after loading scene %lu nodes %lu internal %lu leaves\n", nodeCount, internalNodeCount, leafNodeCount); - // now set up VoxelPersistThread _voxelPersistThread = new VoxelPersistThread(&_serverTree, _voxelPersistFilename); if (_voxelPersistThread) { @@ -377,6 +359,8 @@ void VoxelServer::run() { if (_voxelServerPacketProcessor) { _voxelServerPacketProcessor->initialize(true); } + + qDebug("Now running...\n"); // loop to send to nodes requesting data while (true) { From 924053f2ecee0654f9aecca6c3315b9264cbf267 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 14 Oct 2013 15:10:56 -0700 Subject: [PATCH 5/6] added additional debugging of VoxelNode memory usage, shrunk size of VoxelNode by better alignment --- interface/src/Application.cpp | 10 ++++- .../voxel-server-library/src/VoxelServer.cpp | 1 + libraries/voxels/src/VoxelNode.cpp | 5 ++- libraries/voxels/src/VoxelNode.h | 42 +++++++++++-------- 4 files changed, 37 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 070062f164..6a6a9789a3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2993,13 +2993,19 @@ void Application::displayStats() { drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); - voxelStats << "Voxels Memory Nodes: " << VoxelNode::getVoxelMemoryUsage() / 1000000.f << "MB " + voxelStats << + "Voxels Memory Nodes: " << VoxelNode::getVoxelMemoryUsage() / 1000000.f << "MB " + "Octcodes: " << VoxelNode::getOctcodeMemoryUsage() / 1000000.f << "MB " "Geometry RAM: " << _voxels.getVoxelMemoryUsageRAM() / 1000000.f << "MB " << "VBO: " << _voxels.getVoxelMemoryUsageVBO() / 1000000.f << "MB "; if (_voxels.hasVoxelMemoryUsageGPU()) { voxelStats << "GPU: " << _voxels.getVoxelMemoryUsageGPU() / 1000000.f << "MB "; } - + + // Some debugging for memory usage of VoxelNodes + //voxelStats << "VoxelNode size: " << sizeof(VoxelNode) << " bytes "; + //voxelStats << "AABox size: " << sizeof(AABox) << " bytes "; + drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index e4517672a0..f02069af2e 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -137,6 +137,7 @@ int VoxelServer::civetwebRequestHandler(struct mg_connection* connection) { mg_printf(connection, "%s", "Your Voxel Server is running.\r\n"); mg_printf(connection, "%s", "Current Statistics\r\n"); mg_printf(connection, "Voxel Node Memory Usage: %f MB\r\n", VoxelNode::getVoxelMemoryUsage() / 1000000.f); + mg_printf(connection, "Octcode Memory Usage: %f MB\r\n", VoxelNode::getOctcodeMemoryUsage() / 1000000.f); VoxelTree* theTree = VoxelServer::GetInstance()->getTree(); unsigned long nodeCount = theTree->rootNode->getSubTreeNodeCount(); diff --git a/libraries/voxels/src/VoxelNode.cpp b/libraries/voxels/src/VoxelNode.cpp index 154d573836..ad83b5a9cf 100644 --- a/libraries/voxels/src/VoxelNode.cpp +++ b/libraries/voxels/src/VoxelNode.cpp @@ -22,6 +22,7 @@ #include "VoxelTree.h" uint64_t VoxelNode::_voxelMemoryUsage = 0; +uint64_t VoxelNode::_octcodeMemoryUsage = 0; VoxelNode::VoxelNode() { unsigned char* rootCode = new unsigned char[1]; @@ -60,14 +61,14 @@ void VoxelNode::init(unsigned char * octalCode) { markWithChangedTime(); _voxelMemoryUsage += sizeof(VoxelNode); - _voxelMemoryUsage += bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_octalCode)); + _octcodeMemoryUsage += bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_octalCode)); } VoxelNode::~VoxelNode() { notifyDeleteHooks(); _voxelMemoryUsage -= sizeof(VoxelNode); - _voxelMemoryUsage -= bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_octalCode)); + _octcodeMemoryUsage -= bytesRequiredForCodeLength(numberOfThreeBitSectionsInCode(_octalCode)); delete[] _octalCode; diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index 6a92ab1e42..41196c81b5 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -128,6 +128,7 @@ public: unsigned long getSubTreeLeafNodeCount() const { return _subtreeLeafNodeCount; } static uint64_t getVoxelMemoryUsage() { return _voxelMemoryUsage; } + static uint64_t getOctcodeMemoryUsage() { return _octcodeMemoryUsage; } private: void calculateAABox(); @@ -135,28 +136,35 @@ private: void notifyDeleteHooks(); void notifyUpdateHooks(); - nodeColor _trueColor; + VoxelNode* _children[8]; /// Client and server, pointers to child nodes, 64 bytes + AABox _box; /// Client and server, axis aligned box for bounds of this voxel, 48 bytes + unsigned char* _octalCode; /// Client and server, pointer to octal code for this node, 8 bytes + + uint64_t _lastChanged; /// Client and server, timestamp this node was last changed, 8 bytes + unsigned long _subtreeNodeCount; /// Client and server, nodes below this node, 8 bytes + unsigned long _subtreeLeafNodeCount; /// Client and server, leaves below this node, 8 bytes + + glBufferIndex _glBufferIndex; /// Client only, vbo index for this voxel if being rendered, 8 bytes + VoxelSystem* _voxelSystem; /// Client only, pointer to VoxelSystem rendering this voxel, 8 bytes + + float _density; /// Client and server, If leaf: density = 1, if internal node: 0-1 density of voxels inside, 4 bytes + int _childCount; /// Client and server, current child nodes set to non-null in _children, 4 bytes + + nodeColor _trueColor; /// Client and server, true color of this voxel, 4 bytes #ifndef NO_FALSE_COLOR // !NO_FALSE_COLOR means, does have false color - nodeColor _currentColor; - bool _falseColored; + nodeColor _currentColor; /// Client only, false color of this voxel, 4 bytes + bool _falseColored; /// Client only, is this voxel false colored, 1 bytes #endif - glBufferIndex _glBufferIndex; - VoxelSystem* _voxelSystem; - bool _isDirty; - uint64_t _lastChanged; - bool _shouldRender; - AABox _box; - unsigned char* _octalCode; - VoxelNode* _children[8]; - int _childCount; - unsigned long _subtreeNodeCount; - unsigned long _subtreeLeafNodeCount; - float _density; // If leaf: density = 1, if internal node: 0-1 density of voxels inside - uint16_t _sourceID; + + bool _isDirty; /// Client only, has this voxel changed since being rendered, 1 byte + bool _shouldRender; /// Client only, should this voxel render at this time, 1 byte + uint16_t _sourceID; /// Client only, stores node id of voxel server that sent his voxel, 2 bytes + static std::vector _deleteHooks; static std::vector _updateHooks; static uint64_t _voxelMemoryUsage; + static uint64_t _octcodeMemoryUsage; }; -#endif /* defined(__hifi__VoxelNode__) */ +#endif /* defined(__hifi__VoxelNode__) */ \ No newline at end of file From 746bce86268cbcc0e82347d075215971da32661c Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 15 Oct 2013 11:01:22 -0700 Subject: [PATCH 6/6] All onscreen text, overlay OFF when stats are off --- interface/src/Application.cpp | 83 ++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6a6a9789a3..f9424500a7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2791,9 +2791,11 @@ void Application::displayOverlay() { } #ifndef _WIN32 - _audio.render(_glWidget->width(), _glWidget->height()); - if (Menu::getInstance()->isOptionChecked(MenuOption::Oscilloscope)) { - _audioScope.render(45, _glWidget->height() - 200); + if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { + _audio.render(_glWidget->width(), _glWidget->height()); + if (Menu::getInstance()->isOptionChecked(MenuOption::Oscilloscope)) { + _audioScope.render(45, _glWidget->height() - 200); + } } #endif @@ -2833,7 +2835,24 @@ void Application::displayOverlay() { glPointSize(1.0f); if (Menu::getInstance()->isOptionChecked(MenuOption::Stats)) { + // Onscreen text about position, servers, etc displayStats(); + // Bandwidth meter + if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth)) { + _bandwidthMeter.render(_glWidget->width(), _glWidget->height()); + } + // Stats at upper right of screen about who domain server is telling us about + glPointSize(1.0f); + char nodes[100]; + + NodeList* nodeList = NodeList::getInstance(); + int totalAvatars = 0, totalServers = 0; + + for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { + node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++; + } + sprintf(nodes, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars); + drawtext(_glWidget->width() - 150, 20, 0.10, 0, 1.0, 0, nodes, 1, 0, 0); } // testing rendering coverage map @@ -2845,9 +2864,6 @@ void Application::displayOverlay() { renderCoverageMap(); } - if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth)) { - _bandwidthMeter.render(_glWidget->width(), _glWidget->height()); - } if (Menu::getInstance()->isOptionChecked(MenuOption::Log)) { LogDisplay::instance.render(_glWidget->width(), _glWidget->height()); @@ -2867,19 +2883,6 @@ void Application::displayOverlay() { drawtext(_glWidget->width() - 102, _glWidget->height() - 22, 0.30, 0, 1.0, 0, frameTimer, 1, 1, 1); } - // Stats at upper right of screen about who domain server is telling us about - glPointSize(1.0f); - char nodes[100]; - - NodeList* nodeList = NodeList::getInstance(); - int totalAvatars = 0, totalServers = 0; - - for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { - node->getType() == NODE_TYPE_AGENT ? totalAvatars++ : totalServers++; - } - - sprintf(nodes, "Servers: %d, Avatars: %d\n", totalServers, totalAvatars); - drawtext(_glWidget->width() - 150, 20, 0.10, 0, 1.0, 0, nodes, 1, 0, 0); // render the webcam input frame _webcam.renderPreview(_glWidget->width(), _glWidget->height()); @@ -2941,11 +2944,12 @@ void Application::displayOverlay() { void Application::displayStats() { int statsVerticalOffset = 8; - + const int PELS_PER_LINE = 15; char stats[200]; + statsVerticalOffset += PELS_PER_LINE; sprintf(stats, "%3.0f FPS, %d Pkts/sec, %3.2f Mbps ", _fps, _packetsPerSecond, (float)_bytesPerSecond * 8.f / 1000000.f); - drawtext(10, statsVerticalOffset + 15, 0.10f, 0, 1.0, 0, stats); + drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, stats); if (Menu::getInstance()->isOptionChecked(MenuOption::TestPing)) { int pingAudio = 0, pingAvatar = 0, pingVoxel = 0, pingVoxelMax = 0; @@ -2975,14 +2979,16 @@ void Application::displayStats() { } char pingStats[200]; + statsVerticalOffset += PELS_PER_LINE; sprintf(pingStats, "Ping audio/avatar/voxel: %d / %d / %d avg %d max ", pingAudio, pingAvatar, pingVoxel, pingVoxelMax); - drawtext(10, statsVerticalOffset + 35, 0.10f, 0, 1.0, 0, pingStats); + drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, pingStats); } char avatarStats[200]; + statsVerticalOffset += PELS_PER_LINE; glm::vec3 avatarPos = _myAvatar.getPosition(); 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 + 55, 0.10f, 0, 1.0, 0, avatarStats); + drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarStats); std::stringstream voxelStats; @@ -2990,7 +2996,8 @@ void Application::displayStats() { voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " << "Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K " << "Max: " << _voxels.getMaxVoxels()/1000.f << "K "; - drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + statsVerticalOffset += PELS_PER_LINE; + drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelStats << @@ -3006,27 +3013,32 @@ void Application::displayStats() { //voxelStats << "VoxelNode size: " << sizeof(VoxelNode) << " bytes "; //voxelStats << "AABox size: " << sizeof(AABox) << " bytes "; - drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + 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; - drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + 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; - drawtext(10, statsVerticalOffset + 290, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + 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; - drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + 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; - drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + 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]; @@ -3038,20 +3050,21 @@ void Application::displayStats() { } else { sprintf(avatarMixerStats, "No Avatar Mixer"); } - - drawtext(10, statsVerticalOffset + 350, 0.10f, 0, 1.0, 0, avatarMixerStats); - drawtext(10, statsVerticalOffset + 450, 0.10f, 0, 1.0, 0, (char *)LeapManager::statusString().c_str()); + statsVerticalOffset += PELS_PER_LINE; + drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, avatarMixerStats); + statsVerticalOffset += PELS_PER_LINE; + drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, (char *)LeapManager::statusString().c_str()); if (_perfStatsOn) { // Get the PerfStats group details. We need to allocate and array of char* long enough to hold 1+groups char** perfStatLinesArray = new char*[PerfStat::getGroupCount()+1]; int lines = PerfStat::DumpStats(perfStatLinesArray); - int atZ = 150; // arbitrary place on screen that looks good + for (int line=0; line < lines; line++) { - drawtext(10, statsVerticalOffset + atZ, 0.10f, 0, 1.0, 0, perfStatLinesArray[line]); + statsVerticalOffset += PELS_PER_LINE; + drawtext(10, statsVerticalOffset, 0.10f, 0, 1.0, 0, perfStatLinesArray[line]); delete perfStatLinesArray[line]; // we're responsible for cleanup perfStatLinesArray[line]=NULL; - atZ+=20; // height of a line } delete []perfStatLinesArray; // we're responsible for cleanup }