From b13a4b2a71d6b027ae109c06ba2aeae85b5e7596 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 2 Jul 2015 11:07:47 -0700 Subject: [PATCH 01/14] add edit update stats --- interface/src/devices/TV3DManager.cpp | 1 - interface/src/ui/ApplicationCompositor.cpp | 5 ---- interface/src/ui/ApplicationOverlay.cpp | 3 --- interface/src/ui/AvatarInputs.cpp | 1 - interface/src/ui/OctreeStatsDialog.cpp | 15 ++++++++++++ interface/src/ui/OctreeStatsDialog.h | 4 ++++ libraries/entities/src/EntityItem.cpp | 9 +++++++ libraries/entities/src/EntityTree.cpp | 28 ++++++++++++++++++++++ libraries/entities/src/EntityTree.h | 13 ++++++++++ 9 files changed, 69 insertions(+), 10 deletions(-) diff --git a/interface/src/devices/TV3DManager.cpp b/interface/src/devices/TV3DManager.cpp index 41e549a861..e945b5e79a 100644 --- a/interface/src/devices/TV3DManager.cpp +++ b/interface/src/devices/TV3DManager.cpp @@ -109,7 +109,6 @@ void TV3DManager::display(RenderArgs* renderArgs, Camera& whichCamera) { glScissor(portalX, portalY, portalW, portalH); glm::mat4 projection = glm::frustum(eye.left, eye.right, eye.bottom, eye.top, nearZ, farZ); - float fov = atan(1.0f / projection[1][1]); projection = glm::translate(projection, vec3(eye.modelTranslation, 0, 0)); eyeCamera.setProjection(projection); diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 6cdf690d99..bb19392458 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -25,18 +25,13 @@ // Used to animate the magnification windows -static const float MAG_SPEED = 0.08f; static const quint64 MSECS_TO_USECS = 1000ULL; static const quint64 TOOLTIP_DELAY = 500 * MSECS_TO_USECS; -static const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f }; static const float RETICLE_COLOR[] = { 0.0f, 198.0f / 255.0f, 244.0f / 255.0f }; static const float reticleSize = TWO_PI / 100.0f; -static const float CONNECTION_STATUS_BORDER_COLOR[] = { 1.0f, 0.0f, 0.0f }; -static const float CONNECTION_STATUS_BORDER_LINE_WIDTH = 4.0f; - static const float CURSOR_PIXEL_SIZE = 32.0f; static const float MOUSE_PITCH_RANGE = 1.0f * PI; static const float MOUSE_YAW_RANGE = 0.5f * TWO_PI; diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 63f68b86ce..e7d220893f 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -36,9 +36,6 @@ #include "ui/Stats.h" #include "ui/AvatarInputs.h" -const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f }; -const int AUDIO_METER_GAP = 5; -const int MUTE_ICON_PADDING = 10; const vec4 CONNECTION_STATUS_BORDER_COLOR{ 1.0f, 0.0f, 0.0f, 0.8f }; const float CONNECTION_STATUS_BORDER_LINE_WIDTH = 4.0f; static const float ORTHO_NEAR_CLIP = -10000; diff --git a/interface/src/ui/AvatarInputs.cpp b/interface/src/ui/AvatarInputs.cpp index 11f744aaca..870038cd01 100644 --- a/interface/src/ui/AvatarInputs.cpp +++ b/interface/src/ui/AvatarInputs.cpp @@ -67,7 +67,6 @@ void AvatarInputs::update() { AI_UPDATE(cameraMuted, Menu::getInstance()->isOptionChecked(MenuOption::MuteFaceTracking)); auto audioIO = DependencyManager::get(); - const float CLIPPING_INDICATOR_TIME = 1.0f; const float AUDIO_METER_AVERAGING = 0.5; const float LOG2 = log(2.0f); const float METER_LOUDNESS_SCALE = 2.8f / 5.0f; diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 462811fc1c..4e55e3beef 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -50,6 +50,7 @@ OctreeStatsDialog::OctreeStatsDialog(QWidget* parent, NodeToOctreeSceneStats* mo _localElements = AddStatItem("Local Elements"); _localElementsMemory = AddStatItem("Elements Memory"); _sendingMode = AddStatItem("Sending Mode"); + _entityUpdateTime = AddStatItem("Entity Update Time"); layout()->setSizeConstraint(QLayout::SetFixedSize); } @@ -203,6 +204,20 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { "Leaves: " << qPrintable(serversLeavesString) << ""; label->setText(statsValue.str().c_str()); + label = _labels[_entityUpdateTime]; + auto entites = Application::getInstance()->getEntities()->getTree(); + quint64 averageEditDelta = entites->getAverageEditDeltas(); + QString averageEditDeltaString = locale.toString((uint)averageEditDelta); + quint64 maxEditDelta = entites->getMaxEditDelta(); + QString maxEditDeltaString = locale.toString((uint)maxEditDelta); + + statsValue.str(""); + statsValue << + "Average: " << qPrintable(averageEditDeltaString) << " (usecs) / " << + "Max: " << qPrintable(maxEditDeltaString) << " (usecs)"; + label->setText(statsValue.str().c_str()); + + showAllOctreeServers(); this->QDialog::paintEvent(event); diff --git a/interface/src/ui/OctreeStatsDialog.h b/interface/src/ui/OctreeStatsDialog.h index 03683d8171..5ddda8067a 100644 --- a/interface/src/ui/OctreeStatsDialog.h +++ b/interface/src/ui/OctreeStatsDialog.h @@ -63,6 +63,10 @@ private: int _serverElements; int _localElements; int _localElementsMemory; + + int _entityUpdateTime; + + int _octreeServerLables[MAX_VOXEL_SERVERS]; int _octreeServerLabelsCount; details _extraServerDetails[MAX_VOXEL_SERVERS]; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 74b7a36504..e24f6846fd 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -414,6 +414,14 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef dataAt += sizeof(lastEditedFromBuffer); bytesRead += sizeof(lastEditedFromBuffer); lastEditedFromBufferAdjusted = lastEditedFromBuffer - clockSkew; + + // Tracking for editing roundtrips here. We will tell our EntityTree that we just got incoming data about + // and entity that was edited at some time in the past. The tree will determine how it wants to track this + // information. + if (_element && _element->getTree()) { + _element->getTree()->trackIncomingEntityLastEdited(lastEditedFromBufferAdjusted); + } + if (lastEditedFromBufferAdjusted > now) { lastEditedFromBufferAdjusted = now; } @@ -486,6 +494,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef qCDebug(entities) << " lastEditedFromBufferAdjusted:" << debugTime(lastEditedFromBufferAdjusted, now); #endif } + encodedUpdateDelta = updateDeltaCoder; // determine true length dataAt += encodedUpdateDelta.size(); bytesRead += encodedUpdateDelta.size(); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 6a652d609b..0fbe6d40ed 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -34,6 +34,7 @@ EntityTree::EntityTree(bool shouldReaverage) : _simulation(NULL) { _rootElement = createNewElement(); + resetClientEditStats(); } EntityTree::~EntityTree() { @@ -60,6 +61,8 @@ void EntityTree::eraseAllOctreeElements(bool createNewRoot) { } _entityToElementMap.clear(); Octree::eraseAllOctreeElements(createNewRoot); + + resetClientEditStats(); } bool EntityTree::handlesEditPacketType(PacketType packetType) const { @@ -1104,3 +1107,28 @@ bool EntityTree::readFromMap(QVariantMap& map) { return true; } + +void EntityTree::resetClientEditStats() { + _treeResetTime = usecTimestampNow(); + _maxEditDelta = 0; + _totalEditDeltas = 0; + _totalTrackedEdits = 0; +} + + + +void EntityTree::trackIncomingEntityLastEdited(quint64 lastEditedTime) { + // we don't want to track all edit deltas, just those edits that have happend + // since we connected to this domain. This will filter out all previously created + // content and only track new edits + if (lastEditedTime > _treeResetTime) { + quint64 now = usecTimestampNow(); + quint64 sinceEdit = now - lastEditedTime; + + _totalEditDeltas += sinceEdit; + _totalTrackedEdits++; + if (sinceEdit > _maxEditDelta) { + _maxEditDelta = sinceEdit; + } + } +} diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index fa72cc7691..9db57af383 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -185,6 +185,12 @@ public: virtual quint64 getAverageCreateTime() const { return _totalCreates == 0 ? 0 : _totalCreateTime / _totalCreates; } virtual quint64 getAverageLoggingTime() const { return _totalEditMessages == 0 ? 0 : _totalLoggingTime / _totalEditMessages; } + void trackIncomingEntityLastEdited(quint64 lastEditedTime); + quint64 getAverageEditDeltas() const + { return _totalTrackedEdits == 0 ? 0 : _totalEditDeltas / _totalTrackedEdits; } + quint64 getMaxEditDelta() const + { return _maxEditDelta; } + signals: void deletingEntity(const EntityItemID& entityID); void addingEntity(const EntityItemID& entityID); @@ -230,6 +236,13 @@ private: quint64 _totalUpdateTime = 0; quint64 _totalCreateTime = 0; quint64 _totalLoggingTime = 0; + + // these performance statistics are only used in the client + void resetClientEditStats(); + int _totalTrackedEdits = 0; + quint64 _totalEditDeltas = 0; + quint64 _maxEditDelta = 0; + quint64 _treeResetTime = 0; }; #endif // hifi_EntityTree_h From 63b585da0fda9cccd69453513c5ba545c39e44e3 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 2 Jul 2015 13:28:12 -0700 Subject: [PATCH 02/14] added updates per second stat --- interface/src/ui/OctreeStatsDialog.cpp | 43 ++++++++++++++++++++++++-- interface/src/ui/OctreeStatsDialog.h | 6 +++- libraries/entities/src/EntityTree.h | 4 +-- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 4e55e3beef..9426f2b2e0 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -25,7 +25,9 @@ OctreeStatsDialog::OctreeStatsDialog(QWidget* parent, NodeToOctreeSceneStats* model) : QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint), - _model(model) { + _model(model), + _averageUpdatesPerSecond(SAMPLES_PER_SECOND) +{ _statCount = 0; _octreeServerLabelsCount = 0; @@ -51,6 +53,7 @@ OctreeStatsDialog::OctreeStatsDialog(QWidget* parent, NodeToOctreeSceneStats* mo _localElementsMemory = AddStatItem("Elements Memory"); _sendingMode = AddStatItem("Sending Mode"); _entityUpdateTime = AddStatItem("Entity Update Time"); + _entityUpdates = AddStatItem("Entity Updates"); layout()->setSizeConstraint(QLayout::SetFixedSize); } @@ -204,19 +207,53 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { "Leaves: " << qPrintable(serversLeavesString) << ""; label->setText(statsValue.str().c_str()); + // Entity Edits update time label = _labels[_entityUpdateTime]; auto entites = Application::getInstance()->getEntities()->getTree(); - quint64 averageEditDelta = entites->getAverageEditDeltas(); + auto averageEditDelta = entites->getAverageEditDeltas(); + auto maxEditDelta = entites->getMaxEditDelta(); + QString averageEditDeltaString = locale.toString((uint)averageEditDelta); - quint64 maxEditDelta = entites->getMaxEditDelta(); QString maxEditDeltaString = locale.toString((uint)maxEditDelta); statsValue.str(""); statsValue << "Average: " << qPrintable(averageEditDeltaString) << " (usecs) / " << "Max: " << qPrintable(maxEditDeltaString) << " (usecs)"; + label->setText(statsValue.str().c_str()); + // Entity Edits + label = _labels[_entityUpdates]; + auto totalTrackedEdits = entites->getTotalTrackedEdits(); + + // track our updated per second + const quint64 SAMPLING_WINDOW = USECS_PER_SECOND / SAMPLES_PER_SECOND; + quint64 now = usecTimestampNow(); + quint64 sinceLastWindow = now - _lastWindowAt; + auto editsInLastWindow = totalTrackedEdits - _lastKnownTrackedEdits; + float sinceLastWindowInSeconds = (float)sinceLastWindow / (float)USECS_PER_SECOND; + float recentUpdatesPerSecond = (float)editsInLastWindow / sinceLastWindowInSeconds; + if (sinceLastWindow > SAMPLING_WINDOW) { + _averageUpdatesPerSecond.updateAverage(recentUpdatesPerSecond); + _lastWindowAt = now; + _lastKnownTrackedEdits = totalTrackedEdits; + } + + auto updatesPerSecond = _averageUpdatesPerSecond.getAverage(); + if (updatesPerSecond < 1) { + updatesPerSecond = 0; // we don't really care about small updates per second so suppress those + } + + QString totalTrackedEditsString = locale.toString((uint)totalTrackedEdits); + QString updatesPerSecondString = locale.toString(updatesPerSecond); + + statsValue.str(""); + statsValue << + "" << qPrintable(updatesPerSecondString) << " updates per second / " << + "" << qPrintable(totalTrackedEditsString) << " total updates "; + + label->setText(statsValue.str().c_str()); showAllOctreeServers(); diff --git a/interface/src/ui/OctreeStatsDialog.h b/interface/src/ui/OctreeStatsDialog.h index 5ddda8067a..acbf766510 100644 --- a/interface/src/ui/OctreeStatsDialog.h +++ b/interface/src/ui/OctreeStatsDialog.h @@ -65,7 +65,11 @@ private: int _localElementsMemory; int _entityUpdateTime; - + int _entityUpdates; + const int SAMPLES_PER_SECOND = 10; + SimpleMovingAverage _averageUpdatesPerSecond; + quint64 _lastWindowAt = 0; + quint64 _lastKnownTrackedEdits = 0; int _octreeServerLables[MAX_VOXEL_SERVERS]; int _octreeServerLabelsCount; diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 9db57af383..92c726729d 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -188,8 +188,8 @@ public: void trackIncomingEntityLastEdited(quint64 lastEditedTime); quint64 getAverageEditDeltas() const { return _totalTrackedEdits == 0 ? 0 : _totalEditDeltas / _totalTrackedEdits; } - quint64 getMaxEditDelta() const - { return _maxEditDelta; } + quint64 getMaxEditDelta() const { return _maxEditDelta; } + quint64 getTotalTrackedEdits() const { return _totalTrackedEdits; } signals: void deletingEntity(const EntityItemID& entityID); From 5c4d4893def43ca46c10f39eef2a0ce38c4662d5 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 2 Jul 2015 13:44:28 -0700 Subject: [PATCH 03/14] added bytes per edit stats --- interface/src/ui/OctreeStatsDialog.cpp | 13 ++++++++----- libraries/entities/src/EntityItem.cpp | 15 ++++++++------- libraries/entities/src/EntityTree.cpp | 3 ++- libraries/entities/src/EntityTree.h | 5 ++++- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 9426f2b2e0..c8784f69b8 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -209,9 +209,9 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { // Entity Edits update time label = _labels[_entityUpdateTime]; - auto entites = Application::getInstance()->getEntities()->getTree(); - auto averageEditDelta = entites->getAverageEditDeltas(); - auto maxEditDelta = entites->getMaxEditDelta(); + auto entities = Application::getInstance()->getEntities()->getTree(); + auto averageEditDelta = entities->getAverageEditDeltas(); + auto maxEditDelta = entities->getMaxEditDelta(); QString averageEditDeltaString = locale.toString((uint)averageEditDelta); QString maxEditDeltaString = locale.toString((uint)maxEditDelta); @@ -225,7 +225,8 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { // Entity Edits label = _labels[_entityUpdates]; - auto totalTrackedEdits = entites->getTotalTrackedEdits(); + auto totalTrackedEdits = entities->getTotalTrackedEdits(); + auto bytesPerEdit = entities->getAverageEditBytes(); // track our updated per second const quint64 SAMPLING_WINDOW = USECS_PER_SECOND / SAMPLES_PER_SECOND; @@ -247,11 +248,13 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { QString totalTrackedEditsString = locale.toString((uint)totalTrackedEdits); QString updatesPerSecondString = locale.toString(updatesPerSecond); + QString bytesPerEditString = locale.toString(bytesPerEdit); statsValue.str(""); statsValue << "" << qPrintable(updatesPerSecondString) << " updates per second / " << - "" << qPrintable(totalTrackedEditsString) << " total updates "; + "" << qPrintable(totalTrackedEditsString) << " total updates / " << + "Average Size: " << qPrintable(bytesPerEditString) << " bytes "; label->setText(statsValue.str().c_str()); diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index e24f6846fd..0f681ba5f7 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -415,13 +415,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef bytesRead += sizeof(lastEditedFromBuffer); lastEditedFromBufferAdjusted = lastEditedFromBuffer - clockSkew; - // Tracking for editing roundtrips here. We will tell our EntityTree that we just got incoming data about - // and entity that was edited at some time in the past. The tree will determine how it wants to track this - // information. - if (_element && _element->getTree()) { - _element->getTree()->trackIncomingEntityLastEdited(lastEditedFromBufferAdjusted); - } - if (lastEditedFromBufferAdjusted > now) { lastEditedFromBufferAdjusted = now; } @@ -646,6 +639,14 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef } } + // Tracking for editing roundtrips here. We will tell our EntityTree that we just got incoming data about + // and entity that was edited at some time in the past. The tree will determine how it wants to track this + // information. + if (_element && _element->getTree()) { + _element->getTree()->trackIncomingEntityLastEdited(lastEditedFromBufferAdjusted, bytesRead); + } + + return bytesRead; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 0fbe6d40ed..ae4d8ab236 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1117,7 +1117,7 @@ void EntityTree::resetClientEditStats() { -void EntityTree::trackIncomingEntityLastEdited(quint64 lastEditedTime) { +void EntityTree::trackIncomingEntityLastEdited(quint64 lastEditedTime, int bytesRead) { // we don't want to track all edit deltas, just those edits that have happend // since we connected to this domain. This will filter out all previously created // content and only track new edits @@ -1126,6 +1126,7 @@ void EntityTree::trackIncomingEntityLastEdited(quint64 lastEditedTime) { quint64 sinceEdit = now - lastEditedTime; _totalEditDeltas += sinceEdit; + _totalEditBytes += bytesRead; _totalTrackedEdits++; if (sinceEdit > _maxEditDelta) { _maxEditDelta = sinceEdit; diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 92c726729d..263cff2171 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -185,9 +185,11 @@ public: virtual quint64 getAverageCreateTime() const { return _totalCreates == 0 ? 0 : _totalCreateTime / _totalCreates; } virtual quint64 getAverageLoggingTime() const { return _totalEditMessages == 0 ? 0 : _totalLoggingTime / _totalEditMessages; } - void trackIncomingEntityLastEdited(quint64 lastEditedTime); + void trackIncomingEntityLastEdited(quint64 lastEditedTime, int bytesRead); quint64 getAverageEditDeltas() const { return _totalTrackedEdits == 0 ? 0 : _totalEditDeltas / _totalTrackedEdits; } + quint64 getAverageEditBytes() const + { return _totalTrackedEdits == 0 ? 0 : _totalEditBytes / _totalTrackedEdits; } quint64 getMaxEditDelta() const { return _maxEditDelta; } quint64 getTotalTrackedEdits() const { return _totalTrackedEdits; } @@ -240,6 +242,7 @@ private: // these performance statistics are only used in the client void resetClientEditStats(); int _totalTrackedEdits = 0; + quint64 _totalEditBytes = 0; quint64 _totalEditDeltas = 0; quint64 _maxEditDelta = 0; quint64 _treeResetTime = 0; From 8be1fd28e53124b4121a5d9ee427b0955b5bdf2d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 2 Jul 2015 13:57:00 -0700 Subject: [PATCH 04/14] stripping naked gl calls from overlays to allow vive and oculus plugins to work --- .../src/ui/overlays/BillboardOverlay.cpp | 25 +------ interface/src/ui/overlays/Grid3DOverlay.cpp | 69 +------------------ .../src/ui/overlays/LocalModelsOverlay.cpp | 22 +++--- interface/src/ui/overlays/OverlaysPayload.cpp | 12 ++-- .../src/ui/overlays/Rectangle3DOverlay.cpp | 63 +---------------- interface/src/ui/overlays/Sphere3DOverlay.cpp | 21 +++--- libraries/render-utils/src/paintStrokes.slf | 27 ++++++++ libraries/render-utils/src/paintStrokes.slv | 35 ++++++++++ 8 files changed, 92 insertions(+), 182 deletions(-) create mode 100644 libraries/render-utils/src/paintStrokes.slf create mode 100644 libraries/render-utils/src/paintStrokes.slv diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index 288a950bbb..913eb749a9 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -94,30 +94,7 @@ void BillboardOverlay::render(RenderArgs* args) { batch->setUniformTexture(0, args->_whiteTexture); // restore default white color after me } else { - glEnable(GL_ALPHA_TEST); - glAlphaFunc(GL_GREATER, 0.5f); - - glEnable(GL_TEXTURE_2D); - glDisable(GL_LIGHTING); - - glBindTexture(GL_TEXTURE_2D, _texture->getID()); - - glPushMatrix(); { - glTranslatef(getPosition().x, getPosition().y, getPosition().z); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - glScalef(_dimensions.x, _dimensions.y, 1.0f); - - DependencyManager::get()->renderQuad(topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, - glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)); - - } glPopMatrix(); - - glDisable(GL_TEXTURE_2D); - glEnable(GL_LIGHTING); - glDisable(GL_ALPHA_TEST); - - glBindTexture(GL_TEXTURE_2D, 0); + qDebug() << "NO NAKED GL CALLS ALLOWED HERE! PLEASE USE THE BATCHING SYSTEM NEXT TIME"; } } diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index 6316c8cd77..295dc1b2b5 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -90,74 +90,7 @@ void Grid3DOverlay::render(RenderArgs* args) { DependencyManager::get()->renderGrid(*batch, MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor); } } else { - if (!_gridProgram.isLinked()) { - if (!_gridProgram.addShaderFromSourceFile(QGLShader::Vertex, PathUtils::resourcesPath() + "shaders/grid.vert")) { - qDebug() << "Failed to compile: " + _gridProgram.log(); - return; - } - if (!_gridProgram.addShaderFromSourceFile(QGLShader::Fragment, PathUtils::resourcesPath() + "shaders/grid.frag")) { - qDebug() << "Failed to compile: " + _gridProgram.log(); - return; - } - if (!_gridProgram.link()) { - qDebug() << "Failed to link: " + _gridProgram.log(); - return; - } - } - - // Render code largely taken from MetavoxelEditor::render() - glDisable(GL_LIGHTING); - - glDepthMask(GL_FALSE); - - glPushMatrix(); - - glm::quat rotation = getRotation(); - - glm::vec3 axis = glm::axis(rotation); - - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - - glLineWidth(1.5f); - - glm::vec3 position = getPosition(); - - _gridProgram.bind(); - - // Minor grid - glPushMatrix(); - { - glTranslatef(_minorGridWidth * (floorf(rotated.x / spacing) - MINOR_GRID_DIVISIONS / 2), - spacing * (floorf(rotated.y / spacing) - MINOR_GRID_DIVISIONS / 2), position.z); - - float scale = MINOR_GRID_DIVISIONS * spacing; - glScalef(scale, scale, scale); - - DependencyManager::get()->renderGrid(MINOR_GRID_DIVISIONS, MINOR_GRID_DIVISIONS, gridColor); - } - glPopMatrix(); - - // Major grid - glPushMatrix(); - { - glLineWidth(4.0f); - spacing *= _majorGridEvery; - glTranslatef(spacing * (floorf(rotated.x / spacing) - MAJOR_GRID_DIVISIONS / 2), - spacing * (floorf(rotated.y / spacing) - MAJOR_GRID_DIVISIONS / 2), position.z); - - float scale = MAJOR_GRID_DIVISIONS * spacing; - glScalef(scale, scale, scale); - - DependencyManager::get()->renderGrid(MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor); - } - glPopMatrix(); - - _gridProgram.release(); - - glPopMatrix(); - - glEnable(GL_LIGHTING); - glDepthMask(GL_TRUE); + qDebug() << "NO NAKED GL CALLS ALLOWED HERE! PLEASE USE THE BATCHING SYSTEM NEXT TIME"; } } diff --git a/interface/src/ui/overlays/LocalModelsOverlay.cpp b/interface/src/ui/overlays/LocalModelsOverlay.cpp index 912196041f..6e0b53f0c2 100644 --- a/interface/src/ui/overlays/LocalModelsOverlay.cpp +++ b/interface/src/ui/overlays/LocalModelsOverlay.cpp @@ -32,25 +32,25 @@ void LocalModelsOverlay::update(float deltatime) { void LocalModelsOverlay::render(RenderArgs* args) { if (_visible) { - float glowLevel = getGlowLevel(); Glower* glower = NULL; if (glowLevel > 0.0f) { glower = new Glower(glowLevel); } - - glPushMatrix(); { - Application* app = Application::getInstance(); - glm::vec3 oldTranslation = app->getViewMatrixTranslation(); - app->setViewMatrixTranslation(oldTranslation + getPosition()); - _entityTreeRenderer->render(args); - Application::getInstance()->setViewMatrixTranslation(oldTranslation); - } glPopMatrix(); - + + auto batch = args ->_batch; + Application* app = Application::getInstance(); + glm::vec3 oldTranslation = app->getViewMatrixTranslation(); + Transform transform = Transform(); + transform.setTranslation(oldTranslation + getPosition()); + batch->setViewTransform(transform); + _entityTreeRenderer->render(args); + transform.setTranslation(oldTranslation); + batch->setViewTransform(transform); + if (glower) { delete glower; } - } } diff --git a/interface/src/ui/overlays/OverlaysPayload.cpp b/interface/src/ui/overlays/OverlaysPayload.cpp index b7cacef80c..e6b37d693b 100644 --- a/interface/src/ui/overlays/OverlaysPayload.cpp +++ b/interface/src/ui/overlays/OverlaysPayload.cpp @@ -62,19 +62,19 @@ namespace render { template <> void payloadRender(const Overlay::Pointer& overlay, RenderArgs* args) { if (args) { if (overlay->getAnchor() == Overlay::MY_AVATAR) { - glPushMatrix(); + auto batch = args->_batch; MyAvatar* avatar = DependencyManager::get()->getMyAvatar(); glm::quat myAvatarRotation = avatar->getOrientation(); glm::vec3 myAvatarPosition = avatar->getPosition(); float angle = glm::degrees(glm::angle(myAvatarRotation)); glm::vec3 axis = glm::axis(myAvatarRotation); float myAvatarScale = avatar->getScale(); - - glTranslatef(myAvatarPosition.x, myAvatarPosition.y, myAvatarPosition.z); - glRotatef(angle, axis.x, axis.y, axis.z); - glScalef(myAvatarScale, myAvatarScale, myAvatarScale); + Transform transform = Transform(); + transform.setTranslation(myAvatarPosition); + transform.setRotation(glm::angleAxis(angle, axis)); + transform.setScale(myAvatarScale); + batch->setModelTransform(transform); overlay->render(args); - glPopMatrix(); } else { overlay->render(args); } diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 74bbd1bca8..6f35ccb3d0 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -88,69 +88,8 @@ void Rectangle3DOverlay::render(RenderArgs* args) { } } } else { - glDisable(GL_LIGHTING); - float glowLevel = getGlowLevel(); - Glower* glower = NULL; - if (glowLevel > 0.0f) { - glower = new Glower(glowLevel); - } - - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - glPushMatrix(); - glm::vec3 positionToCenter = center - position; - glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); - //glScalef(dimensions.x, dimensions.y, 1.0f); - - glLineWidth(_lineWidth); - - auto geometryCache = DependencyManager::get(); - - // for our overlay, is solid means we draw a solid "filled" rectangle otherwise we just draw a border line... - if (getIsSolid()) { - glm::vec3 topLeft(-halfDimensions.x, -halfDimensions.y, 0.0f); - glm::vec3 bottomRight(halfDimensions.x, halfDimensions.y, 0.0f); - DependencyManager::get()->renderQuad(topLeft, bottomRight, rectangleColor); - } else { - if (getIsDashedLine()) { - - glm::vec3 point1(-halfDimensions.x, -halfDimensions.y, 0.0f); - glm::vec3 point2(halfDimensions.x, -halfDimensions.y, 0.0f); - glm::vec3 point3(halfDimensions.x, halfDimensions.y, 0.0f); - glm::vec3 point4(-halfDimensions.x, halfDimensions.y, 0.0f); - - geometryCache->renderDashedLine(point1, point2, rectangleColor); - geometryCache->renderDashedLine(point2, point3, rectangleColor); - geometryCache->renderDashedLine(point3, point4, rectangleColor); - geometryCache->renderDashedLine(point4, point1, rectangleColor); - - } else { - - if (halfDimensions != _previousHalfDimensions) { - QVector border; - border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); - border << glm::vec3(halfDimensions.x, -halfDimensions.y, 0.0f); - border << glm::vec3(halfDimensions.x, halfDimensions.y, 0.0f); - border << glm::vec3(-halfDimensions.x, halfDimensions.y, 0.0f); - border << glm::vec3(-halfDimensions.x, -halfDimensions.y, 0.0f); - geometryCache->updateVertices(_geometryCacheID, border, rectangleColor); - - _previousHalfDimensions = halfDimensions; - - } - geometryCache->renderVertices(gpu::LINE_STRIP, _geometryCacheID); - } - } - - glPopMatrix(); - glPopMatrix(); - - if (glower) { - delete glower; - } + qDebug() << "NO NAKED GL CALLS ALLOWED HERE! PLEASE USE THE BATCHING SYSTEM NEXT TIME"; } } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index e129954db9..dd60ee4af8 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -55,17 +55,16 @@ void Sphere3DOverlay::render(RenderArgs* args) { glower = new Glower(glowLevel); } - glPushMatrix(); - glTranslatef(position.x, position.y, position.z); - glm::vec3 axis = glm::axis(rotation); - glRotatef(glm::degrees(glm::angle(rotation)), axis.x, axis.y, axis.z); - glPushMatrix(); - glm::vec3 positionToCenter = center - position; - glTranslatef(positionToCenter.x, positionToCenter.y, positionToCenter.z); - glScalef(dimensions.x, dimensions.y, dimensions.z); - DependencyManager::get()->renderSphere(1.0f, SLICES, SLICES, sphereColor, _isSolid); - glPopMatrix(); - glPopMatrix(); + Transform transform = Transform(); + transform.setTranslation(position); + glm::vec3 axis = glm::axis(rotation); + transform.setRotation(glm::angleAxis(glm::angle(rotation), axis)); + + glm::vec3 positionToCenter = center - position; + transform.setTranslation(positionToCenter); + transform.setScale(dimensions); + DependencyManager::get()->renderSphere(*batch, 1.0f, SLICES, SLICES, sphereColor, _isSolid); + if (glower) { delete glower; diff --git a/libraries/render-utils/src/paintStrokes.slf b/libraries/render-utils/src/paintStrokes.slf new file mode 100644 index 0000000000..bbbb44cc51 --- /dev/null +++ b/libraries/render-utils/src/paintStrokes.slf @@ -0,0 +1,27 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// simple.frag +// fragment shader +// +// Created by Andrzej Kapolka on 9/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include DeferredBufferWrite.slh@> + +// the interpolated normal +varying vec4 interpolatedNormal; + +void main(void) { + packDeferredFragment( + normalize(interpolatedNormal.xyz), + glowIntensity, + gl_Color.rgb, + gl_FrontMaterial.specular.rgb, + gl_FrontMaterial.shininess); +} diff --git a/libraries/render-utils/src/paintStrokes.slv b/libraries/render-utils/src/paintStrokes.slv new file mode 100644 index 0000000000..380734e70c --- /dev/null +++ b/libraries/render-utils/src/paintStrokes.slv @@ -0,0 +1,35 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// simple.vert +// vertex shader +// +// Created by Andrzej Kapolka on 9/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include gpu/Transform.slh@> + +<$declareStandardTransform()$> + +// the interpolated normal +varying vec4 interpolatedNormal; + +void main(void) { + gl_TexCoord[0] = gl_MultiTexCoord0; + + // pass along the diffuse color + gl_FrontColor = gl_Color; + + // standard transform + TransformCamera cam = getTransformCamera(); + TransformObject obj = getTransformObject(); + <$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$> + <$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$> + + interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); +} \ No newline at end of file From 4db2b8dd59031611ce0c2a94329a0384160cafe0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 2 Jul 2015 15:05:45 -0700 Subject: [PATCH 05/14] removed shader code used in a different branch --- libraries/render-utils/src/paintStrokes.slf | 27 ---------------- libraries/render-utils/src/paintStrokes.slv | 35 --------------------- 2 files changed, 62 deletions(-) delete mode 100644 libraries/render-utils/src/paintStrokes.slf delete mode 100644 libraries/render-utils/src/paintStrokes.slv diff --git a/libraries/render-utils/src/paintStrokes.slf b/libraries/render-utils/src/paintStrokes.slf deleted file mode 100644 index bbbb44cc51..0000000000 --- a/libraries/render-utils/src/paintStrokes.slf +++ /dev/null @@ -1,27 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// simple.frag -// fragment shader -// -// Created by Andrzej Kapolka on 9/15/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -<@include DeferredBufferWrite.slh@> - -// the interpolated normal -varying vec4 interpolatedNormal; - -void main(void) { - packDeferredFragment( - normalize(interpolatedNormal.xyz), - glowIntensity, - gl_Color.rgb, - gl_FrontMaterial.specular.rgb, - gl_FrontMaterial.shininess); -} diff --git a/libraries/render-utils/src/paintStrokes.slv b/libraries/render-utils/src/paintStrokes.slv deleted file mode 100644 index 380734e70c..0000000000 --- a/libraries/render-utils/src/paintStrokes.slv +++ /dev/null @@ -1,35 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// -// simple.vert -// vertex shader -// -// Created by Andrzej Kapolka on 9/15/14. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -<@include gpu/Transform.slh@> - -<$declareStandardTransform()$> - -// the interpolated normal -varying vec4 interpolatedNormal; - -void main(void) { - gl_TexCoord[0] = gl_MultiTexCoord0; - - // pass along the diffuse color - gl_FrontColor = gl_Color; - - // standard transform - TransformCamera cam = getTransformCamera(); - TransformObject obj = getTransformObject(); - <$transformModelToClipPos(cam, obj, gl_Vertex, gl_Position)$> - <$transformModelToEyeDir(cam, obj, gl_Normal, interpolatedNormal.xyz)$> - - interpolatedNormal = vec4(normalize(interpolatedNormal.xyz), 0.0); -} \ No newline at end of file From 0c0b8dbbc15c0255abc06453a596ca1b9e17b8f1 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 2 Jul 2015 16:19:13 -0700 Subject: [PATCH 06/14] add stats for elements and entities per incoming packet --- interface/src/ui/OctreeStatsDialog.cpp | 28 ++++++++++++++++---- interface/src/ui/OctreeStatsDialog.h | 2 ++ libraries/entities/src/EntityItem.cpp | 2 ++ libraries/entities/src/EntityTreeElement.cpp | 2 ++ libraries/octree/src/Octree.h | 2 ++ libraries/octree/src/OctreeRenderer.cpp | 15 +++++++++-- libraries/octree/src/OctreeRenderer.h | 7 +++++ 7 files changed, 51 insertions(+), 7 deletions(-) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index c8784f69b8..12ed3cf36f 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -52,6 +52,8 @@ OctreeStatsDialog::OctreeStatsDialog(QWidget* parent, NodeToOctreeSceneStats* mo _localElements = AddStatItem("Local Elements"); _localElementsMemory = AddStatItem("Elements Memory"); _sendingMode = AddStatItem("Sending Mode"); + + _entityPackets = AddStatItem("Entity Packets"); _entityUpdateTime = AddStatItem("Entity Update Time"); _entityUpdates = AddStatItem("Entity Updates"); @@ -207,11 +209,27 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { "Leaves: " << qPrintable(serversLeavesString) << ""; label->setText(statsValue.str().c_str()); + // Entity Edits update time + label = _labels[_entityPackets]; + auto entities = Application::getInstance()->getEntities(); + auto entitiesTree = entities->getTree(); + auto averageElementsPerPacket = entities->getAverageElementsPerPacket(); + auto averageEntitiesPerPacket = entities->getAverageEntitiesPerPacket(); + + QString averageElementsPerPacketString = locale.toString(averageElementsPerPacket); + QString averageEntitiesPerPacketString = locale.toString(averageEntitiesPerPacket); + + statsValue.str(""); + statsValue << + "Elements: " << qPrintable(averageEntitiesPerPacketString) << " per packet / " << + "Entities: " << qPrintable(averageEntitiesPerPacketString) << " per packet"; + + label->setText(statsValue.str().c_str()); + // Entity Edits update time label = _labels[_entityUpdateTime]; - auto entities = Application::getInstance()->getEntities()->getTree(); - auto averageEditDelta = entities->getAverageEditDeltas(); - auto maxEditDelta = entities->getMaxEditDelta(); + auto averageEditDelta = entitiesTree->getAverageEditDeltas(); + auto maxEditDelta = entitiesTree->getMaxEditDelta(); QString averageEditDeltaString = locale.toString((uint)averageEditDelta); QString maxEditDeltaString = locale.toString((uint)maxEditDelta); @@ -225,8 +243,8 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { // Entity Edits label = _labels[_entityUpdates]; - auto totalTrackedEdits = entities->getTotalTrackedEdits(); - auto bytesPerEdit = entities->getAverageEditBytes(); + auto totalTrackedEdits = entitiesTree->getTotalTrackedEdits(); + auto bytesPerEdit = entitiesTree->getAverageEditBytes(); // track our updated per second const quint64 SAMPLING_WINDOW = USECS_PER_SECOND / SAMPLES_PER_SECOND; diff --git a/interface/src/ui/OctreeStatsDialog.h b/interface/src/ui/OctreeStatsDialog.h index acbf766510..4c59744af2 100644 --- a/interface/src/ui/OctreeStatsDialog.h +++ b/interface/src/ui/OctreeStatsDialog.h @@ -66,6 +66,8 @@ private: int _entityUpdateTime; int _entityUpdates; + int _entityPackets; + const int SAMPLES_PER_SECOND = 10; SimpleMovingAverage _averageUpdatesPerSecond; quint64 _lastWindowAt = 0; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 511238efca..5e129365fe 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -346,6 +346,8 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef return 0; } + args.entitiesPerPacket++; + // Header bytes // object ID [16 bytes] // ByteCountCoded(type code) [~1 byte] diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 4bc81e1da6..41c0529b80 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -702,6 +702,8 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int int bytesRead = 0; uint16_t numberOfEntities = 0; int expectedBytesPerEntity = EntityItem::expectedBytes(); + + args.elementsPerPacket++; if (bytesLeftToRead >= (int)sizeof(numberOfEntities)) { // read our entities in.... diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index 6eeb423ddd..f1d32aa390 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -195,6 +195,8 @@ public: SharedNodePointer sourceNode; bool wantImportProgress; PacketVersion bitstreamVersion; + int elementsPerPacket = 0; + int entitiesPerPacket = 0; ReadBitstreamToTreeParams( bool includeColor = WANT_COLOR, diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 7852f1d4b4..f4c5491678 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -101,6 +101,9 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar sequence, flightTime, packetLength, dataBytes); } + int elementsPerPacket = 0; + int entitiesPerPacket = 0; + int subsection = 1; while (dataBytes > 0) { if (packetIsCompressed) { @@ -139,13 +142,21 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar qCDebug(octree) << "OctreeRenderer::processDatagram() ******* END _tree->readBitstreamToTree()..."; } _tree->unlock(); - + dataBytes -= sectionLength; dataAt += sectionLength; + + elementsPerPacket += args.elementsPerPacket; + entitiesPerPacket += args.entitiesPerPacket; + } + subsection++; } - subsection++; + _elementsPerPacket.updateAverage(elementsPerPacket); + _entitiesPerPacket.updateAverage(entitiesPerPacket); } + + } bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) { diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index 98026b732c..9a70e0923e 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -61,12 +61,19 @@ public: /// clears the tree virtual void clear(); + float getAverageElementsPerPacket() const { return _elementsPerPacket.getAverage(); } + float getAverageEntitiesPerPacket() const { return _entitiesPerPacket.getAverage(); } + protected: virtual Octree* createTree() = 0; Octree* _tree; bool _managedTree; ViewFrustum* _viewFrustum; + + SimpleMovingAverage _elementsPerPacket; + SimpleMovingAverage _entitiesPerPacket; + }; #endif // hifi_OctreeRenderer_h From 8916dd205664761e2052a09562eade21c2e0f889 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 2 Jul 2015 17:00:35 -0700 Subject: [PATCH 07/14] add stats for elements and entities per second --- interface/src/ui/OctreeStatsDialog.cpp | 25 ++++++++++++++++++++----- interface/src/ui/OctreeStatsDialog.h | 3 ++- libraries/octree/src/OctreeRenderer.cpp | 23 +++++++++++++++++++++-- libraries/octree/src/OctreeRenderer.h | 9 +++++++++ 4 files changed, 52 insertions(+), 8 deletions(-) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 12ed3cf36f..ce9034ce2d 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -53,7 +53,8 @@ OctreeStatsDialog::OctreeStatsDialog(QWidget* parent, NodeToOctreeSceneStats* mo _localElementsMemory = AddStatItem("Elements Memory"); _sendingMode = AddStatItem("Sending Mode"); - _entityPackets = AddStatItem("Entity Packets"); + _processedPacketsElements = AddStatItem("Processed Packets Elements"); + _processedPacketsEntities = AddStatItem("Processed Packets Entities"); _entityUpdateTime = AddStatItem("Entity Update Time"); _entityUpdates = AddStatItem("Entity Updates"); @@ -209,20 +210,34 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { "Leaves: " << qPrintable(serversLeavesString) << ""; label->setText(statsValue.str().c_str()); - // Entity Edits update time - label = _labels[_entityPackets]; + // Processed Entities Related stats auto entities = Application::getInstance()->getEntities(); auto entitiesTree = entities->getTree(); + + // Processed Packets Elements auto averageElementsPerPacket = entities->getAverageElementsPerPacket(); auto averageEntitiesPerPacket = entities->getAverageEntitiesPerPacket(); + auto averageElementsPerSecond = entities->getAverageElementsPerSecond(); + auto averageEntitiesPerSecond = entities->getAverageEntitiesPerSecond(); QString averageElementsPerPacketString = locale.toString(averageElementsPerPacket); QString averageEntitiesPerPacketString = locale.toString(averageEntitiesPerPacket); + QString averageElementsPerSecondString = locale.toString(averageElementsPerSecond); + QString averageEntitiesPerSecondString = locale.toString(averageEntitiesPerSecond); + label = _labels[_processedPacketsElements]; statsValue.str(""); statsValue << - "Elements: " << qPrintable(averageEntitiesPerPacketString) << " per packet / " << - "Entities: " << qPrintable(averageEntitiesPerPacketString) << " per packet"; + "" << qPrintable(averageElementsPerPacketString) << " per packet / " << + "" << qPrintable(averageElementsPerSecondString) << " per second"; + + label->setText(statsValue.str().c_str()); + + label = _labels[_processedPacketsEntities]; + statsValue.str(""); + statsValue << + "" << qPrintable(averageEntitiesPerPacketString) << " per packet / " << + "" << qPrintable(averageEntitiesPerSecondString) << " per second"; label->setText(statsValue.str().c_str()); diff --git a/interface/src/ui/OctreeStatsDialog.h b/interface/src/ui/OctreeStatsDialog.h index 4c59744af2..9b0b1ad90a 100644 --- a/interface/src/ui/OctreeStatsDialog.h +++ b/interface/src/ui/OctreeStatsDialog.h @@ -66,7 +66,8 @@ private: int _entityUpdateTime; int _entityUpdates; - int _entityPackets; + int _processedPacketsElements; + int _processedPacketsEntities; const int SAMPLES_PER_SECOND = 10; SimpleMovingAverage _averageUpdatesPerSecond; diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index f4c5491678..e77f652932 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -149,14 +149,33 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar elementsPerPacket += args.elementsPerPacket; entitiesPerPacket += args.entitiesPerPacket; + _elementsInLastWindow += args.elementsPerPacket; + _entitiesInLastWindow += args.entitiesPerPacket; + } subsection++; } _elementsPerPacket.updateAverage(elementsPerPacket); _entitiesPerPacket.updateAverage(entitiesPerPacket); + + quint64 now = usecTimestampNow(); + if (_lastWindowAt == 0) { + _lastWindowAt = now; + } + quint64 sinceLastWindow = now - _lastWindowAt; + + const quint64 USECS_PER_SECOND = 1000 * 1000; + if (sinceLastWindow > USECS_PER_SECOND) { + float elementsPerSecondInWindow = (float)_elementsInLastWindow / (float)(sinceLastWindow / USECS_PER_SECOND); + float entitiesPerSecondInWindow = (float)_entitiesInLastWindow / (float)(sinceLastWindow / USECS_PER_SECOND); + _elementsPerSecond.updateAverage(elementsPerSecondInWindow); + _entitiesPerSecond.updateAverage(entitiesPerSecondInWindow); + + _lastWindowAt = now; + _elementsInLastWindow = 0; + _entitiesInLastWindow = 0; + } } - - } bool OctreeRenderer::renderOperation(OctreeElement* element, void* extraData) { diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index 9a70e0923e..de0f4dc1bb 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -63,6 +63,9 @@ public: float getAverageElementsPerPacket() const { return _elementsPerPacket.getAverage(); } float getAverageEntitiesPerPacket() const { return _entitiesPerPacket.getAverage(); } + + float getAverageElementsPerSecond() const { return _elementsPerSecond.getAverage(); } + float getAverageEntitiesPerSecond() const { return _entitiesPerSecond.getAverage(); } protected: virtual Octree* createTree() = 0; @@ -73,6 +76,12 @@ protected: SimpleMovingAverage _elementsPerPacket; SimpleMovingAverage _entitiesPerPacket; + SimpleMovingAverage _elementsPerSecond; + SimpleMovingAverage _entitiesPerSecond; + + quint64 _lastWindowAt = 0; + int _elementsInLastWindow = 0; + int _entitiesInLastWindow = 0; }; From a54cf6706470b28b10e7feb539cc5a254bd055d4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 2 Jul 2015 17:28:53 -0700 Subject: [PATCH 08/14] add stats for processing time per packet --- interface/src/ui/OctreeStatsDialog.cpp | 19 +++++++++++++++++++ interface/src/ui/OctreeStatsDialog.h | 1 + libraries/octree/src/OctreeRenderer.cpp | 16 ++++++++++++++++ libraries/octree/src/OctreeRenderer.h | 8 ++++++++ 4 files changed, 44 insertions(+) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index ce9034ce2d..4c95e7a68a 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -55,6 +55,8 @@ OctreeStatsDialog::OctreeStatsDialog(QWidget* parent, NodeToOctreeSceneStats* mo _processedPacketsElements = AddStatItem("Processed Packets Elements"); _processedPacketsEntities = AddStatItem("Processed Packets Entities"); + _processedPacketsTiming = AddStatItem("Processed Packets Timing"); + _entityUpdateTime = AddStatItem("Entity Update Time"); _entityUpdates = AddStatItem("Entity Updates"); @@ -220,11 +222,19 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { auto averageElementsPerSecond = entities->getAverageElementsPerSecond(); auto averageEntitiesPerSecond = entities->getAverageEntitiesPerSecond(); + auto averageWaitLockPerPacket = entities->getAverageWaitLockPerPacket(); + auto averageUncompressPerPacket = entities->getAverageUncompressPerPacket(); + auto averageReadBitstreamPerPacket = entities->getAverageReadBitstreamPerPacket(); + QString averageElementsPerPacketString = locale.toString(averageElementsPerPacket); QString averageEntitiesPerPacketString = locale.toString(averageEntitiesPerPacket); QString averageElementsPerSecondString = locale.toString(averageElementsPerSecond); QString averageEntitiesPerSecondString = locale.toString(averageEntitiesPerSecond); + QString averageWaitLockPerPacketString = locale.toString(averageWaitLockPerPacket); + QString averageUncompressPerPacketString = locale.toString(averageUncompressPerPacket); + QString averageReadBitstreamPerPacketString = locale.toString(averageReadBitstreamPerPacket); + label = _labels[_processedPacketsElements]; statsValue.str(""); statsValue << @@ -241,6 +251,15 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { label->setText(statsValue.str().c_str()); + label = _labels[_processedPacketsTiming]; + statsValue.str(""); + statsValue << + "Lock Wait:" << qPrintable(averageWaitLockPerPacketString) << " (usecs) / " << + "Uncompress:" << qPrintable(averageUncompressPerPacketString) << " (usecs) / " << + "Process:" << qPrintable(averageReadBitstreamPerPacketString) << " (usecs)"; + + label->setText(statsValue.str().c_str()); + // Entity Edits update time label = _labels[_entityUpdateTime]; auto averageEditDelta = entitiesTree->getAverageEditDeltas(); diff --git a/interface/src/ui/OctreeStatsDialog.h b/interface/src/ui/OctreeStatsDialog.h index 9b0b1ad90a..986080de56 100644 --- a/interface/src/ui/OctreeStatsDialog.h +++ b/interface/src/ui/OctreeStatsDialog.h @@ -68,6 +68,7 @@ private: int _entityUpdates; int _processedPacketsElements; int _processedPacketsEntities; + int _processedPacketsTiming; const int SAMPLES_PER_SECOND = 10; SimpleMovingAverage _averageUpdatesPerSecond; diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index e77f652932..5ffc22d5ee 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -104,6 +104,10 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar int elementsPerPacket = 0; int entitiesPerPacket = 0; + quint64 totalWaitingForLock = 0; + quint64 totalUncompress = 0; + quint64 totalReadBitsteam = 0; + int subsection = 1; while (dataBytes > 0) { if (packetIsCompressed) { @@ -123,7 +127,9 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar // ask the VoxelTree to read the bitstream into the tree ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, sourceUUID, sourceNode, false, packetVersion); + quint64 startLock = usecTimestampNow(); _tree->lockForWrite(); + quint64 startUncompress = usecTimestampNow(); OctreePacketData packetData(packetIsCompressed); packetData.loadFinalizedContent(dataAt, sectionLength); if (extraDebugging) { @@ -137,7 +143,9 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar if (extraDebugging) { qCDebug(octree) << "OctreeRenderer::processDatagram() ******* START _tree->readBitstreamToTree()..."; } + quint64 startReadBitsteam = usecTimestampNow(); _tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args); + quint64 endReadBitsteam = usecTimestampNow(); if (extraDebugging) { qCDebug(octree) << "OctreeRenderer::processDatagram() ******* END _tree->readBitstreamToTree()..."; } @@ -152,11 +160,19 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar _elementsInLastWindow += args.elementsPerPacket; _entitiesInLastWindow += args.entitiesPerPacket; + totalWaitingForLock += (startUncompress - startLock); + totalUncompress += (startReadBitsteam - startUncompress); + totalReadBitsteam += (endReadBitsteam - startReadBitsteam); + } subsection++; } _elementsPerPacket.updateAverage(elementsPerPacket); _entitiesPerPacket.updateAverage(entitiesPerPacket); + + _waitLockPerPacket.updateAverage(totalWaitingForLock); + _uncompressPerPacket.updateAverage(totalUncompress); + _readBitstreamPerPacket.updateAverage(totalReadBitsteam); quint64 now = usecTimestampNow(); if (_lastWindowAt == 0) { diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index de0f4dc1bb..894e5c2355 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -66,6 +66,10 @@ public: float getAverageElementsPerSecond() const { return _elementsPerSecond.getAverage(); } float getAverageEntitiesPerSecond() const { return _entitiesPerSecond.getAverage(); } + + float getAverageWaitLockPerPacket() const { return _waitLockPerPacket.getAverage(); } + float getAverageUncompressPerPacket() const { return _uncompressPerPacket.getAverage(); } + float getAverageReadBitstreamPerPacket() const { return _readBitstreamPerPacket.getAverage(); } protected: virtual Octree* createTree() = 0; @@ -79,6 +83,10 @@ protected: SimpleMovingAverage _elementsPerSecond; SimpleMovingAverage _entitiesPerSecond; + SimpleMovingAverage _waitLockPerPacket; + SimpleMovingAverage _uncompressPerPacket; + SimpleMovingAverage _readBitstreamPerPacket; + quint64 _lastWindowAt = 0; int _elementsInLastWindow = 0; int _entitiesInLastWindow = 0; From e1530b3ce942fa2f19b730089d81fe5de02309ac Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 2 Jul 2015 18:15:24 -0700 Subject: [PATCH 09/14] added a FIXME STUTTER note --- libraries/octree/src/OctreeRenderer.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 5ffc22d5ee..6fa3f47120 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -128,6 +128,9 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, sourceUUID, sourceNode, false, packetVersion); quint64 startLock = usecTimestampNow(); + + // FIXME STUTTER - there may be an opportunity to bump this lock outside of the + // loop to reduce the amount of locking/unlocking we're doing _tree->lockForWrite(); quint64 startUncompress = usecTimestampNow(); OctreePacketData packetData(packetIsCompressed); From 29a7584ee6af7c5a1d6981eab2aeee651b306652 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 Jul 2015 11:29:59 -0700 Subject: [PATCH 10/14] remove dead code --- assignment-client/src/octree/OctreeServer.cpp | 41 - interface/src/ui/ApplicationCompositor.cpp | 5 - interface/src/ui/ApplicationOverlay.cpp | 3 - libraries/entities/src/EntityItem.cpp | 3 - libraries/entities/src/EntityTree.cpp | 3 - libraries/octree/src/Octree.cpp | 10 - libraries/octree/src/OctreeElement.cpp | 770 ------------------ libraries/octree/src/OctreeElement.h | 48 -- .../render-utils/src/RenderDeferredTask.cpp | 1 - libraries/render/src/render/DrawTask.cpp | 2 - 10 files changed, 886 deletions(-) diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 06fb5c4f47..72f2567809 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -760,47 +760,6 @@ bool OctreeServer::handleHTTPRequest(HTTPConnection* connection, const QUrl& url statsString += QString(" Total: %1 nodes\r\n") .arg(locale.toString((uint)checkSum).rightJustified(16, ' ')); -#ifdef BLENDED_UNION_CHILDREN - statsString += "\r\n"; - statsString += "OctreeElement Children Encoding Statistics...\r\n"; - - statsString += QString().sprintf(" Single or No Children: %10.llu nodes (%5.2f%%)\r\n", - OctreeElement::getSingleChildrenCount(), - ((float)OctreeElement::getSingleChildrenCount() / (float)nodeCount) * AS_PERCENT)); - statsString += QString().sprintf(" Two Children as Offset: %10.llu nodes (%5.2f%%)\r\n", - OctreeElement::getTwoChildrenOffsetCount(), - ((float)OctreeElement::getTwoChildrenOffsetCount() / (float)nodeCount) * AS_PERCENT)); - statsString += QString().sprintf(" Two Children as External: %10.llu nodes (%5.2f%%)\r\n", - OctreeElement::getTwoChildrenExternalCount(), - ((float)OctreeElement::getTwoChildrenExternalCount() / (float)nodeCount) * AS_PERCENT); - statsString += QString().sprintf(" Three Children as Offset: %10.llu nodes (%5.2f%%)\r\n", - OctreeElement::getThreeChildrenOffsetCount(), - ((float)OctreeElement::getThreeChildrenOffsetCount() / (float)nodeCount) * AS_PERCENT); - statsString += QString().sprintf(" Three Children as External: %10.llu nodes (%5.2f%%)\r\n", - OctreeElement::getThreeChildrenExternalCount(), - ((float)OctreeElement::getThreeChildrenExternalCount() / (float)nodeCount) * AS_PERCENT); - statsString += QString().sprintf(" Children as External Array: %10.llu nodes (%5.2f%%)\r\n", - OctreeElement::getExternalChildrenCount(), - ((float)OctreeElement::getExternalChildrenCount() / (float)nodeCount) * AS_PERCENT); - - checkSum = OctreeElement::getSingleChildrenCount() + - OctreeElement::getTwoChildrenOffsetCount() + OctreeElement::getTwoChildrenExternalCount() + - OctreeElement::getThreeChildrenOffsetCount() + OctreeElement::getThreeChildrenExternalCount() + - OctreeElement::getExternalChildrenCount(); - - statsString += " ----------------\r\n"; - statsString += QString().sprintf(" Total: %10.llu nodes\r\n", checkSum); - statsString += QString().sprintf(" Expected: %10.lu nodes\r\n", nodeCount); - - statsString += "\r\n"; - statsString += "In other news....\r\n"; - - statsString += QString().sprintf("could store 4 children internally: %10.llu nodes\r\n", - OctreeElement::getCouldStoreFourChildrenInternally()); - statsString += QString().sprintf("could NOT store 4 children internally: %10.llu nodes\r\n", - OctreeElement::getCouldNotStoreFourChildrenInternally()); -#endif - statsString += "\r\n\r\n"; statsString += "\r\n"; statsString += ""; diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 4c3a2a44c1..dafa332d53 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -25,18 +25,13 @@ // Used to animate the magnification windows -static const float MAG_SPEED = 0.08f; static const quint64 MSECS_TO_USECS = 1000ULL; static const quint64 TOOLTIP_DELAY = 500 * MSECS_TO_USECS; -static const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f }; static const float RETICLE_COLOR[] = { 0.0f, 198.0f / 255.0f, 244.0f / 255.0f }; static const float reticleSize = TWO_PI / 100.0f; -static const float CONNECTION_STATUS_BORDER_COLOR[] = { 1.0f, 0.0f, 0.0f }; -static const float CONNECTION_STATUS_BORDER_LINE_WIDTH = 4.0f; - static const float CURSOR_PIXEL_SIZE = 32.0f; static const float MOUSE_PITCH_RANGE = 1.0f * PI; static const float MOUSE_YAW_RANGE = 0.5f * TWO_PI; diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 63f68b86ce..e7d220893f 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -36,9 +36,6 @@ #include "ui/Stats.h" #include "ui/AvatarInputs.h" -const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f }; -const int AUDIO_METER_GAP = 5; -const int MUTE_ICON_PADDING = 10; const vec4 CONNECTION_STATUS_BORDER_COLOR{ 1.0f, 0.0f, 0.0f, 0.8f }; const float CONNECTION_STATUS_BORDER_LINE_WIDTH = 4.0f; static const float ORTHO_NEAR_CLIP = -10000; diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 6559289e33..d63a7243e7 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -30,9 +30,6 @@ #include "EntityActionFactoryInterface.h" -const quint64 DEFAULT_SIMULATOR_CHANGE_LOCKOUT_PERIOD = (quint64)(0.2f * USECS_PER_SECOND); -const quint64 MAX_SIMULATOR_CHANGE_LOCKOUT_PERIOD = 2 * USECS_PER_SECOND; - bool EntityItem::_sendPhysicsUpdates = true; int EntityItem::_maxActionsDataSize = 800; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index a341051986..d6f71ebd56 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -26,9 +26,6 @@ #include "LogHandler.h" -const quint64 SIMULATOR_CHANGE_LOCKOUT_PERIOD = (quint64)(0.2f * USECS_PER_SECOND); - - EntityTree::EntityTree(bool shouldReaverage) : Octree(shouldReaverage), _fbxService(NULL), diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index adc2040b8a..7f421368d8 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -667,11 +667,6 @@ OctreeElement* Octree::getOctreeElementAt(float x, float y, float z, float s) co element = NULL; } delete[] octalCode; // cleanup memory -#ifdef HAS_AUDIT_CHILDREN - if (element) { - element->auditChildren("Octree::getOctreeElementAt()"); - } -#endif // def HAS_AUDIT_CHILDREN return element; } @@ -680,11 +675,6 @@ OctreeElement* Octree::getOctreeEnclosingElementAt(float x, float y, float z, fl OctreeElement* element = nodeForOctalCode(_rootElement, octalCode, NULL); delete[] octalCode; // cleanup memory -#ifdef HAS_AUDIT_CHILDREN - if (element) { - element->auditChildren("Octree::getOctreeElementAt()"); - } -#endif // def HAS_AUDIT_CHILDREN return element; } diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index e09d5fb910..e11a11fc8e 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -71,19 +71,9 @@ void OctreeElement::init(unsigned char * octalCode) { _childrenExternal = false; -#ifdef BLENDED_UNION_CHILDREN - _children.external = NULL; - _singleChildrenCount++; -#endif _childrenCount[0]++; // default pointers to child nodes to NULL -#ifdef HAS_AUDIT_CHILDREN - for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { - _childrenArray[i] = NULL; - } -#endif // def HAS_AUDIT_CHILDREN - #ifdef SIMPLE_CHILD_ARRAY for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { _simpleChildArray[i] = NULL; @@ -218,9 +208,6 @@ void OctreeElement::deleteChildAtIndex(int childIndex) { _voxelNodeLeafCount++; } } -#ifdef HAS_AUDIT_CHILDREN - auditChildren("deleteChildAtIndex()"); -#endif // def HAS_AUDIT_CHILDREN } // does not delete the node! @@ -236,10 +223,6 @@ OctreeElement* OctreeElement::removeChildAtIndex(int childIndex) { _voxelNodeLeafCount++; } } - -#ifdef HAS_AUDIT_CHILDREN - auditChildren("removeChildAtIndex()"); -#endif // def HAS_AUDIT_CHILDREN return returnedChild; } @@ -255,60 +238,11 @@ bool OctreeElement::isParentOf(OctreeElement* possibleChild) const { return false; } - -#ifdef HAS_AUDIT_CHILDREN -void OctreeElement::auditChildren(const char* label) const { - bool auditFailed = false; - for (int childIndex = 0; childIndex < NUMBER_OF_CHILDREN; childIndex++) { - OctreeElement* testChildNew = getChildAtIndex(childIndex); - OctreeElement* testChildOld = _childrenArray[childIndex]; - - if (testChildNew != testChildOld) { - auditFailed = true; - } - } - - const bool alwaysReport = false; // set this to true to get additional debugging - if (alwaysReport || auditFailed) { - qDebug("%s... auditChildren() %s <<<<", label, (auditFailed ? "FAILED" : "PASSED")); - qDebug(" _childrenExternal=%s", debug::valueOf(_childrenExternal)); - qDebug(" childCount=%d", getChildCount()); - - QDebug bitOutput = qDebug().nospace(); - bitOutput << " _childBitmask="; - outputBits(_childBitmask, bitOutput); - - - for (int childIndex = 0; childIndex < NUMBER_OF_CHILDREN; childIndex++) { - OctreeElement* testChildNew = getChildAtIndex(childIndex); - OctreeElement* testChildOld = _childrenArray[childIndex]; - - qCebug("child at index %d... testChildOld=%p testChildNew=%p %s", - childIndex, testChildOld, testChildNew , - ((testChildNew != testChildOld) ? " DOES NOT MATCH <<<< BAD <<<<" : " - OK ") - ); - } - qDebug("%s... auditChildren() <<<< DONE <<<<", label); - } -} -#endif // def HAS_AUDIT_CHILDREN - - quint64 OctreeElement::_getChildAtIndexTime = 0; quint64 OctreeElement::_getChildAtIndexCalls = 0; quint64 OctreeElement::_setChildAtIndexTime = 0; quint64 OctreeElement::_setChildAtIndexCalls = 0; -#ifdef BLENDED_UNION_CHILDREN -quint64 OctreeElement::_singleChildrenCount = 0; -quint64 OctreeElement::_twoChildrenOffsetCount = 0; -quint64 OctreeElement::_twoChildrenExternalCount = 0; -quint64 OctreeElement::_threeChildrenOffsetCount = 0; -quint64 OctreeElement::_threeChildrenExternalCount = 0; -quint64 OctreeElement::_couldStoreFourChildrenInternally = 0; -quint64 OctreeElement::_couldNotStoreFourChildrenInternally = 0; -#endif - quint64 OctreeElement::_externalChildrenCount = 0; quint64 OctreeElement::_childrenCount[NUMBER_OF_CHILDREN + 1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; @@ -341,319 +275,8 @@ OctreeElement* OctreeElement::getChildAtIndex(int childIndex) const { } break; } #endif // def SIMPLE_EXTERNAL_CHILDREN - -#ifdef BLENDED_UNION_CHILDREN - PerformanceWarning warn(false,"getChildAtIndex",false,&_getChildAtIndexTime,&_getChildAtIndexCalls); - OctreeElement* result = NULL; - int childCount = getChildCount(); - -#ifdef HAS_AUDIT_CHILDREN - const char* caseStr = NULL; -#endif - - switch (childCount) { - case 0: -#ifdef HAS_AUDIT_CHILDREN - caseStr = "0 child case"; -#endif - break; - case 1: { -#ifdef HAS_AUDIT_CHILDREN - caseStr = "1 child case"; -#endif - int indexOne = getNthBit(_childBitmask, 1); - if (indexOne == childIndex) { - result = _children.single; - } - } break; - case 2: { -#ifdef HAS_AUDIT_CHILDREN - caseStr = "2 child case"; -#endif - int indexOne = getNthBit(_childBitmask, 1); - int indexTwo = getNthBit(_childBitmask, 2); - - if (_childrenExternal) { - //assert(_children.external); - if (indexOne == childIndex) { - result = _children.external[0]; - } else if (indexTwo == childIndex) { - result = _children.external[1]; - } - } else { - if (indexOne == childIndex) { - int32_t offset = _children.offsetsTwoChildren[0]; - result = (OctreeElement*)((uint8_t*)this + offset); - } else if (indexTwo == childIndex) { - int32_t offset = _children.offsetsTwoChildren[1]; - result = (OctreeElement*)((uint8_t*)this + offset); - } - } - } break; - case 3: { -#ifdef HAS_AUDIT_CHILDREN - caseStr = "3 child case"; -#endif - int indexOne = getNthBit(_childBitmask, 1); - int indexTwo = getNthBit(_childBitmask, 2); - int indexThree = getNthBit(_childBitmask, 3); - - if (_childrenExternal) { - //assert(_children.external); - if (indexOne == childIndex) { - result = _children.external[0]; - } else if (indexTwo == childIndex) { - result = _children.external[1]; - } else if (indexThree == childIndex) { - result = _children.external[2]; - } else { - } - } else { - int64_t offsetOne, offsetTwo, offsetThree; - decodeThreeOffsets(offsetOne, offsetTwo, offsetThree); - - if (indexOne == childIndex) { - result = (OctreeElement*)((uint8_t*)this + offsetOne); - } else if (indexTwo == childIndex) { - result = (OctreeElement*)((uint8_t*)this + offsetTwo); - } else if (indexThree == childIndex) { - result = (OctreeElement*)((uint8_t*)this + offsetThree); - } - } - } break; - default: { -#ifdef HAS_AUDIT_CHILDREN - caseStr = "default"; -#endif - // if we have 4 or more, we know we're in external mode, so we just need to figure out which - // slot in our external array this child is. - if (oneAtBit(_childBitmask, childIndex)) { - childCount = getChildCount(); - for (int ordinal = 1; ordinal <= childCount; ordinal++) { - int index = getNthBit(_childBitmask, ordinal); - if (index == childIndex) { - int externalIndex = ordinal-1; - if (externalIndex < childCount && externalIndex >= 0) { - result = _children.external[externalIndex]; - } else { - qCDebug(octree, "getChildAtIndex() attempt to access external client out of " - "bounds externalIndex=%d <<<<<<<<<< WARNING!!!", externalIndex); - } - break; - } - } - } - } break; - } -#ifdef HAS_AUDIT_CHILDREN - if (result != _childrenArray[childIndex]) { - qCDebug(octree, "getChildAtIndex() case:%s result<%p> != _childrenArray[childIndex]<%p> <<<<<<<<<< WARNING!!!", - caseStr, result,_childrenArray[childIndex]); - } -#endif // def HAS_AUDIT_CHILDREN - return result; -#endif } -#ifdef BLENDED_UNION_CHILDREN -void OctreeElement::storeTwoChildren(OctreeElement* childOne, OctreeElement* childTwo) { - int64_t offsetOne = (uint8_t*)childOne - (uint8_t*)this; - int64_t offsetTwo = (uint8_t*)childTwo - (uint8_t*)this; - - const int64_t minOffset = std::numeric_limits::min(); - const int64_t maxOffset = std::numeric_limits::max(); - - bool forceExternal = true; - if (!forceExternal && isBetween(offsetOne, maxOffset, minOffset) && isBetween(offsetTwo, maxOffset, minOffset)) { - // if previously external, then clean it up... - if (_childrenExternal) { - //assert(_children.external); - const int previousChildCount = 2; - _externalChildrenMemoryUsage -= previousChildCount * sizeof(OctreeElement*); - delete[] _children.external; - _children.external = NULL; // probably not needed! - _childrenExternal = false; - } - - // encode in union - _children.offsetsTwoChildren[0] = offsetOne; - _children.offsetsTwoChildren[1] = offsetTwo; - - _twoChildrenOffsetCount++; - } else { - // encode in array - - // if not previously external, then allocate appropriately - if (!_childrenExternal) { - _childrenExternal = true; - const int newChildCount = 2; - _externalChildrenMemoryUsage += newChildCount * sizeof(OctreeElement*); - _children.external = new OctreeElement*[newChildCount]; - memset(_children.external, 0, sizeof(OctreeElement*) * newChildCount); - } - _children.external[0] = childOne; - _children.external[1] = childTwo; - _twoChildrenExternalCount++; - } -} - -void OctreeElement::retrieveTwoChildren(OctreeElement*& childOne, OctreeElement*& childTwo) { - // If we previously had an external array, then get the - if (_childrenExternal) { - childOne = _children.external[0]; - childTwo = _children.external[1]; - delete[] _children.external; - _children.external = NULL; // probably not needed! - _childrenExternal = false; - _twoChildrenExternalCount--; - const int newChildCount = 2; - _externalChildrenMemoryUsage -= newChildCount * sizeof(OctreeElement*); - } else { - int64_t offsetOne = _children.offsetsTwoChildren[0]; - int64_t offsetTwo = _children.offsetsTwoChildren[1]; - childOne = (OctreeElement*)((uint8_t*)this + offsetOne); - childTwo = (OctreeElement*)((uint8_t*)this + offsetTwo); - _twoChildrenOffsetCount--; - } -} - -void OctreeElement::decodeThreeOffsets(int64_t& offsetOne, int64_t& offsetTwo, int64_t& offsetThree) const { - const quint64 ENCODE_BITS = 21; - const quint64 ENCODE_MASK = 0xFFFFF; - const quint64 ENCODE_MASK_SIGN = 0x100000; - - quint64 offsetEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK; - quint64 offsetEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK; - quint64 offsetEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK); - - quint64 signEncodedOne = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 2)) & ENCODE_MASK_SIGN; - quint64 signEncodedTwo = (_children.offsetsThreeChildrenEncoded >> (ENCODE_BITS * 1)) & ENCODE_MASK_SIGN; - quint64 signEncodedThree = (_children.offsetsThreeChildrenEncoded & ENCODE_MASK_SIGN); - - bool oneNegative = signEncodedOne == ENCODE_MASK_SIGN; - bool twoNegative = signEncodedTwo == ENCODE_MASK_SIGN; - bool threeNegative = signEncodedThree == ENCODE_MASK_SIGN; - - offsetOne = oneNegative ? -offsetEncodedOne : offsetEncodedOne; - offsetTwo = twoNegative ? -offsetEncodedTwo : offsetEncodedTwo; - offsetThree = threeNegative ? -offsetEncodedThree : offsetEncodedThree; -} - -void OctreeElement::encodeThreeOffsets(int64_t offsetOne, int64_t offsetTwo, int64_t offsetThree) { - const quint64 ENCODE_BITS = 21; - const quint64 ENCODE_MASK = 0xFFFFF; - const quint64 ENCODE_MASK_SIGN = 0x100000; - - quint64 offsetEncodedOne, offsetEncodedTwo, offsetEncodedThree; - if (offsetOne < 0) { - offsetEncodedOne = ((-offsetOne & ENCODE_MASK) | ENCODE_MASK_SIGN); - } else { - offsetEncodedOne = offsetOne & ENCODE_MASK; - } - offsetEncodedOne = offsetEncodedOne << (ENCODE_BITS * 2); - - if (offsetTwo < 0) { - offsetEncodedTwo = ((-offsetTwo & ENCODE_MASK) | ENCODE_MASK_SIGN); - } else { - offsetEncodedTwo = offsetTwo & ENCODE_MASK; - } - offsetEncodedTwo = offsetEncodedTwo << ENCODE_BITS; - - if (offsetThree < 0) { - offsetEncodedThree = ((-offsetThree & ENCODE_MASK) | ENCODE_MASK_SIGN); - } else { - offsetEncodedThree = offsetThree & ENCODE_MASK; - } - _children.offsetsThreeChildrenEncoded = offsetEncodedOne | offsetEncodedTwo | offsetEncodedThree; -} - -void OctreeElement::storeThreeChildren(OctreeElement* childOne, OctreeElement* childTwo, OctreeElement* childThree) { - int64_t offsetOne = (uint8_t*)childOne - (uint8_t*)this; - int64_t offsetTwo = (uint8_t*)childTwo - (uint8_t*)this; - int64_t offsetThree = (uint8_t*)childThree - (uint8_t*)this; - - const int64_t minOffset = -1048576; // what can fit in 20 bits // std::numeric_limits::min(); - const int64_t maxOffset = 1048576; // what can fit in 20 bits // std::numeric_limits::max(); - - bool forceExternal = true; - if (!forceExternal && - isBetween(offsetOne, maxOffset, minOffset) && - isBetween(offsetTwo, maxOffset, minOffset) && - isBetween(offsetThree, maxOffset, minOffset)) { - // if previously external, then clean it up... - if (_childrenExternal) { - delete[] _children.external; - _children.external = NULL; // probably not needed! - _childrenExternal = false; - const int previousChildCount = 3; - _externalChildrenMemoryUsage -= previousChildCount * sizeof(OctreeElement*); - } - // encode in union - encodeThreeOffsets(offsetOne, offsetTwo, offsetThree); - _threeChildrenOffsetCount++; - } else { - // encode in array - - // if not previously external, then allocate appropriately - if (!_childrenExternal) { - _childrenExternal = true; - const int newChildCount = 3; - _externalChildrenMemoryUsage += newChildCount * sizeof(OctreeElement*); - _children.external = new OctreeElement*[newChildCount]; - memset(_children.external, 0, sizeof(OctreeElement*) * newChildCount); - } - _children.external[0] = childOne; - _children.external[1] = childTwo; - _children.external[2] = childThree; - _threeChildrenExternalCount++; - } -} - -void OctreeElement::retrieveThreeChildren(OctreeElement*& childOne, OctreeElement*& childTwo, OctreeElement*& childThree) { - // If we previously had an external array, then get the - if (_childrenExternal) { - childOne = _children.external[0]; - childTwo = _children.external[1]; - childThree = _children.external[2]; - delete[] _children.external; - _children.external = NULL; // probably not needed! - _childrenExternal = false; - _threeChildrenExternalCount--; - _externalChildrenMemoryUsage -= 3 * sizeof(OctreeElement*); - } else { - int64_t offsetOne, offsetTwo, offsetThree; - decodeThreeOffsets(offsetOne, offsetTwo, offsetThree); - - childOne = (OctreeElement*)((uint8_t*)this + offsetOne); - childTwo = (OctreeElement*)((uint8_t*)this + offsetTwo); - childThree = (OctreeElement*)((uint8_t*)this + offsetThree); - _threeChildrenOffsetCount--; - } -} - -void OctreeElement::checkStoreFourChildren(OctreeElement* childOne, OctreeElement* childTwo, OctreeElement* childThree, OctreeElement* childFour) { - int64_t offsetOne = (uint8_t*)childOne - (uint8_t*)this; - int64_t offsetTwo = (uint8_t*)childTwo - (uint8_t*)this; - int64_t offsetThree = (uint8_t*)childThree - (uint8_t*)this; - int64_t offsetFour = (uint8_t*)childFour - (uint8_t*)this; - - const int64_t minOffset = std::numeric_limits::min(); - const int64_t maxOffset = std::numeric_limits::max(); - - bool forceExternal = true; - if (!forceExternal && - isBetween(offsetOne, maxOffset, minOffset) && - isBetween(offsetTwo, maxOffset, minOffset) && - isBetween(offsetThree, maxOffset, minOffset) && - isBetween(offsetFour, maxOffset, minOffset) - ) { - _couldStoreFourChildrenInternally++; - } else { - _couldNotStoreFourChildrenInternally++; - } -} -#endif - void OctreeElement::deleteAllChildren() { // first delete all the OctreeElement objects... for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { @@ -667,52 +290,6 @@ void OctreeElement::deleteAllChildren() { // if the children_t union represents _children.external we need to delete it here delete[] _children.external; } - -#ifdef BLENDED_UNION_CHILDREN - // now, reset our internal state and ANY and all population data - int childCount = getChildCount(); - switch (childCount) { - case 0: { - _singleChildrenCount--; - _childrenCount[0]--; - } break; - case 1: { - _singleChildrenCount--; - _childrenCount[1]--; - } break; - - case 2: { - if (_childrenExternal) { - _twoChildrenExternalCount--; - } else { - _twoChildrenOffsetCount--; - } - _childrenCount[2]--; - } break; - - case 3: { - if (_childrenExternal) { - _threeChildrenExternalCount--; - } else { - _threeChildrenOffsetCount--; - } - _childrenCount[3]--; - } break; - - default: { - _externalChildrenCount--; - _childrenCount[childCount]--; - } break; - - - } - - // If we had externally stored children, clean them too. - if (_childrenExternal && _children.external) { - delete[] _children.external; - } - _children.single = NULL; -#endif // BLENDED_UNION_CHILDREN } void OctreeElement::setChildAtIndex(int childIndex, OctreeElement* child) { @@ -788,353 +365,6 @@ void OctreeElement::setChildAtIndex(int childIndex, OctreeElement* child) { } #endif // def SIMPLE_EXTERNAL_CHILDREN - -#ifdef BLENDED_UNION_CHILDREN - PerformanceWarning warn(false,"setChildAtIndex",false,&_setChildAtIndexTime,&_setChildAtIndexCalls); - - // Here's how we store things... - // If we have 0 or 1 children, then we just store them in the _children.single; - // If we have 2 children, - // then if we can we store them as 32 bit signed offsets from our own this pointer, - // _children.offsetsTwoChildren[0]-[1] - // these are 32 bit offsets - - unsigned char previousChildMask = _childBitmask; - int previousChildCount = getChildCount(); - if (child) { - setAtBit(_childBitmask, childIndex); - } else { - clearAtBit(_childBitmask, childIndex); - } - int newChildCount = getChildCount(); - - // track our population data - if (previousChildCount != newChildCount) { - _childrenCount[previousChildCount]--; - _childrenCount[newChildCount]++; - } - - // If we had 0 children and we still have 0 children, then there is nothing to do. - if (previousChildCount == 0 && newChildCount == 0) { - // nothing to do... - } else if ((previousChildCount == 0 || previousChildCount == 1) && newChildCount == 1) { - // If we had 0 children, and we're setting our first child or if we had 1 child, or we're resetting the same child, - // then we can just store it in _children.single - _children.single = child; - } else if (previousChildCount == 1 && newChildCount == 0) { - // If we had 1 child, and we've removed our last child, then we can just store NULL in _children.single - _children.single = NULL; - } else if (previousChildCount == 1 && newChildCount == 2) { - // If we had 1 child, and we're adding a second child, then we need to determine - // if we can use offsets to store them - - OctreeElement* childOne; - OctreeElement* childTwo; - - if (getNthBit(previousChildMask, 1) < childIndex) { - childOne = _children.single; - childTwo = child; - } else { - childOne = child; - childTwo = _children.single; - } - - _singleChildrenCount--; - storeTwoChildren(childOne, childTwo); - } else if (previousChildCount == 2 && newChildCount == 1) { - // If we had 2 children, and we're removing one, then we know we can go down to single mode - //assert(child == NULL); // this is the only logical case - - int indexTwo = getNthBit(previousChildMask, 2); - bool keepChildOne = indexTwo == childIndex; - - OctreeElement* childOne; - OctreeElement* childTwo; - - retrieveTwoChildren(childOne, childTwo); - - _singleChildrenCount++; - - if (keepChildOne) { - _children.single = childOne; - } else { - _children.single = childTwo; - } - } else if (previousChildCount == 2 && newChildCount == 2) { - // If we had 2 children, and still have 2, then we know we are resetting one of our existing children - - int indexOne = getNthBit(previousChildMask, 1); - bool replaceChildOne = indexOne == childIndex; - - // Get the existing two children out of their encoding... - OctreeElement* childOne; - OctreeElement* childTwo; - retrieveTwoChildren(childOne, childTwo); - - if (replaceChildOne) { - childOne = child; - } else { - childTwo = child; - } - - storeTwoChildren(childOne, childTwo); - - } else if (previousChildCount == 2 && newChildCount == 3) { - // If we had 2 children, and now have 3, then we know we are going to an external case... - - // First, decode the children... - OctreeElement* childOne; - OctreeElement* childTwo; - OctreeElement* childThree; - - // Get the existing two children out of their encoding... - retrieveTwoChildren(childOne, childTwo); - - // determine order of the existing children - int indexOne = getNthBit(previousChildMask, 1); - int indexTwo = getNthBit(previousChildMask, 2); - - if (childIndex < indexOne) { - childThree = childTwo; - childTwo = childOne; - childOne = child; - } else if (childIndex < indexTwo) { - childThree = childTwo; - childTwo = child; - } else { - childThree = child; - } - storeThreeChildren(childOne, childTwo, childThree); - } else if (previousChildCount == 3 && newChildCount == 2) { - // If we had 3 children, and now have 2, then we know we are going from an external case to a potential internal case - - // We need to determine which children we had, and which one we got rid of... - int indexOne = getNthBit(previousChildMask, 1); - int indexTwo = getNthBit(previousChildMask, 2); - - bool removeChildOne = indexOne == childIndex; - bool removeChildTwo = indexTwo == childIndex; - - OctreeElement* childOne; - OctreeElement* childTwo; - OctreeElement* childThree; - - // Get the existing two children out of their encoding... - retrieveThreeChildren(childOne, childTwo, childThree); - - if (removeChildOne) { - childOne = childTwo; - childTwo = childThree; - } else if (removeChildTwo) { - childTwo = childThree; - } else { - // removing child three, nothing to do. - } - - storeTwoChildren(childOne, childTwo); - } else if (previousChildCount == 3 && newChildCount == 3) { - // If we had 3 children, and now have 3, then we need to determine which item we're replacing... - - // We need to determine which children we had, and which one we got rid of... - int indexOne = getNthBit(previousChildMask, 1); - int indexTwo = getNthBit(previousChildMask, 2); - - bool replaceChildOne = indexOne == childIndex; - bool replaceChildTwo = indexTwo == childIndex; - - OctreeElement* childOne; - OctreeElement* childTwo; - OctreeElement* childThree; - - // Get the existing two children out of their encoding... - retrieveThreeChildren(childOne, childTwo, childThree); - - if (replaceChildOne) { - childOne = child; - } else if (replaceChildTwo) { - childTwo = child; - } else { - childThree = child; - } - - storeThreeChildren(childOne, childTwo, childThree); - } else if (previousChildCount == 3 && newChildCount == 4) { - // If we had 3 children, and now have 4, then we know we are going to an external case... - - // First, decode the children... - OctreeElement* childOne; - OctreeElement* childTwo; - OctreeElement* childThree; - OctreeElement* childFour; - - // Get the existing two children out of their encoding... - retrieveThreeChildren(childOne, childTwo, childThree); - - // determine order of the existing children - int indexOne = getNthBit(previousChildMask, 1); - int indexTwo = getNthBit(previousChildMask, 2); - int indexThree = getNthBit(previousChildMask, 3); - - if (childIndex < indexOne) { - childFour = childThree; - childThree = childTwo; - childTwo = childOne; - childOne = child; - } else if (childIndex < indexTwo) { - childFour = childThree; - childThree = childTwo; - childTwo = child; - } else if (childIndex < indexThree) { - childFour = childThree; - childThree = child; - } else { - childFour = child; - } - - // now, allocate the external... - _childrenExternal = true; - const int newChildCount = 4; - _children.external = new OctreeElement*[newChildCount]; - memset(_children.external, 0, sizeof(OctreeElement*) * newChildCount); - - _externalChildrenMemoryUsage += newChildCount * sizeof(OctreeElement*); - - _children.external[0] = childOne; - _children.external[1] = childTwo; - _children.external[2] = childThree; - _children.external[3] = childFour; - _externalChildrenCount++; - } else if (previousChildCount == 4 && newChildCount == 3) { - // If we had 4 children, and now have 3, then we know we are going from an external case to a potential internal case - //assert(_children.external && _childrenExternal && previousChildCount == 4); - - // We need to determine which children we had, and which one we got rid of... - int indexOne = getNthBit(previousChildMask, 1); - int indexTwo = getNthBit(previousChildMask, 2); - int indexThree = getNthBit(previousChildMask, 3); - - bool removeChildOne = indexOne == childIndex; - bool removeChildTwo = indexTwo == childIndex; - bool removeChildThree = indexThree == childIndex; - - OctreeElement* childOne = _children.external[0]; - OctreeElement* childTwo = _children.external[1]; - OctreeElement* childThree = _children.external[2]; - OctreeElement* childFour = _children.external[3]; - - if (removeChildOne) { - childOne = childTwo; - childTwo = childThree; - childThree = childFour; - } else if (removeChildTwo) { - childTwo = childThree; - childThree = childFour; - } else if (removeChildThree) { - childThree = childFour; - } else { - // removing child four, nothing to do. - } - - // clean up the external children... - _childrenExternal = false; - delete[] _children.external; - _children.external = NULL; - _externalChildrenCount--; - _externalChildrenMemoryUsage -= previousChildCount * sizeof(OctreeElement*); - storeThreeChildren(childOne, childTwo, childThree); - } else if (previousChildCount == newChildCount) { - //assert(_children.external && _childrenExternal && previousChildCount >= 4); - //assert(previousChildCount == newChildCount); - - // 4 or more children, one item being replaced, we know we're stored externally, we just need to find the one - // that needs to be replaced and replace it. - for (int ordinal = 1; ordinal <= 8; ordinal++) { - int index = getNthBit(previousChildMask, ordinal); - if (index == childIndex) { - // this is our child to be replaced - int nthChild = ordinal-1; - _children.external[nthChild] = child; - break; - } - } - } else if (previousChildCount < newChildCount) { - // Growing case... previous must be 4 or greater - //assert(_children.external && _childrenExternal && previousChildCount >= 4); - //assert(previousChildCount == newChildCount-1); - - // 4 or more children, one item being added, we know we're stored externally, we just figure out where to insert - // this child pointer into our external list - OctreeElement** newExternalList = new OctreeElement*[newChildCount]; - memset(newExternalList, 0, sizeof(OctreeElement*) * newChildCount); - - int copiedCount = 0; - for (int ordinal = 1; ordinal <= newChildCount; ordinal++) { - int index = getNthBit(previousChildMask, ordinal); - if (index != -1 && index < childIndex) { - newExternalList[ordinal - 1] = _children.external[ordinal - 1]; - copiedCount++; - } else { - - // insert our new child here... - newExternalList[ordinal - 1] = child; - - // if we didn't copy all of our previous children, then we need to - if (copiedCount < previousChildCount) { - // our child needs to be inserted before this index, and everything else pushed out... - for (int oldOrdinal = ordinal; oldOrdinal <= previousChildCount; oldOrdinal++) { - newExternalList[oldOrdinal] = _children.external[oldOrdinal - 1]; - } - } - break; - } - } - delete[] _children.external; - _children.external = newExternalList; - _externalChildrenMemoryUsage -= previousChildCount * sizeof(OctreeElement*); - _externalChildrenMemoryUsage += newChildCount * sizeof(OctreeElement*); - - } else if (previousChildCount > newChildCount) { - //assert(_children.external && _childrenExternal && previousChildCount >= 4); - //assert(previousChildCount == newChildCount+1); - - // 4 or more children, one item being removed, we know we're stored externally, we just figure out which - // item to remove from our external list - OctreeElement** newExternalList = new OctreeElement*[newChildCount]; - - for (int ordinal = 1; ordinal <= previousChildCount; ordinal++) { - int index = getNthBit(previousChildMask, ordinal); - //assert(index != -1); - if (index < childIndex) { - newExternalList[ordinal - 1] = _children.external[ordinal - 1]; - } else { - // our child needs to be removed from here, and everything else pulled in... - for (int moveOrdinal = ordinal; moveOrdinal <= newChildCount; moveOrdinal++) { - newExternalList[moveOrdinal - 1] = _children.external[moveOrdinal]; - } - break; - } - } - delete[] _children.external; - _children.external = newExternalList; - _externalChildrenMemoryUsage -= previousChildCount * sizeof(OctreeElement*); - _externalChildrenMemoryUsage += newChildCount * sizeof(OctreeElement*); - } else { - //assert(false); - qCDebug(octree, "THIS SHOULD NOT HAPPEN previousChildCount == %d && newChildCount == %d",previousChildCount, newChildCount); - } - - // check to see if we could store these 4 children locally - if (getChildCount() == 4 && _childrenExternal && _children.external) { - checkStoreFourChildren(_children.external[0], _children.external[1], _children.external[2], _children.external[3]); - } - - -#ifdef HAS_AUDIT_CHILDREN - _childrenArray[childIndex] = child; - auditChildren("setChildAtIndex()"); -#endif // def HAS_AUDIT_CHILDREN - -#endif } diff --git a/libraries/octree/src/OctreeElement.h b/libraries/octree/src/OctreeElement.h index e2229b2214..830655242f 100644 --- a/libraries/octree/src/OctreeElement.h +++ b/libraries/octree/src/OctreeElement.h @@ -12,7 +12,6 @@ #ifndef hifi_OctreeElement_h #define hifi_OctreeElement_h -//#define HAS_AUDIT_CHILDREN //#define SIMPLE_CHILD_ARRAY #define SIMPLE_EXTERNAL_CHILDREN @@ -204,25 +203,9 @@ public: static quint64 getSetChildAtIndexTime() { return _setChildAtIndexTime; } static quint64 getSetChildAtIndexCalls() { return _setChildAtIndexCalls; } -#ifdef BLENDED_UNION_CHILDREN - static quint64 getSingleChildrenCount() { return _singleChildrenCount; } - static quint64 getTwoChildrenOffsetCount() { return _twoChildrenOffsetCount; } - static quint64 getTwoChildrenExternalCount() { return _twoChildrenExternalCount; } - static quint64 getThreeChildrenOffsetCount() { return _threeChildrenOffsetCount; } - static quint64 getThreeChildrenExternalCount() { return _threeChildrenExternalCount; } - static quint64 getCouldStoreFourChildrenInternally() { return _couldStoreFourChildrenInternally; } - static quint64 getCouldNotStoreFourChildrenInternally() { return _couldNotStoreFourChildrenInternally; } -#endif - static quint64 getExternalChildrenCount() { return _externalChildrenCount; } static quint64 getChildrenCount(int childCount) { return _childrenCount[childCount]; } -#ifdef BLENDED_UNION_CHILDREN -#ifdef HAS_AUDIT_CHILDREN - void auditChildren(const char* label) const; -#endif // def HAS_AUDIT_CHILDREN -#endif // def BLENDED_UNION_CHILDREN - enum ChildIndex { CHILD_BOTTOM_RIGHT_NEAR = 0, CHILD_BOTTOM_RIGHT_FAR = 1, @@ -261,15 +244,6 @@ protected: void deleteAllChildren(); void setChildAtIndex(int childIndex, OctreeElement* child); -#ifdef BLENDED_UNION_CHILDREN - void storeTwoChildren(OctreeElement* childOne, OctreeElement* childTwo); - void retrieveTwoChildren(OctreeElement*& childOne, OctreeElement*& childTwo); - void storeThreeChildren(OctreeElement* childOne, OctreeElement* childTwo, OctreeElement* childThree); - void retrieveThreeChildren(OctreeElement*& childOne, OctreeElement*& childTwo, OctreeElement*& childThree); - void decodeThreeOffsets(int64_t& offsetOne, int64_t& offsetTwo, int64_t& offsetThree) const; - void encodeThreeOffsets(int64_t offsetOne, int64_t offsetTwo, int64_t offsetThree); - void checkStoreFourChildren(OctreeElement* childOne, OctreeElement* childTwo, OctreeElement* childThree, OctreeElement* childFour); -#endif void calculateAACube(); void notifyDeleteHooks(); void notifyUpdateHooks(); @@ -296,19 +270,6 @@ protected: } _children; #endif -#ifdef BLENDED_UNION_CHILDREN - union children_t { - OctreeElement* single; - int32_t offsetsTwoChildren[2]; - quint64 offsetsThreeChildrenEncoded; - OctreeElement** external; - } _children; -#ifdef HAS_AUDIT_CHILDREN - OctreeElement* _childrenArray[8]; /// Only used when HAS_AUDIT_CHILDREN is enabled to help debug children encoding -#endif // def HAS_AUDIT_CHILDREN - -#endif //def BLENDED_UNION_CHILDREN - uint16_t _sourceUUIDKey; /// Client only, stores node id of voxel server that sent his voxel, 2 bytes // Support for _sourceUUID, we use these static member variables to track the UUIDs that are @@ -345,15 +306,6 @@ protected: static quint64 _setChildAtIndexTime; static quint64 _setChildAtIndexCalls; -#ifdef BLENDED_UNION_CHILDREN - static quint64 _singleChildrenCount; - static quint64 _twoChildrenOffsetCount; - static quint64 _twoChildrenExternalCount; - static quint64 _threeChildrenOffsetCount; - static quint64 _threeChildrenExternalCount; - static quint64 _couldStoreFourChildrenInternally; - static quint64 _couldNotStoreFourChildrenInternally; -#endif static quint64 _externalChildrenCount; static quint64 _childrenCount[NUMBER_OF_CHILDREN + 1]; }; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index e0c66eb604..850baf3d06 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -135,7 +135,6 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) { assert(renderContext->args); assert(renderContext->args->_viewFrustum); - auto& renderDetails = renderContext->args->_details; RenderArgs* args = renderContext->args; gpu::Batch batch; diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 6076ec0006..46103f7803 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -59,7 +59,6 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont assert(renderContext->args); assert(renderContext->args->_viewFrustum); - auto& scene = sceneContext->_scene; RenderArgs* args = renderContext->args; auto renderDetails = renderContext->args->_details._item; @@ -101,7 +100,6 @@ void render::cullItems(const SceneContextPointer& sceneContext, const RenderCont void FetchItems::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, ItemIDsBounds& outItems) { auto& scene = sceneContext->_scene; auto& items = scene->getMasterBucket().at(_filter); - auto& renderDetails = renderContext->args->_details; outItems.clear(); outItems.reserve(items.size()); From 3d06b011aa2863bb1dc2027c9afbdc5ce1a18ecb Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Fri, 3 Jul 2015 13:27:00 -0700 Subject: [PATCH 11/14] adding batch to renderHUD --- .../src/ui/overlays/BillboardOverlay.cpp | 2 -- interface/src/ui/overlays/Grid3DOverlay.cpp | 2 -- interface/src/ui/overlays/Overlays.cpp | 6 ++++ .../src/ui/overlays/Rectangle3DOverlay.cpp | 3 -- interface/src/ui/overlays/Sphere3DOverlay.cpp | 28 ------------------- 5 files changed, 6 insertions(+), 35 deletions(-) diff --git a/interface/src/ui/overlays/BillboardOverlay.cpp b/interface/src/ui/overlays/BillboardOverlay.cpp index 913eb749a9..988223765a 100644 --- a/interface/src/ui/overlays/BillboardOverlay.cpp +++ b/interface/src/ui/overlays/BillboardOverlay.cpp @@ -93,8 +93,6 @@ void BillboardOverlay::render(RenderArgs* args) { glm::vec4(color.red / MAX_COLOR, color.green / MAX_COLOR, color.blue / MAX_COLOR, alpha)); batch->setUniformTexture(0, args->_whiteTexture); // restore default white color after me - } else { - qDebug() << "NO NAKED GL CALLS ALLOWED HERE! PLEASE USE THE BATCHING SYSTEM NEXT TIME"; } } diff --git a/interface/src/ui/overlays/Grid3DOverlay.cpp b/interface/src/ui/overlays/Grid3DOverlay.cpp index 295dc1b2b5..baf7b42ac5 100644 --- a/interface/src/ui/overlays/Grid3DOverlay.cpp +++ b/interface/src/ui/overlays/Grid3DOverlay.cpp @@ -89,8 +89,6 @@ void Grid3DOverlay::render(RenderArgs* args) { DependencyManager::get()->renderGrid(*batch, MAJOR_GRID_DIVISIONS, MAJOR_GRID_DIVISIONS, gridColor); } - } else { - qDebug() << "NO NAKED GL CALLS ALLOWED HERE! PLEASE USE THE BATCHING SYSTEM NEXT TIME"; } } diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index dc49478f38..fb0a095e13 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "BillboardOverlay.h" #include "Circle3DOverlay.h" @@ -96,6 +97,10 @@ void Overlays::cleanupOverlaysToDelete() { void Overlays::renderHUD(RenderArgs* renderArgs) { QReadLocker lock(&_lock); + gpu::Batch batch; + renderArgs->_batch = &batch; + + foreach(Overlay::Pointer thisOverlay, _overlaysHUD) { if (thisOverlay->is3D()) { glEnable(GL_DEPTH_TEST); @@ -109,6 +114,7 @@ void Overlays::renderHUD(RenderArgs* renderArgs) { thisOverlay->render(renderArgs); } } + gpu::GLBackend::renderBatch(batch, true); } unsigned int Overlays::addOverlay(const QString& type, const QScriptValue& properties) { diff --git a/interface/src/ui/overlays/Rectangle3DOverlay.cpp b/interface/src/ui/overlays/Rectangle3DOverlay.cpp index 6f35ccb3d0..ddab8040b1 100644 --- a/interface/src/ui/overlays/Rectangle3DOverlay.cpp +++ b/interface/src/ui/overlays/Rectangle3DOverlay.cpp @@ -87,9 +87,6 @@ void Rectangle3DOverlay::render(RenderArgs* args) { geometryCache->renderVertices(*batch, gpu::LINE_STRIP, _geometryCacheID); } } - } else { - - qDebug() << "NO NAKED GL CALLS ALLOWED HERE! PLEASE USE THE BATCHING SYSTEM NEXT TIME"; } } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index dd60ee4af8..259fe98acf 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -41,34 +41,6 @@ void Sphere3DOverlay::render(RenderArgs* args) { transform.postScale(getDimensions()); batch->setModelTransform(transform); DependencyManager::get()->renderSphere(*batch, 1.0f, SLICES, SLICES, sphereColor, _isSolid); - } else { - glDisable(GL_LIGHTING); - - glm::vec3 position = getPosition(); - glm::vec3 center = getCenter(); - glm::vec3 dimensions = getDimensions(); - glm::quat rotation = getRotation(); - - float glowLevel = getGlowLevel(); - Glower* glower = NULL; - if (glowLevel > 0.0f) { - glower = new Glower(glowLevel); - } - - Transform transform = Transform(); - transform.setTranslation(position); - glm::vec3 axis = glm::axis(rotation); - transform.setRotation(glm::angleAxis(glm::angle(rotation), axis)); - - glm::vec3 positionToCenter = center - position; - transform.setTranslation(positionToCenter); - transform.setScale(dimensions); - DependencyManager::get()->renderSphere(*batch, 1.0f, SLICES, SLICES, sphereColor, _isSolid); - - - if (glower) { - delete glower; - } } } From 40cdd8646e3c727fdbb558fd618ed231a39e274b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 3 Jul 2015 15:53:53 -0700 Subject: [PATCH 12/14] add packets per second to octree processing stats --- interface/src/ui/OctreeStatsDialog.cpp | 12 ++++++++++++ interface/src/ui/OctreeStatsDialog.h | 1 + libraries/octree/src/OctreeRenderer.cpp | 5 +++++ libraries/octree/src/OctreeRenderer.h | 4 ++++ 4 files changed, 22 insertions(+) diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 4c95e7a68a..eea962b412 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -53,6 +53,7 @@ OctreeStatsDialog::OctreeStatsDialog(QWidget* parent, NodeToOctreeSceneStats* mo _localElementsMemory = AddStatItem("Elements Memory"); _sendingMode = AddStatItem("Sending Mode"); + _processedPackets = AddStatItem("Processed Packets"); _processedPacketsElements = AddStatItem("Processed Packets Elements"); _processedPacketsEntities = AddStatItem("Processed Packets Entities"); _processedPacketsTiming = AddStatItem("Processed Packets Timing"); @@ -219,6 +220,8 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { // Processed Packets Elements auto averageElementsPerPacket = entities->getAverageElementsPerPacket(); auto averageEntitiesPerPacket = entities->getAverageEntitiesPerPacket(); + + auto averagePacketsPerSecond = entities->getAveragePacketsPerSecond(); auto averageElementsPerSecond = entities->getAverageElementsPerSecond(); auto averageEntitiesPerSecond = entities->getAverageEntitiesPerSecond(); @@ -228,6 +231,8 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { QString averageElementsPerPacketString = locale.toString(averageElementsPerPacket); QString averageEntitiesPerPacketString = locale.toString(averageEntitiesPerPacket); + + QString averagePacketsPerSecondString = locale.toString(averagePacketsPerSecond); QString averageElementsPerSecondString = locale.toString(averageElementsPerSecond); QString averageEntitiesPerSecondString = locale.toString(averageEntitiesPerSecond); @@ -235,6 +240,13 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { QString averageUncompressPerPacketString = locale.toString(averageUncompressPerPacket); QString averageReadBitstreamPerPacketString = locale.toString(averageReadBitstreamPerPacket); + label = _labels[_processedPackets]; + statsValue.str(""); + statsValue << + "" << qPrintable(averagePacketsPerSecondString) << " per second"; + + label->setText(statsValue.str().c_str()); + label = _labels[_processedPacketsElements]; statsValue.str(""); statsValue << diff --git a/interface/src/ui/OctreeStatsDialog.h b/interface/src/ui/OctreeStatsDialog.h index 986080de56..f56a00bc86 100644 --- a/interface/src/ui/OctreeStatsDialog.h +++ b/interface/src/ui/OctreeStatsDialog.h @@ -66,6 +66,7 @@ private: int _entityUpdateTime; int _entityUpdates; + int _processedPackets; int _processedPacketsElements; int _processedPacketsEntities; int _processedPacketsTiming; diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 6fa3f47120..d0aebd216e 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -101,6 +101,8 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar sequence, flightTime, packetLength, dataBytes); } + _packetsInLastWindow++; + int elementsPerPacket = 0; int entitiesPerPacket = 0; @@ -185,12 +187,15 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar const quint64 USECS_PER_SECOND = 1000 * 1000; if (sinceLastWindow > USECS_PER_SECOND) { + float packetsPerSecondInWindow = (float)_packetsInLastWindow / (float)(sinceLastWindow / USECS_PER_SECOND); float elementsPerSecondInWindow = (float)_elementsInLastWindow / (float)(sinceLastWindow / USECS_PER_SECOND); float entitiesPerSecondInWindow = (float)_entitiesInLastWindow / (float)(sinceLastWindow / USECS_PER_SECOND); + _packetsPerSecond.updateAverage(packetsPerSecondInWindow); _elementsPerSecond.updateAverage(elementsPerSecondInWindow); _entitiesPerSecond.updateAverage(entitiesPerSecondInWindow); _lastWindowAt = now; + _packetsInLastWindow = 0; _elementsInLastWindow = 0; _entitiesInLastWindow = 0; } diff --git a/libraries/octree/src/OctreeRenderer.h b/libraries/octree/src/OctreeRenderer.h index 894e5c2355..cf3b2a2ecd 100644 --- a/libraries/octree/src/OctreeRenderer.h +++ b/libraries/octree/src/OctreeRenderer.h @@ -64,6 +64,7 @@ public: float getAverageElementsPerPacket() const { return _elementsPerPacket.getAverage(); } float getAverageEntitiesPerPacket() const { return _entitiesPerPacket.getAverage(); } + float getAveragePacketsPerSecond() const { return _packetsPerSecond.getAverage(); } float getAverageElementsPerSecond() const { return _elementsPerSecond.getAverage(); } float getAverageEntitiesPerSecond() const { return _entitiesPerSecond.getAverage(); } @@ -80,6 +81,8 @@ protected: SimpleMovingAverage _elementsPerPacket; SimpleMovingAverage _entitiesPerPacket; + + SimpleMovingAverage _packetsPerSecond; SimpleMovingAverage _elementsPerSecond; SimpleMovingAverage _entitiesPerSecond; @@ -88,6 +91,7 @@ protected: SimpleMovingAverage _readBitstreamPerPacket; quint64 _lastWindowAt = 0; + int _packetsInLastWindow = 0; int _elementsInLastWindow = 0; int _entitiesInLastWindow = 0; From 74733452da2cdda7ead883bb680983f0ac809df2 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 Jul 2015 11:25:27 -0700 Subject: [PATCH 13/14] some tweaks to make stats dialog more readable --- interface/src/Menu.cpp | 1 + interface/src/Menu.h | 1 + interface/src/ui/OctreeStatsDialog.cpp | 48 ++++++++++++++++---------- interface/src/ui/OctreeStatsDialog.h | 2 ++ 4 files changed, 33 insertions(+), 19 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index c70d11b837..9f49361f79 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -531,6 +531,7 @@ Menu::Menu() { addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::PipelineWarnings); addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::LogExtraTimings); addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::SuppressShortTimings); + addCheckableActionToQMenuAndActionHash(timingMenu, MenuOption::ShowRealtimeEntityStats); auto audioIO = DependencyManager::get(); MenuWrapper* audioDebugMenu = developerMenu->addMenu("Audio"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index fae7092989..043bb53a7f 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -269,6 +269,7 @@ namespace MenuOption { const QString ShowDSConnectTable = "Show Domain Connection Timing"; const QString ShowBordersEntityNodes = "Show Entity Nodes"; const QString ShowIKConstraints = "Show IK Constraints"; + const QString ShowRealtimeEntityStats = "Show Realtime Entity Stats"; const QString SimpleShadows = "Simple"; const QString SixenseEnabled = "Enable Hydra Support"; const QString SixenseMouseInput = "Enable Sixense Mouse Input"; diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index eea962b412..94f91a5ab7 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -129,6 +129,34 @@ OctreeStatsDialog::~OctreeStatsDialog() { void OctreeStatsDialog::paintEvent(QPaintEvent* event) { + // Processed Entities Related stats + auto entities = Application::getInstance()->getEntities(); + auto entitiesTree = entities->getTree(); + + // Do this ever paint event... even if we don't update + auto totalTrackedEdits = entitiesTree->getTotalTrackedEdits(); + + // track our updated per second + const quint64 SAMPLING_WINDOW = USECS_PER_SECOND / SAMPLES_PER_SECOND; + quint64 now = usecTimestampNow(); + quint64 sinceLastWindow = now - _lastWindowAt; + auto editsInLastWindow = totalTrackedEdits - _lastKnownTrackedEdits; + float sinceLastWindowInSeconds = (float)sinceLastWindow / (float)USECS_PER_SECOND; + float recentUpdatesPerSecond = (float)editsInLastWindow / sinceLastWindowInSeconds; + if (sinceLastWindow > SAMPLING_WINDOW) { + _averageUpdatesPerSecond.updateAverage(recentUpdatesPerSecond); + _lastWindowAt = now; + _lastKnownTrackedEdits = totalTrackedEdits; + } + + // Only refresh our stats every once in a while, unless asked for realtime + quint64 REFRESH_AFTER = Menu::getInstance()->isOptionChecked(MenuOption::ShowRealtimeEntityStats) ? 0 : USECS_PER_SECOND; + quint64 sinceLastRefresh = now - _lastRefresh; + if (sinceLastRefresh < REFRESH_AFTER) { + return QDialog::paintEvent(event); + } + _lastRefresh = now; + // Update labels QLabel* label; @@ -213,10 +241,6 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { "Leaves: " << qPrintable(serversLeavesString) << ""; label->setText(statsValue.str().c_str()); - // Processed Entities Related stats - auto entities = Application::getInstance()->getEntities(); - auto entitiesTree = entities->getTree(); - // Processed Packets Elements auto averageElementsPerPacket = entities->getAverageElementsPerPacket(); auto averageEntitiesPerPacket = entities->getAverageEntitiesPerPacket(); @@ -289,22 +313,8 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { // Entity Edits label = _labels[_entityUpdates]; - auto totalTrackedEdits = entitiesTree->getTotalTrackedEdits(); auto bytesPerEdit = entitiesTree->getAverageEditBytes(); - // track our updated per second - const quint64 SAMPLING_WINDOW = USECS_PER_SECOND / SAMPLES_PER_SECOND; - quint64 now = usecTimestampNow(); - quint64 sinceLastWindow = now - _lastWindowAt; - auto editsInLastWindow = totalTrackedEdits - _lastKnownTrackedEdits; - float sinceLastWindowInSeconds = (float)sinceLastWindow / (float)USECS_PER_SECOND; - float recentUpdatesPerSecond = (float)editsInLastWindow / sinceLastWindowInSeconds; - if (sinceLastWindow > SAMPLING_WINDOW) { - _averageUpdatesPerSecond.updateAverage(recentUpdatesPerSecond); - _lastWindowAt = now; - _lastKnownTrackedEdits = totalTrackedEdits; - } - auto updatesPerSecond = _averageUpdatesPerSecond.getAverage(); if (updatesPerSecond < 1) { updatesPerSecond = 0; // we don't really care about small updates per second so suppress those @@ -324,7 +334,7 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { showAllOctreeServers(); - this->QDialog::paintEvent(event); + QDialog::paintEvent(event); } void OctreeStatsDialog::showAllOctreeServers() { int serverCount = 0; diff --git a/interface/src/ui/OctreeStatsDialog.h b/interface/src/ui/OctreeStatsDialog.h index f56a00bc86..063c04b295 100644 --- a/interface/src/ui/OctreeStatsDialog.h +++ b/interface/src/ui/OctreeStatsDialog.h @@ -76,6 +76,8 @@ private: quint64 _lastWindowAt = 0; quint64 _lastKnownTrackedEdits = 0; + quint64 _lastRefresh = 0; + int _octreeServerLables[MAX_VOXEL_SERVERS]; int _octreeServerLabelsCount; details _extraServerDetails[MAX_VOXEL_SERVERS]; From c4a5160b890260f75f21e99e88e6f9e8267fc43e Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 Jul 2015 19:13:35 -0700 Subject: [PATCH 14/14] CR feedback --- libraries/octree/src/OctreeRenderer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index d0aebd216e..c4534b2565 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -12,9 +12,11 @@ #include #include -#include +#include #include #include +#include + #include "OctreeLogging.h" #include "OctreeRenderer.h" @@ -185,7 +187,6 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar } quint64 sinceLastWindow = now - _lastWindowAt; - const quint64 USECS_PER_SECOND = 1000 * 1000; if (sinceLastWindow > USECS_PER_SECOND) { float packetsPerSecondInWindow = (float)_packetsInLastWindow / (float)(sinceLastWindow / USECS_PER_SECOND); float elementsPerSecondInWindow = (float)_elementsInLastWindow / (float)(sinceLastWindow / USECS_PER_SECOND);