From b74aad32ede3cb9d9c65d538c28b6099ca216f2c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 10 Jul 2017 18:27:40 -0700 Subject: [PATCH 01/10] minor cleanup in OctreeSendThread::packetDistributor() --- .../src/octree/OctreeSendThread.cpp | 56 ++++++------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 7db06f12c0..2a4e317670 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -334,8 +334,6 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* && ((!viewFrustumChanged && nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged())); } - bool somethingToSend = true; // assume we have something - // If our packet already has content in it, then we must use the color choice of the waiting packet. // If we're starting a fresh packet, then... // If we're moving, and the client asked for low res, then we force monochrome, otherwise, use @@ -404,7 +402,6 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* // If we have something in our elementBag, then turn them into packets and send them out... if (!nodeData->elementBag.isEmpty()) { - int bytesWritten = 0; quint64 start = usecTimestampNow(); // TODO: add these to stats page @@ -414,6 +411,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* int extraPackingAttempts = 0; bool completedScene = false; + bool somethingToSend = true; // assume we have something while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval && !nodeData->isShuttingDown()) { float lockWaitElapsedUsec = OctreeServer::SKIP_TIME; float encodeElapsedUsec = OctreeServer::SKIP_TIME; @@ -461,7 +459,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* // are reported to client. Since you can encode without the lock nodeData->stats.encodeStarted(); - bytesWritten = _myServer->getOctree()->encodeTreeBitstream(subTree, &_packetData, nodeData->elementBag, params); + _myServer->getOctree()->encodeTreeBitstream(subTree, &_packetData, nodeData->elementBag, params); quint64 encodeEnd = usecTimestampNow(); encodeElapsedUsec = (float)(encodeEnd - encodeStart); @@ -479,45 +477,30 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* nodeData->stats.encodeStopped(); }); } else { - // If the bag was empty then we didn't even attempt to encode, and so we know the bytesWritten were 0 - bytesWritten = 0; somethingToSend = false; // this will cause us to drop out of the loop... } - // If the last node didn't fit, but we're in compressed mode, then we actually want to see if we can fit a - // little bit more in this packet. To do this we write into the packet, but don't send it yet, we'll - // keep attempting to write in compressed mode to add more compressed segments - - // We only consider sending anything if there is something in the _packetData to send... But - // if bytesWritten == 0 it means either the subTree couldn't fit or we had an empty bag... Both cases - // mean we should send the previous packet contents and reset it. if (completedScene || lastNodeDidntFit) { - + // we probably want to flush what has accumulated in nodeData but: + // do we have more data to send? and is there room? if (_packetData.hasContent()) { + // yes, more data to send quint64 compressAndWriteStart = usecTimestampNow(); - - // if for some reason the finalized size is greater than our available size, then probably the "compressed" - // form actually inflated beyond our padding, and in this case we will send the current packet, then - // write to out new packet... - unsigned int writtenSize = _packetData.getFinalizedSize() + sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); - - if (writtenSize > nodeData->getAvailable()) { + unsigned int additionalSize = _packetData.getFinalizedSize() + sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); + if (additionalSize > nodeData->getAvailable()) { + // no room --> flush what we've got packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent); } + // either there is room, or we've flushed and reset nodeData's data buffer + // so we can transfer whatever is in _packetData to nodeData nodeData->writeToPacket(_packetData.getFinalizedData(), _packetData.getFinalizedSize()); - quint64 compressAndWriteEnd = usecTimestampNow(); - compressAndWriteElapsedUsec = (float)(compressAndWriteEnd - compressAndWriteStart); + compressAndWriteElapsedUsec = (float)(usecTimestampNow()- compressAndWriteStart); } - // If we're not running compressed, then we know we can just send now. Or if we're running compressed, but - // the packet doesn't have enough space to bother attempting to pack more... - bool sendNow = true; - - if (!completedScene && (nodeData->getAvailable() >= MINIMUM_ATTEMPT_MORE_PACKING && - extraPackingAttempts <= REASONABLE_NUMBER_OF_PACKING_ATTEMPTS)) { - sendNow = false; // try to pack more - } + bool sendNow = completedScene || + nodeData->getAvailable() < MINIMUM_ATTEMPT_MORE_PACKING || + extraPackingAttempts > REASONABLE_NUMBER_OF_PACKING_ATTEMPTS; int targetSize = MAX_OCTREE_PACKET_DATA_SIZE; if (sendNow) { @@ -529,16 +512,13 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); extraPackingAttempts = 0; } else { - // If we're in compressed mode, then we want to see if we have room for more in this wire packet. - // but we've finalized the _packetData, so we want to start a new section, we will do that by - // resetting the packet settings with the max uncompressed size of our current available space - // in the wire packet. We also include room for our section header, and a little bit of padding - // to account for the fact that whenc compressing small amounts of data, we sometimes end up with - // a larger compressed size then uncompressed size + // We want to see if we have room for more in this wire packet but we've copied the _packetData, + // so we want to start a new section. We will do that by resetting the packet settings with the max + // size of our current available space in the wire packet plus room for our section header and a + // little bit of padding. targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) - COMPRESS_PADDING; } _packetData.changeSettings(true, targetSize); // will do reset - NOTE: Always compressed - } OctreeServer::trackTreeWaitTime(lockWaitElapsedUsec); OctreeServer::trackEncodeTime(encodeElapsedUsec); From 076ae28bed5d46df9d892bf831940b102845931c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Jul 2017 09:52:39 -0700 Subject: [PATCH 02/10] one less strand of spaghetti when counting packets --- .../src/octree/OctreeSendThread.cpp | 28 +++++++++++-------- .../src/octree/OctreeSendThread.h | 6 ++-- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 2a4e317670..028128e80b 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -130,7 +130,7 @@ AtomicUIntStat OctreeSendThread::_totalSpecialPackets { 0 }; int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, int& trueBytesSent, - int& truePacketsSent, bool dontSuppressDuplicate) { + bool dontSuppressDuplicate) { OctreeServer::didHandlePacketSend(this); // if we're shutting down, then exit early @@ -222,7 +222,6 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* } trueBytesSent += statsPacket.getDataSize(); - truePacketsSent++; packetsSent++; OctreeServer::didCallWriteDatagram(this); @@ -290,7 +289,6 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* if (packetSent) { nodeData->stats.packetSent(nodeData->getPacket().getPayloadSize()); trueBytesSent += nodeData->getPacket().getPayloadSize(); - truePacketsSent++; packetsSent++; nodeData->octreePacketSent(); nodeData->resetOctreePacket(); @@ -342,7 +340,9 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* // If we have a packet waiting, and our desired want color, doesn't match the current waiting packets color // then let's just send that waiting packet. if (nodeData->isPacketWaiting()) { - packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent); + int numPackets = handlePacketSend(node, nodeData, trueBytesSent); + truePacketsSent += numPackets; + packetsSentThisInterval += numPackets; } else { nodeData->resetOctreePacket(); } @@ -373,8 +373,9 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* //unsigned long encodeTime = nodeData->stats.getTotalEncodeTime(); //unsigned long elapsedTime = nodeData->stats.getElapsedTime(); - int packetsJustSent = handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent, isFullScene); - packetsSentThisInterval += packetsJustSent; + int numPackets = handlePacketSend(node, nodeData, trueBytesSent, isFullScene); + truePacketsSent += numPackets; + packetsSentThisInterval += numPackets; // If we're starting a full scene, then definitely we want to empty the elementBag if (isFullScene) { @@ -489,7 +490,9 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* unsigned int additionalSize = _packetData.getFinalizedSize() + sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); if (additionalSize > nodeData->getAvailable()) { // no room --> flush what we've got - packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent); + int numPackets = handlePacketSend(node, nodeData, trueBytesSent); + truePacketsSent += numPackets; + packetsSentThisInterval += numPackets; } // either there is room, or we've flushed and reset nodeData's data buffer @@ -505,7 +508,9 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* int targetSize = MAX_OCTREE_PACKET_DATA_SIZE; if (sendNow) { quint64 packetSendingStart = usecTimestampNow(); - packetsSentThisInterval += handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent); + int numPackets = handlePacketSend(node, nodeData, trueBytesSent); + truePacketsSent += numPackets; + packetsSentThisInterval += numPackets; quint64 packetSendingEnd = usecTimestampNow(); packetSendingElapsedUsec = (float)(packetSendingEnd - packetSendingStart); @@ -587,12 +592,11 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* // the clients will know the scene is stable if (isFullScene) { int thisTrueBytesSent = 0; - int thisTruePacketsSent = 0; nodeData->stats.sceneCompleted(); - int packetsJustSent = handlePacketSend(node, nodeData, thisTrueBytesSent, thisTruePacketsSent, true); + int numPackets = handlePacketSend(node, nodeData, thisTrueBytesSent, true); _totalBytes += thisTrueBytesSent; - _totalPackets += thisTruePacketsSent; - truePacketsSent += packetsJustSent; + _totalPackets += numPackets; + truePacketsSent += numPackets; } } diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index 06c9b5f1d6..f1d153b6e3 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -34,7 +34,7 @@ public: void setIsShuttingDown(); bool isShuttingDown() { return _isShuttingDown; } - + QUuid getNodeUuid() const { return _nodeUuid; } static AtomicUIntStat _totalBytes; @@ -58,9 +58,9 @@ protected: QWeakPointer _node; private: - int handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent, bool dontSuppressDuplicate = false); + int handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, int& trueBytesSent, bool dontSuppressDuplicate = false); int packetDistributor(SharedNodePointer node, OctreeQueryNode* nodeData, bool viewFrustumChanged); - + QUuid _nodeUuid; From ca3f0ceecbe5d57481000fc23a6ea14beaf0b619 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Jul 2017 10:02:18 -0700 Subject: [PATCH 03/10] remove crufty comments --- assignment-client/src/octree/OctreeSendThread.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 028128e80b..7c6478208e 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -332,13 +332,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* && ((!viewFrustumChanged && nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged())); } - // If our packet already has content in it, then we must use the color choice of the waiting packet. - // If we're starting a fresh packet, then... - // If we're moving, and the client asked for low res, then we force monochrome, otherwise, use - // the clients requested color state. - - // If we have a packet waiting, and our desired want color, doesn't match the current waiting packets color - // then let's just send that waiting packet. + // send any waiting packet if (nodeData->isPacketWaiting()) { int numPackets = handlePacketSend(node, nodeData, trueBytesSent); truePacketsSent += numPackets; From a5cd11cea7d65de0a492aa53fcc4935f03861442 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Jul 2017 10:11:24 -0700 Subject: [PATCH 04/10] remove more crufty comments --- assignment-client/src/octree/OctreeSendThread.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 7c6478208e..e6449f9f72 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -399,10 +399,6 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* if (!nodeData->elementBag.isEmpty()) { quint64 start = usecTimestampNow(); - // TODO: add these to stats page - //quint64 startCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000; - //quint64 startCompressCalls = OctreePacketData::getCompressContentCalls(); - int extraPackingAttempts = 0; bool completedScene = false; @@ -570,12 +566,6 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* int elapsedmsec = (end - start) / USECS_PER_MSEC; OctreeServer::trackLoopTime(elapsedmsec); - // TODO: add these to stats page - //quint64 endCompressCalls = OctreePacketData::getCompressContentCalls(); - //int elapsedCompressCalls = endCompressCalls - startCompressCalls; - //quint64 endCompressTimeMsecs = OctreePacketData::getCompressContentTime() / 1000; - //int elapsedCompressTimeMsecs = endCompressTimeMsecs - startCompressTimeMsecs; - // if after sending packets we've emptied our bag, then we want to remember that we've sent all // the octree elements from the current view frustum if (nodeData->elementBag.isEmpty()) { From 9d111d1f92126001265bb0af305030f4b217a968 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Jul 2017 13:42:35 -0700 Subject: [PATCH 05/10] remove unused OctreeSendThread::_nodeMissingCount --- assignment-client/src/octree/OctreeSendThread.cpp | 1 - assignment-client/src/octree/OctreeSendThread.h | 1 - 2 files changed, 2 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index e6449f9f72..f35fe9ef70 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -81,7 +81,6 @@ bool OctreeSendThread::process() { // don't do any send processing until the initial load of the octree is complete... if (_myServer->isInitialLoadComplete()) { if (auto node = _node.lock()) { - _nodeMissingCount = 0; OctreeQueryNode* nodeData = static_cast(node->getLinkedData()); // Sometimes the node data has not yet been linked, in which case we can't really do anything diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index f1d153b6e3..df1d5f3811 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -66,7 +66,6 @@ private: OctreePacketData _packetData; - int _nodeMissingCount { 0 }; bool _isShuttingDown { false }; }; From 15879b28324dcde7c0b28c89855b01093b42a6e3 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Jul 2017 13:53:08 -0700 Subject: [PATCH 06/10] + OctreeSendThread::traverseTreeAndSendContents() this abstracts a portion of OctreeSendThread::packetDistributor() which will make it easier to split apart the tree traversal from the sending of packets also cleaned up some of the packet stats tracking --- .../src/octree/OctreeSendThread.cpp | 370 +++++++++--------- .../src/octree/OctreeSendThread.h | 6 +- 2 files changed, 192 insertions(+), 184 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index f35fe9ef70..edf7b6da0b 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -128,8 +128,7 @@ AtomicUIntStat OctreeSendThread::_totalSpecialBytes { 0 }; AtomicUIntStat OctreeSendThread::_totalSpecialPackets { 0 }; -int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, int& trueBytesSent, - bool dontSuppressDuplicate) { +int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, bool dontSuppressDuplicate) { OctreeServer::didHandlePacketSend(this); // if we're shutting down, then exit early @@ -140,15 +139,14 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* bool debug = _myServer->wantsDebugSending(); quint64 now = usecTimestampNow(); - bool packetSent = false; // did we send a packet? - int packetsSent = 0; + int numPackets = 0; // Here's where we check to see if this packet is a duplicate of the last packet. If it is, we will silently // obscure the packet and not send it. This allows the callers and upper level logic to not need to know about // this rate control savings. if (!dontSuppressDuplicate && nodeData->shouldSuppressDuplicatePacket()) { nodeData->resetOctreePacket(); // we still need to reset it though! - return packetsSent; // without sending... + return numPackets; // without sending... } // If we've got a stats message ready to send, then see if we can piggyback them together @@ -165,9 +163,12 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* // since a stats message is only included on end of scene, don't consider any of these bytes "wasted", since // there was nothing else to send. int thisWastedBytes = 0; + int numBytes = statsPacket.getDataSize(); _totalWastedBytes += thisWastedBytes; - _totalBytes += statsPacket.getDataSize(); + _totalBytes += numBytes; _totalPackets++; + _trueBytesSent += numBytes; + numPackets++; if (debug) { NLPacket& sentPacket = nodeData->getPacket(); @@ -190,18 +191,22 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* // actually send it OctreeServer::didCallWriteDatagram(this); DependencyManager::get()->sendUnreliablePacket(statsPacket, *node); - packetSent = true; } else { // not enough room in the packet, send two packets + + // first packet OctreeServer::didCallWriteDatagram(this); DependencyManager::get()->sendUnreliablePacket(statsPacket, *node); // since a stats message is only included on end of scene, don't consider any of these bytes "wasted", since // there was nothing else to send. int thisWastedBytes = 0; + int numBytes = statsPacket.getDataSize(); _totalWastedBytes += thisWastedBytes; - _totalBytes += statsPacket.getDataSize(); + _totalBytes += numBytes; _totalPackets++; + _trueBytesSent += numBytes; + numPackets++; if (debug) { NLPacket& sentPacket = nodeData->getPacket(); @@ -220,18 +225,17 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* "] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]"; } - trueBytesSent += statsPacket.getDataSize(); - packetsSent++; - + // second packet OctreeServer::didCallWriteDatagram(this); DependencyManager::get()->sendUnreliablePacket(nodeData->getPacket(), *node); - packetSent = true; - int packetSizeWithHeader = nodeData->getPacket().getDataSize(); - thisWastedBytes = udt::MAX_PACKET_SIZE - packetSizeWithHeader; + numBytes = nodeData->getPacket().getDataSize(); + thisWastedBytes = udt::MAX_PACKET_SIZE - numBytes; _totalWastedBytes += thisWastedBytes; - _totalBytes += nodeData->getPacket().getDataSize(); + _totalBytes += numBytes; _totalPackets++; + _trueBytesSent += numBytes; + numPackets++; if (debug) { NLPacket& sentPacket = nodeData->getPacket(); @@ -257,13 +261,13 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* // just send the octree packet OctreeServer::didCallWriteDatagram(this); DependencyManager::get()->sendUnreliablePacket(nodeData->getPacket(), *node); - packetSent = true; - int packetSizeWithHeader = nodeData->getPacket().getDataSize(); - int thisWastedBytes = udt::MAX_PACKET_SIZE - packetSizeWithHeader; + int numBytes = nodeData->getPacket().getDataSize(); + int thisWastedBytes = udt::MAX_PACKET_SIZE - numBytes; _totalWastedBytes += thisWastedBytes; - _totalBytes += packetSizeWithHeader; + _totalBytes += numBytes; _totalPackets++; + numPackets++; if (debug) { NLPacket& sentPacket = nodeData->getPacket(); @@ -278,22 +282,22 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* qDebug() << "Sending packet at " << now << " [" << _totalPackets <<"]: sequence: " << sequence << " timestamp: " << timestamp << - " size: " << packetSizeWithHeader << " [" << _totalBytes << + " size: " << numBytes << " [" << _totalBytes << "] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]"; } + _trueBytesSent += numBytes; } } // remember to track our stats - if (packetSent) { + if (numPackets > 0) { nodeData->stats.packetSent(nodeData->getPacket().getPayloadSize()); - trueBytesSent += nodeData->getPacket().getPayloadSize(); - packetsSent++; nodeData->octreePacketSent(); nodeData->resetOctreePacket(); } - return packetsSent; + _truePacketsSent += numPackets; + return numPackets; } /// Version of octree element distributor that sends the deepest LOD level at once @@ -312,13 +316,9 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* preDistributionProcessing(); } - // calculate max number of packets that can be sent during this interval - int clientMaxPacketsPerInterval = std::max(1, (nodeData->getMaxQueryPacketsPerSecond() / INTERVALS_PER_SECOND)); - int maxPacketsPerInterval = std::min(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval()); - - int truePacketsSent = 0; - int trueBytesSent = 0; - int packetsSentThisInterval = 0; + _truePacketsSent = 0; + _trueBytesSent = 0; + _packetsSentThisInterval = 0; bool isFullScene = nodeData->shouldForceFullScene(); if (isFullScene) { @@ -333,9 +333,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* // send any waiting packet if (nodeData->isPacketWaiting()) { - int numPackets = handlePacketSend(node, nodeData, trueBytesSent); - truePacketsSent += numPackets; - packetsSentThisInterval += numPackets; + _packetsSentThisInterval += handlePacketSend(node, nodeData); } else { nodeData->resetOctreePacket(); } @@ -366,9 +364,7 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* //unsigned long encodeTime = nodeData->stats.getTotalEncodeTime(); //unsigned long elapsedTime = nodeData->stats.getElapsedTime(); - int numPackets = handlePacketSend(node, nodeData, trueBytesSent, isFullScene); - truePacketsSent += numPackets; - packetsSentThisInterval += numPackets; + _packetsSentThisInterval += handlePacketSend(node, nodeData, isFullScene); // If we're starting a full scene, then definitely we want to empty the elementBag if (isFullScene) { @@ -398,165 +394,42 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* if (!nodeData->elementBag.isEmpty()) { quint64 start = usecTimestampNow(); - int extraPackingAttempts = 0; - bool completedScene = false; - - bool somethingToSend = true; // assume we have something - while (somethingToSend && packetsSentThisInterval < maxPacketsPerInterval && !nodeData->isShuttingDown()) { - float lockWaitElapsedUsec = OctreeServer::SKIP_TIME; - float encodeElapsedUsec = OctreeServer::SKIP_TIME; - float compressAndWriteElapsedUsec = OctreeServer::SKIP_TIME; - float packetSendingElapsedUsec = OctreeServer::SKIP_TIME; - - quint64 startInside = usecTimestampNow(); - - bool lastNodeDidntFit = false; // assume each node fits - if (!nodeData->elementBag.isEmpty()) { - - quint64 lockWaitStart = usecTimestampNow(); - _myServer->getOctree()->withReadLock([&]{ - quint64 lockWaitEnd = usecTimestampNow(); - lockWaitElapsedUsec = (float)(lockWaitEnd - lockWaitStart); - quint64 encodeStart = usecTimestampNow(); - - OctreeElementPointer subTree = nodeData->elementBag.extract(); - if (!subTree) { - return; - } - - float octreeSizeScale = nodeData->getOctreeSizeScale(); - int boundaryLevelAdjustClient = nodeData->getBoundaryLevelAdjust(); - - int boundaryLevelAdjust = boundaryLevelAdjustClient + - (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST); - - EncodeBitstreamParams params(INT_MAX, WANT_EXISTS_BITS, DONT_CHOP, - viewFrustumChanged, boundaryLevelAdjust, octreeSizeScale, - isFullScene, _myServer->getJurisdiction(), nodeData); - nodeData->copyCurrentViewFrustum(params.viewFrustum); - if (viewFrustumChanged) { - nodeData->copyLastKnownViewFrustum(params.lastViewFrustum); - } - - // Our trackSend() function is implemented by the server subclass, and will be called back - // during the encodeTreeBitstream() as new entities/data elements are sent - params.trackSend = [this, node](const QUuid& dataID, quint64 dataEdited) { - _myServer->trackSend(dataID, dataEdited, node->getUUID()); - }; - - // TODO: should this include the lock time or not? This stat is sent down to the client, - // it seems like it may be a good idea to include the lock time as part of the encode time - // are reported to client. Since you can encode without the lock - nodeData->stats.encodeStarted(); - - _myServer->getOctree()->encodeTreeBitstream(subTree, &_packetData, nodeData->elementBag, params); - - quint64 encodeEnd = usecTimestampNow(); - encodeElapsedUsec = (float)(encodeEnd - encodeStart); - - // If after calling encodeTreeBitstream() there are no nodes left to send, then we know we've - // sent the entire scene. We want to know this below so we'll actually write this content into - // the packet and send it - completedScene = nodeData->elementBag.isEmpty(); - - if (params.stopReason == EncodeBitstreamParams::DIDNT_FIT) { - lastNodeDidntFit = true; - extraPackingAttempts++; - } - - nodeData->stats.encodeStopped(); - }); - } else { - somethingToSend = false; // this will cause us to drop out of the loop... - } - - if (completedScene || lastNodeDidntFit) { - // we probably want to flush what has accumulated in nodeData but: - // do we have more data to send? and is there room? - if (_packetData.hasContent()) { - // yes, more data to send - quint64 compressAndWriteStart = usecTimestampNow(); - unsigned int additionalSize = _packetData.getFinalizedSize() + sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); - if (additionalSize > nodeData->getAvailable()) { - // no room --> flush what we've got - int numPackets = handlePacketSend(node, nodeData, trueBytesSent); - truePacketsSent += numPackets; - packetsSentThisInterval += numPackets; - } - - // either there is room, or we've flushed and reset nodeData's data buffer - // so we can transfer whatever is in _packetData to nodeData - nodeData->writeToPacket(_packetData.getFinalizedData(), _packetData.getFinalizedSize()); - compressAndWriteElapsedUsec = (float)(usecTimestampNow()- compressAndWriteStart); - } - - bool sendNow = completedScene || - nodeData->getAvailable() < MINIMUM_ATTEMPT_MORE_PACKING || - extraPackingAttempts > REASONABLE_NUMBER_OF_PACKING_ATTEMPTS; - - int targetSize = MAX_OCTREE_PACKET_DATA_SIZE; - if (sendNow) { - quint64 packetSendingStart = usecTimestampNow(); - int numPackets = handlePacketSend(node, nodeData, trueBytesSent); - truePacketsSent += numPackets; - packetsSentThisInterval += numPackets; - quint64 packetSendingEnd = usecTimestampNow(); - packetSendingElapsedUsec = (float)(packetSendingEnd - packetSendingStart); - - targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); - extraPackingAttempts = 0; - } else { - // We want to see if we have room for more in this wire packet but we've copied the _packetData, - // so we want to start a new section. We will do that by resetting the packet settings with the max - // size of our current available space in the wire packet plus room for our section header and a - // little bit of padding. - targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) - COMPRESS_PADDING; - } - _packetData.changeSettings(true, targetSize); // will do reset - NOTE: Always compressed - } - OctreeServer::trackTreeWaitTime(lockWaitElapsedUsec); - OctreeServer::trackEncodeTime(encodeElapsedUsec); - OctreeServer::trackCompressAndWriteTime(compressAndWriteElapsedUsec); - OctreeServer::trackPacketSendingTime(packetSendingElapsedUsec); - - quint64 endInside = usecTimestampNow(); - quint64 elapsedInsideUsecs = endInside - startInside; - OctreeServer::trackInsideTime((float)elapsedInsideUsecs); - } - - if (somethingToSend && _myServer->wantsVerboseDebug()) { - qCDebug(octree) << "Hit PPS Limit, packetsSentThisInterval =" << packetsSentThisInterval - << " maxPacketsPerInterval = " << maxPacketsPerInterval - << " clientMaxPacketsPerInterval = " << clientMaxPacketsPerInterval; - } + traverseTreeAndSendContents(node, nodeData, viewFrustumChanged, isFullScene); // Here's where we can/should allow the server to send other data... // send the environment packet // TODO: should we turn this into a while loop to better handle sending multiple special packets if (_myServer->hasSpecialPacketsToSend(node) && !nodeData->isShuttingDown()) { int specialPacketsSent = 0; - trueBytesSent += _myServer->sendSpecialPackets(node, nodeData, specialPacketsSent); + int specialBytesSent = _myServer->sendSpecialPackets(node, nodeData, specialPacketsSent); nodeData->resetOctreePacket(); // because nodeData's _sequenceNumber has changed - truePacketsSent += specialPacketsSent; - packetsSentThisInterval += specialPacketsSent; + _truePacketsSent += specialPacketsSent; + _trueBytesSent += specialBytesSent; + _packetsSentThisInterval += specialPacketsSent; _totalPackets += specialPacketsSent; - _totalBytes += trueBytesSent; + _totalBytes += specialBytesSent; _totalSpecialPackets += specialPacketsSent; - _totalSpecialBytes += trueBytesSent; + _totalSpecialBytes += specialBytesSent; } + // calculate max number of packets that can be sent during this interval + int clientMaxPacketsPerInterval = std::max(1, (nodeData->getMaxQueryPacketsPerSecond() / INTERVALS_PER_SECOND)); + int maxPacketsPerInterval = std::min(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval()); + // Re-send packets that were nacked by the client - while (nodeData->hasNextNackedPacket() && packetsSentThisInterval < maxPacketsPerInterval) { + while (nodeData->hasNextNackedPacket() && _packetsSentThisInterval < maxPacketsPerInterval) { const NLPacket* packet = nodeData->getNextNackedPacket(); if (packet) { DependencyManager::get()->sendUnreliablePacket(*packet, *node); - truePacketsSent++; - packetsSentThisInterval++; + int numBytes = packet->getDataSize(); + _truePacketsSent++; + _trueBytesSent += numBytes; + _packetsSentThisInterval++; - _totalBytes += packet->getDataSize(); _totalPackets++; + _totalBytes += numBytes; _totalWastedBytes += udt::MAX_PACKET_SIZE - packet->getDataSize(); } } @@ -574,16 +447,147 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* // If this was a full scene then make sure we really send out a stats packet at this point so that // the clients will know the scene is stable if (isFullScene) { - int thisTrueBytesSent = 0; nodeData->stats.sceneCompleted(); - int numPackets = handlePacketSend(node, nodeData, thisTrueBytesSent, true); - _totalBytes += thisTrueBytesSent; - _totalPackets += numPackets; - truePacketsSent += numPackets; + handlePacketSend(node, nodeData, true); } } } // end if bag wasn't empty, and so we sent stuff... - return truePacketsSent; + return _truePacketsSent; +} + +void OctreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, OctreeQueryNode* nodeData, bool viewFrustumChanged, bool isFullScene) { + // calculate max number of packets that can be sent during this interval + int clientMaxPacketsPerInterval = std::max(1, (nodeData->getMaxQueryPacketsPerSecond() / INTERVALS_PER_SECOND)); + int maxPacketsPerInterval = std::min(clientMaxPacketsPerInterval, _myServer->getPacketsPerClientPerInterval()); + + int extraPackingAttempts = 0; + bool completedScene = false; + + bool somethingToSend = true; // assume we have something + while (somethingToSend && _packetsSentThisInterval < maxPacketsPerInterval && !nodeData->isShuttingDown()) { + float lockWaitElapsedUsec = OctreeServer::SKIP_TIME; + float encodeElapsedUsec = OctreeServer::SKIP_TIME; + float compressAndWriteElapsedUsec = OctreeServer::SKIP_TIME; + float packetSendingElapsedUsec = OctreeServer::SKIP_TIME; + + quint64 startInside = usecTimestampNow(); + + bool lastNodeDidntFit = false; // assume each node fits + if (!nodeData->elementBag.isEmpty()) { + + quint64 lockWaitStart = usecTimestampNow(); + _myServer->getOctree()->withReadLock([&]{ + quint64 lockWaitEnd = usecTimestampNow(); + lockWaitElapsedUsec = (float)(lockWaitEnd - lockWaitStart); + quint64 encodeStart = usecTimestampNow(); + + OctreeElementPointer subTree = nodeData->elementBag.extract(); + if (!subTree) { + return; + } + + float octreeSizeScale = nodeData->getOctreeSizeScale(); + int boundaryLevelAdjustClient = nodeData->getBoundaryLevelAdjust(); + + int boundaryLevelAdjust = boundaryLevelAdjustClient + + (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST); + + EncodeBitstreamParams params(INT_MAX, WANT_EXISTS_BITS, DONT_CHOP, + viewFrustumChanged, boundaryLevelAdjust, octreeSizeScale, + isFullScene, _myServer->getJurisdiction(), nodeData); + nodeData->copyCurrentViewFrustum(params.viewFrustum); + if (viewFrustumChanged) { + nodeData->copyLastKnownViewFrustum(params.lastViewFrustum); + } + + // Our trackSend() function is implemented by the server subclass, and will be called back + // during the encodeTreeBitstream() as new entities/data elements are sent + params.trackSend = [this, node](const QUuid& dataID, quint64 dataEdited) { + _myServer->trackSend(dataID, dataEdited, node->getUUID()); + }; + + // TODO: should this include the lock time or not? This stat is sent down to the client, + // it seems like it may be a good idea to include the lock time as part of the encode time + // are reported to client. Since you can encode without the lock + nodeData->stats.encodeStarted(); + + // NOTE: this is where the tree "contents" are actaully packed + _myServer->getOctree()->encodeTreeBitstream(subTree, &_packetData, nodeData->elementBag, params); + + quint64 encodeEnd = usecTimestampNow(); + encodeElapsedUsec = (float)(encodeEnd - encodeStart); + + // If after calling encodeTreeBitstream() there are no nodes left to send, then we know we've + // sent the entire scene. We want to know this below so we'll actually write this content into + // the packet and send it + completedScene = nodeData->elementBag.isEmpty(); + + if (params.stopReason == EncodeBitstreamParams::DIDNT_FIT) { + lastNodeDidntFit = true; + extraPackingAttempts++; + } + + nodeData->stats.encodeStopped(); + }); + } else { + somethingToSend = false; // this will cause us to drop out of the loop... + } + + if (completedScene || lastNodeDidntFit) { + // we probably want to flush what has accumulated in nodeData but: + // do we have more data to send? and is there room? + if (_packetData.hasContent()) { + // yes, more data to send + quint64 compressAndWriteStart = usecTimestampNow(); + unsigned int additionalSize = _packetData.getFinalizedSize() + sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); + if (additionalSize > nodeData->getAvailable()) { + // no room --> flush what we've got + _packetsSentThisInterval += handlePacketSend(node, nodeData); + } + + // either there is room, or we've flushed and reset nodeData's data buffer + // so we can transfer whatever is in _packetData to nodeData + nodeData->writeToPacket(_packetData.getFinalizedData(), _packetData.getFinalizedSize()); + compressAndWriteElapsedUsec = (float)(usecTimestampNow()- compressAndWriteStart); + } + + bool sendNow = completedScene || + nodeData->getAvailable() < MINIMUM_ATTEMPT_MORE_PACKING || + extraPackingAttempts > REASONABLE_NUMBER_OF_PACKING_ATTEMPTS; + + int targetSize = MAX_OCTREE_PACKET_DATA_SIZE; + if (sendNow) { + quint64 packetSendingStart = usecTimestampNow(); + _packetsSentThisInterval += handlePacketSend(node, nodeData); + quint64 packetSendingEnd = usecTimestampNow(); + packetSendingElapsedUsec = (float)(packetSendingEnd - packetSendingStart); + + targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); + extraPackingAttempts = 0; + } else { + // We want to see if we have room for more in this wire packet but we've copied the _packetData, + // so we want to start a new section. We will do that by resetting the packet settings with the max + // size of our current available space in the wire packet plus room for our section header and a + // little bit of padding. + targetSize = nodeData->getAvailable() - sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) - COMPRESS_PADDING; + } + _packetData.changeSettings(true, targetSize); // will do reset - NOTE: Always compressed + } + OctreeServer::trackTreeWaitTime(lockWaitElapsedUsec); + OctreeServer::trackEncodeTime(encodeElapsedUsec); + OctreeServer::trackCompressAndWriteTime(compressAndWriteElapsedUsec); + OctreeServer::trackPacketSendingTime(packetSendingElapsedUsec); + + quint64 endInside = usecTimestampNow(); + quint64 elapsedInsideUsecs = endInside - startInside; + OctreeServer::trackInsideTime((float)elapsedInsideUsecs); + } + + if (somethingToSend && _myServer->wantsVerboseDebug()) { + qCDebug(octree) << "Hit PPS Limit, packetsSentThisInterval =" << _packetsSentThisInterval + << " maxPacketsPerInterval = " << maxPacketsPerInterval + << " clientMaxPacketsPerInterval = " << clientMaxPacketsPerInterval; + } } diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index df1d5f3811..d158539f57 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -53,12 +53,13 @@ protected: /// Called before a packetDistributor pass to allow for pre-distribution processing virtual void preDistributionProcessing() {}; + virtual void traverseTreeAndSendContents(SharedNodePointer node, OctreeQueryNode* nodeData, bool viewFrustumChanged, bool isFullScene); OctreeServer* _myServer { nullptr }; QWeakPointer _node; private: - int handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, int& trueBytesSent, bool dontSuppressDuplicate = false); + int handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, bool dontSuppressDuplicate = false); int packetDistributor(SharedNodePointer node, OctreeQueryNode* nodeData, bool viewFrustumChanged); @@ -66,6 +67,9 @@ private: OctreePacketData _packetData; + int _truePacketsSent { 0 }; // available for debug stats + int _trueBytesSent { 0 }; // available for debug stats + int _packetsSentThisInterval { 0 }; // used for bandwidth throttle condition bool _isShuttingDown { false }; }; From 3226d33830d6ffaff5d728ed91c0b746f8116f1e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Jul 2017 14:02:16 -0700 Subject: [PATCH 07/10] use cached OctreeSendThread::_nodeUuid --- assignment-client/src/octree/OctreeSendThread.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index edf7b6da0b..2766d5e2e6 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -504,8 +504,8 @@ void OctreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, Octre // Our trackSend() function is implemented by the server subclass, and will be called back // during the encodeTreeBitstream() as new entities/data elements are sent - params.trackSend = [this, node](const QUuid& dataID, quint64 dataEdited) { - _myServer->trackSend(dataID, dataEdited, node->getUUID()); + params.trackSend = [this](const QUuid& dataID, quint64 dataEdited) { + _myServer->trackSend(dataID, dataEdited, _nodeUuid); }; // TODO: should this include the lock time or not? This stat is sent down to the client, From badbe980970311cfdfa5e4b39ea42d43f5918696 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Jul 2017 14:21:49 -0700 Subject: [PATCH 08/10] minor cleanup and constency for packet stats --- .../src/octree/OctreeSendThread.cpp | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 2766d5e2e6..46439b74df 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -160,13 +160,13 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* // copy octree message to back of stats message statsPacket.write(nodeData->getPacket().getData(), nodeData->getPacket().getDataSize()); - // since a stats message is only included on end of scene, don't consider any of these bytes "wasted", since - // there was nothing else to send. - int thisWastedBytes = 0; int numBytes = statsPacket.getDataSize(); - _totalWastedBytes += thisWastedBytes; _totalBytes += numBytes; _totalPackets++; + // since a stats message is only included on end of scene, don't consider any of these bytes "wasted" + // there was nothing else to send. + int thisWastedBytes = 0; + //_totalWastedBytes += 0; _trueBytesSent += numBytes; numPackets++; @@ -198,13 +198,13 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* OctreeServer::didCallWriteDatagram(this); DependencyManager::get()->sendUnreliablePacket(statsPacket, *node); - // since a stats message is only included on end of scene, don't consider any of these bytes "wasted", since - // there was nothing else to send. - int thisWastedBytes = 0; int numBytes = statsPacket.getDataSize(); - _totalWastedBytes += thisWastedBytes; _totalBytes += numBytes; _totalPackets++; + // since a stats message is only included on end of scene, don't consider any of these bytes "wasted" + // there was nothing else to send. + int thisWastedBytes = 0; + //_totalWastedBytes += 0; _trueBytesSent += numBytes; numPackets++; @@ -230,10 +230,11 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* DependencyManager::get()->sendUnreliablePacket(nodeData->getPacket(), *node); numBytes = nodeData->getPacket().getDataSize(); - thisWastedBytes = udt::MAX_PACKET_SIZE - numBytes; - _totalWastedBytes += thisWastedBytes; _totalBytes += numBytes; _totalPackets++; + // since a stats message is only included on end of scene, don't consider any of these bytes "wasted" + // there was nothing else to send. + //_totalWastedBytes += 0; _trueBytesSent += numBytes; numPackets++; @@ -263,11 +264,12 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* DependencyManager::get()->sendUnreliablePacket(nodeData->getPacket(), *node); int numBytes = nodeData->getPacket().getDataSize(); - int thisWastedBytes = udt::MAX_PACKET_SIZE - numBytes; - _totalWastedBytes += thisWastedBytes; _totalBytes += numBytes; _totalPackets++; + int thisWastedBytes = udt::MAX_PACKET_SIZE - numBytes; + _totalWastedBytes += thisWastedBytes; numPackets++; + _trueBytesSent += numBytes; if (debug) { NLPacket& sentPacket = nodeData->getPacket(); @@ -285,7 +287,6 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* " size: " << numBytes << " [" << _totalBytes << "] wasted bytes:" << thisWastedBytes << " [" << _totalWastedBytes << "]"; } - _trueBytesSent += numBytes; } } @@ -331,8 +332,8 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* && ((!viewFrustumChanged && nodeData->getViewFrustumJustStoppedChanging()) || nodeData->hasLodChanged())); } - // send any waiting packet if (nodeData->isPacketWaiting()) { + // send the waiting packet _packetsSentThisInterval += handlePacketSend(node, nodeData); } else { nodeData->resetOctreePacket(); From 1fe7718b9f720b48c13016134eec2f7e3689427b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 11 Jul 2017 15:02:45 -0700 Subject: [PATCH 09/10] restore wasted byte count when unable to fit stats --- assignment-client/src/octree/OctreeSendThread.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 46439b74df..868b377ced 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -232,9 +232,9 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* numBytes = nodeData->getPacket().getDataSize(); _totalBytes += numBytes; _totalPackets++; - // since a stats message is only included on end of scene, don't consider any of these bytes "wasted" - // there was nothing else to send. - //_totalWastedBytes += 0; + // we count wasted bytes here because we were unable to fit the stats packet + thisWastedBytes = udt::MAX_PACKET_SIZE - numBytes; + _totalWastedBytes += thisWastedBytes; _trueBytesSent += numBytes; numPackets++; From 364600c447340998aead63f93caeef45d735fb15 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 12 Jul 2017 11:12:47 -0700 Subject: [PATCH 10/10] fix rendering of simulation ownership debug icons --- interface/src/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 8b616c3029..c7223be208 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -680,7 +680,7 @@ Menu::Menu() { // Developer > Physics >>> MenuWrapper* physicsOptionsMenu = developerMenu->addMenu("Physics"); { - auto drawStatusConfig = qApp->getRenderEngine()->getConfiguration()->getConfig(); + auto drawStatusConfig = qApp->getRenderEngine()->getConfiguration()->getConfig("RenderMainView.DrawStatus"); addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowOwned, 0, false, drawStatusConfig, SLOT(setShowNetwork(bool))); }