From 6d211dd4e526130aad3b586724229536b81d21bd Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 8 Mar 2016 14:52:21 -0800 Subject: [PATCH] first cut at fixing the scene not stable bug --- .../src/octree/OctreeSendThread.cpp | 14 +++++++++++--- assignment-client/src/octree/OctreeSendThread.h | 2 +- interface/src/ui/OctreeStatsDialog.cpp | 5 +++++ interface/src/ui/Stats.cpp | 6 ++++++ libraries/entities/src/EntityItem.cpp | 1 + libraries/entities/src/EntityTreeElement.cpp | 17 +++++++++++++++-- libraries/octree/src/Octree.cpp | 4 +--- libraries/octree/src/OctreeElementBag.h | 1 + libraries/octree/src/OctreePacketData.h | 2 ++ libraries/octree/src/OctreeSceneStats.h | 1 + libraries/shared/src/PropertyFlags.h | 4 +++- 11 files changed, 47 insertions(+), 10 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 2ff06c7439..02526280d4 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -124,7 +124,7 @@ AtomicUIntStat OctreeSendThread::_totalSpecialPackets { 0 }; int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, int& trueBytesSent, - int& truePacketsSent) { + int& truePacketsSent, bool dontSuppressDuplicate) { OctreeServer::didHandlePacketSend(this); // if we're shutting down, then exit early @@ -141,7 +141,7 @@ int OctreeSendThread::handlePacketSend(SharedNodePointer node, OctreeQueryNode* // 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 (nodeData->shouldSuppressDuplicatePacket()) { + if (!dontSuppressDuplicate && nodeData->shouldSuppressDuplicatePacket()) { nodeData->resetOctreePacket(); // we still need to reset it though! return packetsSent; // without sending... } @@ -356,7 +356,7 @@ 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); + int packetsJustSent = handlePacketSend(node, nodeData, trueBytesSent, truePacketsSent, isFullScene); packetsSentThisInterval += packetsJustSent; // If we're starting a full scene, then definitely we want to empty the elementBag @@ -582,6 +582,14 @@ int OctreeSendThread::packetDistributor(SharedNodePointer node, OctreeQueryNode* if (nodeData->elementBag.isEmpty()) { nodeData->updateLastKnownViewFrustum(); nodeData->setViewSent(true); + + if (isFullScene) { + int thisTrueBytesSent = 0; + int thisTruePacketsSent = 0; + nodeData->stats.sceneCompleted(); + // FIXME - are we accounting for packets sent correctly here???? + int packetsJustSent = handlePacketSend(node, nodeData, thisTrueBytesSent, thisTruePacketsSent, true); + } } } // end if bag wasn't empty, and so we sent stuff... diff --git a/assignment-client/src/octree/OctreeSendThread.h b/assignment-client/src/octree/OctreeSendThread.h index 38f5de722f..166171c7f9 100644 --- a/assignment-client/src/octree/OctreeSendThread.h +++ b/assignment-client/src/octree/OctreeSendThread.h @@ -50,7 +50,7 @@ protected: virtual bool process(); private: - int handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent); + int handlePacketSend(SharedNodePointer node, OctreeQueryNode* nodeData, int& trueBytesSent, int& truePacketsSent, bool dontSuppressDuplicate = false); int packetDistributor(SharedNodePointer node, OctreeQueryNode* nodeData, bool viewFrustumChanged); diff --git a/interface/src/ui/OctreeStatsDialog.cpp b/interface/src/ui/OctreeStatsDialog.cpp index 42f31f8b1e..b1f7be0524 100644 --- a/interface/src/ui/OctreeStatsDialog.cpp +++ b/interface/src/ui/OctreeStatsDialog.cpp @@ -220,6 +220,11 @@ void OctreeStatsDialog::paintEvent(QPaintEvent* event) { } else { sendingMode << "S"; } + if (stats.isFullScene()) { + sendingMode << "F"; + } else { + sendingMode << "p"; + } } }); sendingMode << " - " << serverCount << " servers"; diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index e566f513ac..daf6d39cc3 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -224,6 +224,12 @@ void Stats::updateStats(bool force) { } else { sendingModeStream << "S"; } + if (stats.isFullScene()) { + sendingModeStream << "F"; + } + else { + sendingModeStream << "p"; + } } // calculate server node totals diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 04ca7559a0..b7b70d12f2 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -142,6 +142,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packetData, EncodeBitstreamParams& params, EntityTreeElementExtraEncodeData* entityTreeElementExtraEncodeData) const { + // ALL this fits... // object ID [16 bytes] // ByteCountCoded(type code) [~1 byte] diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 15ff531b06..f37cb2ce4f 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -64,6 +64,7 @@ void EntityTreeElement::debugExtraEncodeData(EncodeBitstreamParams& params) cons } void EntityTreeElement::initializeExtraEncodeData(EncodeBitstreamParams& params) { + OctreeElementExtraEncodeData* extraEncodeData = params.extraEncodeData; assert(extraEncodeData); // EntityTrees always require extra encode data on their encoding passes // Check to see if this element yet has encode data... if it doesn't create it @@ -347,6 +348,12 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData #endif indexesOfEntitiesToInclude << i; numberOfEntities++; + } else { + // if the extra data included this entity, and we've decided to not include the entity, then + // we can treat it as if it was completed. + if (entityTreeElementExtraEncodeData->entities.contains(entity->getEntityItemID())) { + entityTreeElementExtraEncodeData->entities.remove(entity->getEntityItemID()); + } } } } @@ -398,6 +405,9 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData // After processing, if we are PARTIAL or COMPLETED then we need to re-include our extra data. // Only our parent can remove our extra data in these cases and only after it knows that all of its // children have been encoded. + // + // FIXME -- this comment seems wrong.... + // // If we weren't able to encode ANY data about ourselves, then we go ahead and remove our element data // since that will signal that the entire element needs to be encoded on the next attempt if (appendElementState == OctreeElement::NONE) { @@ -441,9 +451,12 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData appendElementState = OctreeElement::NONE; } else { if (noEntitiesFit) { - appendElementState = OctreeElement::PARTIAL; + //appendElementState = OctreeElement::PARTIAL; + packetData->discardLevel(elementLevel); + appendElementState = OctreeElement::NONE; + } else { + packetData->endLevel(elementLevel); } - packetData->endLevel(elementLevel); } return appendElementState; } diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 8959bd4aa7..d0fab2fc17 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -942,7 +942,6 @@ int Octree::encodeTreeBitstream(OctreeElementPointer element, int childBytesWritten = encodeTreeBitstreamRecursion(element, packetData, bag, params, currentEncodeLevel, parentLocationThisView); - // if childBytesWritten == 1 then something went wrong... that's not possible assert(childBytesWritten != 1); @@ -1529,7 +1528,6 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, // If we made it this far, then we've written all of our child data... if this element is the root // element, then we also allow the root element to write out it's data... if (continueThisLevel && element == _rootElement && rootElementHasData()) { - int bytesBeforeChild = packetData->getUncompressedSize(); // release the bytes we reserved... @@ -1537,6 +1535,7 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, LevelDetails rootDataLevelKey = packetData->startLevel(); OctreeElement::AppendState rootAppendState = element->appendElementData(packetData, params); + bool partOfRootFit = (rootAppendState != OctreeElement::NONE); bool allOfRootFit = (rootAppendState == OctreeElement::COMPLETED); @@ -1571,7 +1570,6 @@ int Octree::encodeTreeBitstreamRecursion(OctreeElementPointer element, qCDebug(octree) << "WARNING UNEXPECTED CASE: Something failed in packing ROOT data"; qCDebug(octree) << "This is not expected!!!! -- continueThisLevel=FALSE...."; } - } // if we were unable to fit this level in our packet, then rewind and add it to the element bag for diff --git a/libraries/octree/src/OctreeElementBag.h b/libraries/octree/src/OctreeElementBag.h index 97ff019513..e458bfcab5 100644 --- a/libraries/octree/src/OctreeElementBag.h +++ b/libraries/octree/src/OctreeElementBag.h @@ -34,6 +34,7 @@ public: /// a single last item will be returned by extract as a null pointer void deleteAll(); + size_t size() const { return _bagElements.size(); } private: Bag _bagElements; diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index 0aa66b06d0..ed6a49941b 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -236,6 +236,8 @@ public: /// the number of bytes in the packet currently reserved int getReservedBytes() { return _bytesReserved; } + int getBytesAvailable() { return _bytesAvailable; } + /// displays contents for debugging void debugContent(); diff --git a/libraries/octree/src/OctreeSceneStats.h b/libraries/octree/src/OctreeSceneStats.h index ced81277e4..a7d485a28f 100644 --- a/libraries/octree/src/OctreeSceneStats.h +++ b/libraries/octree/src/OctreeSceneStats.h @@ -149,6 +149,7 @@ public: const std::vector& getJurisdictionEndNodes() const { return _jurisdictionEndNodes; } bool isMoving() const { return _isMoving; } + bool isFullScene() const { return _isFullScene; } quint64 getTotalElements() const { return _totalElements; } quint64 getTotalInternal() const { return _totalInternal; } quint64 getTotalLeaves() const { return _totalLeaves; } diff --git a/libraries/shared/src/PropertyFlags.h b/libraries/shared/src/PropertyFlags.h index 985a08fa05..833f06aa2b 100644 --- a/libraries/shared/src/PropertyFlags.h +++ b/libraries/shared/src/PropertyFlags.h @@ -258,9 +258,11 @@ template inline void PropertyFlags::debugDumpBits() { qDebug() << "_minFlag=" << _minFlag; qDebug() << "_maxFlag=" << _maxFlag; qDebug() << "_trailingFlipped=" << _trailingFlipped; + QString bits; for(int i = 0; i < _flags.size(); i++) { - qDebug() << "bit[" << i << "]=" << _flags.at(i); + bits += (_flags.at(i) ? "1" : "0"); } + qDebug() << "bits:" << bits; }