initial changes to OctreeQueryNode for new APIs

This commit is contained in:
Stephen Birarda 2015-07-07 12:08:01 -07:00
parent 474b82e3bf
commit 74924bc5f1
4 changed files with 50 additions and 81 deletions

View file

@ -22,11 +22,9 @@
OctreeQueryNode::OctreeQueryNode() : OctreeQueryNode::OctreeQueryNode() :
_viewSent(false), _viewSent(false),
_octreePacket(new unsigned char[MAX_PACKET_SIZE]), _octreePacket(),
_octreePacketAt(_octreePacket),
_octreePacketAvailableBytes(MAX_PACKET_SIZE),
_octreePacketWaiting(false), _octreePacketWaiting(false),
_lastOctreePacket(new unsigned char[MAX_PACKET_SIZE]), _lastOctreePayload(new char[MAX_PACKET_SIZE]),
_lastOctreePacketLength(0), _lastOctreePacketLength(0),
_duplicatePacketCount(0), _duplicatePacketCount(0),
_firstSuppressedPacket(usecTimestampNow()), _firstSuppressedPacket(usecTimestampNow()),
@ -55,9 +53,8 @@ OctreeQueryNode::~OctreeQueryNode() {
if (_octreeSendThread) { if (_octreeSendThread) {
forceNodeShutdown(); forceNodeShutdown();
} }
delete[] _octreePacket; delete[] _lastOctreePayload;
delete[] _lastOctreePacket;
} }
void OctreeQueryNode::nodeKilled() { void OctreeQueryNode::nodeKilled() {
@ -74,7 +71,7 @@ void OctreeQueryNode::forceNodeShutdown() {
_isShuttingDown = true; _isShuttingDown = true;
elementBag.unhookNotifications(); // if our node is shutting down, then we no longer need octree element notifications elementBag.unhookNotifications(); // if our node is shutting down, then we no longer need octree element notifications
if (_octreeSendThread) { if (_octreeSendThread) {
// we really need to force our thread to shutdown, this is synchronous, we will block while the thread actually // we really need to force our thread to shutdown, this is synchronous, we will block while the thread actually
// shuts down because we really need it to shutdown, and it's ok if we wait for it to complete // shuts down because we really need it to shutdown, and it's ok if we wait for it to complete
OctreeSendThread* sendThread = _octreeSendThread; OctreeSendThread* sendThread = _octreeSendThread;
_octreeSendThread = NULL; _octreeSendThread = NULL;
@ -96,8 +93,8 @@ void OctreeQueryNode::sendThreadFinished() {
} }
void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) { void OctreeQueryNode::initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node) {
_octreeSendThread = new OctreeSendThread(myServer, node); _octreeSendThread = new OctreeSendThread(myServer, node);
// we want to be notified when the thread finishes // we want to be notified when the thread finishes
connect(_octreeSendThread, &GenericThread::finished, this, &OctreeQueryNode::sendThreadFinished); connect(_octreeSendThread, &GenericThread::finished, this, &OctreeQueryNode::sendThreadFinished);
_octreeSendThread->initialize(true); _octreeSendThread->initialize(true);
@ -110,12 +107,11 @@ bool OctreeQueryNode::packetIsDuplicate() const {
} }
// since our packets now include header information, like sequence number, and createTime, we can't just do a memcmp // since our packets now include header information, like sequence number, and createTime, we can't just do a memcmp
// of the entire packet, we need to compare only the packet content... // of the entire packet, we need to compare only the packet content...
int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(_myPacketType);
if (_lastOctreePacketLength == getPacketLength()) { if (_lastOctreePacketLength == getPacketLength()) {
if (memcmp(_lastOctreePacket + (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE), if (memcmp(_lastOctreePayload + OCTREE_PACKET_EXTRA_HEADERS_SIZE,
_octreePacket + (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE), _octreePacket->getPayload() + OCTREE_PACKET_EXTRA_HEADERS_SIZE,
getPacketLength() - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE)) == 0) { _octreePacket->getSizeUsed() - OCTREE_PACKET_EXTRA_HEADERS_SIZE) == 0) {
return true; return true;
} }
} }
@ -163,6 +159,9 @@ bool OctreeQueryNode::shouldSuppressDuplicatePacket() {
void OctreeQueryNode::init() { void OctreeQueryNode::init() {
_myPacketType = getMyPacketType(); _myPacketType = getMyPacketType();
_octreePacket = NLPacket::create(getMyPacketType());
resetOctreePacket(); // don't bump sequence resetOctreePacket(); // don't bump sequence
} }
@ -177,8 +176,8 @@ void OctreeQueryNode::resetOctreePacket() {
// changed since we last reset it. Since we know that no two packets can ever be identical without being the same // changed since we last reset it. Since we know that no two packets can ever be identical without being the same
// scene information, (e.g. the root node packet of a static scene), we can use this as a strategy for reducing // scene information, (e.g. the root node packet of a static scene), we can use this as a strategy for reducing
// packet send rate. // packet send rate.
_lastOctreePacketLength = getPacketLength(); _lastOctreePacketLength = _octreePacket->getSizeUsed();
memcpy(_lastOctreePacket, _octreePacket, _lastOctreePacketLength); memcpy(_lastOctreePayload, _octreePacket->getPayload(), _lastOctreePacketLength);
// If we're moving, and the client asked for low res, then we force monochrome, otherwise, use // If we're moving, and the client asked for low res, then we force monochrome, otherwise, use
// the clients requested color state. // the clients requested color state.
@ -192,31 +191,17 @@ void OctreeQueryNode::resetOctreePacket() {
setAtBit(flags, PACKET_IS_COMPRESSED_BIT); setAtBit(flags, PACKET_IS_COMPRESSED_BIT);
} }
_octreePacketAvailableBytes = MAX_PACKET_SIZE; _octreePacket->reset();
int numBytesPacketHeader = DependencyManager::get<NodeList>()->populatePacketHeader(reinterpret_cast<char*>(_octreePacket),
_myPacketType);
_octreePacketAt = _octreePacket + numBytesPacketHeader;
_octreePacketAvailableBytes -= numBytesPacketHeader;
// pack in flags // pack in flags
OCTREE_PACKET_FLAGS* flagsAt = (OCTREE_PACKET_FLAGS*)_octreePacketAt; _octreePacket->write(&flags, sizeof(flags));
*flagsAt = flags;
_octreePacketAt += sizeof(OCTREE_PACKET_FLAGS);
_octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_FLAGS);
// pack in sequence number // pack in sequence number
OCTREE_PACKET_SEQUENCE* sequenceAt = (OCTREE_PACKET_SEQUENCE*)_octreePacketAt; _octreePacket->write(&_sequenceNumber, sizeof(_sequenceNumber));
*sequenceAt = _sequenceNumber;
_octreePacketAt += sizeof(OCTREE_PACKET_SEQUENCE);
_octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_SEQUENCE);
// pack in timestamp // pack in timestamp
OCTREE_PACKET_SENT_TIME now = usecTimestampNow(); OCTREE_PACKET_SENT_TIME now = usecTimestampNow();
OCTREE_PACKET_SENT_TIME* timeAt = (OCTREE_PACKET_SENT_TIME*)_octreePacketAt; _octreePacket->write(&now, sizeof(now));
*timeAt = now;
_octreePacketAt += sizeof(OCTREE_PACKET_SENT_TIME);
_octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_SENT_TIME);
_octreePacketWaiting = false; _octreePacketWaiting = false;
} }
@ -230,14 +215,11 @@ void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int by
// compressed packets include lead bytes which contain compressed size, this allows packing of // compressed packets include lead bytes which contain compressed size, this allows packing of
// multiple compressed portions together // multiple compressed portions together
if (_currentPacketIsCompressed) { if (_currentPacketIsCompressed) {
*(OCTREE_PACKET_INTERNAL_SECTION_SIZE*)_octreePacketAt = bytes; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionSize = bytes;
_octreePacketAt += sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); _octreePacket->write(&sectionSize, sizeof(sectionSize));
_octreePacketAvailableBytes -= sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE);
} }
if (bytes <= _octreePacketAvailableBytes) { if (bytes <= _octreePacket->bytesAvailable()) {
memcpy(_octreePacketAt, buffer, bytes); _octreePacket->write(buffer, bytes);
_octreePacketAvailableBytes -= bytes;
_octreePacketAt += bytes;
_octreePacketWaiting = true; _octreePacketWaiting = true;
} }
} }
@ -258,8 +240,8 @@ bool OctreeQueryNode::updateCurrentViewFrustum() {
float originalFOV = getCameraFov(); float originalFOV = getCameraFov();
float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND; float wideFOV = originalFOV + VIEW_FRUSTUM_FOV_OVERSEND;
if (0.0f != getCameraAspectRatio() && if (0.0f != getCameraAspectRatio() &&
0.0f != getCameraNearClip() && 0.0f != getCameraNearClip() &&
0.0f != getCameraFarClip()) { 0.0f != getCameraFarClip()) {
newestViewFrustum.setProjection(glm::perspective( newestViewFrustum.setProjection(glm::perspective(
glm::radians(wideFOV), // hack glm::radians(wideFOV), // hack
@ -351,7 +333,7 @@ void OctreeQueryNode::dumpOutOfView() {
if (_isShuttingDown) { if (_isShuttingDown) {
return; return;
} }
int stillInView = 0; int stillInView = 0;
int outOfView = 0; int outOfView = 0;
OctreeElementBag tempBag; OctreeElementBag tempBag;
@ -374,15 +356,7 @@ void OctreeQueryNode::dumpOutOfView() {
} }
} }
void OctreeQueryNode::octreePacketSent() { void OctreeQueryNode::packetSent(const NLPacket& packet) {
packetSent(_octreePacket, getPacketLength());
}
void OctreeQueryNode::packetSent(unsigned char* packet, int packetLength) {
packetSent(QByteArray((char*)packet, packetLength));
}
void OctreeQueryNode::packetSent(const QByteArray& packet) {
_sentPacketHistory.packetSent(_sequenceNumber, packet); _sentPacketHistory.packetSent(_sequenceNumber, packet);
_sequenceNumber++; _sequenceNumber++;
} }
@ -391,12 +365,13 @@ bool OctreeQueryNode::hasNextNackedPacket() const {
return !_nackedSequenceNumbers.isEmpty(); return !_nackedSequenceNumbers.isEmpty();
} }
const QByteArray* OctreeQueryNode::getNextNackedPacket() { NLPacket&& OctreeQueryNode::getNextNackedPacket() {
if (!_nackedSequenceNumbers.isEmpty()) { if (!_nackedSequenceNumbers.isEmpty()) {
// could return null if packet is not in the history // could return null if packet is not in the history
return _sentPacketHistory.getPacket(_nackedSequenceNumbers.dequeue()); return std::move(_sentPacketHistory.getPacket(_nackedSequenceNumbers.dequeue()));
} }
return NULL;
return nullptr;
} }
void OctreeQueryNode::parseNackPacket(const QByteArray& packet) { void OctreeQueryNode::parseNackPacket(const QByteArray& packet) {

View file

@ -41,8 +41,7 @@ public:
void writeToPacket(const unsigned char* buffer, unsigned int bytes); // writes to end of packet void writeToPacket(const unsigned char* buffer, unsigned int bytes); // writes to end of packet
const unsigned char* getPacket() const { return _octreePacket; } NLPacket& getPacket() const { return _octreePacket; }
unsigned int getPacketLength() const { return (MAX_PACKET_SIZE - _octreePacketAvailableBytes); }
bool isPacketWaiting() const { return _octreePacketWaiting; } bool isPacketWaiting() const { return _octreePacketWaiting; }
bool packetIsDuplicate() const; bool packetIsDuplicate() const;
@ -62,7 +61,7 @@ public:
ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; } ViewFrustum& getCurrentViewFrustum() { return _currentViewFrustum; }
ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; } ViewFrustum& getLastKnownViewFrustum() { return _lastKnownViewFrustum; }
// These are not classic setters because they are calculating and maintaining state // These are not classic setters because they are calculating and maintaining state
// which is set asynchronously through the network receive // which is set asynchronously through the network receive
bool updateCurrentViewFrustum(); bool updateCurrentViewFrustum();
@ -86,49 +85,46 @@ public:
} }
bool hasLodChanged() const { return _lodChanged; } bool hasLodChanged() const { return _lodChanged; }
OctreeSceneStats stats; OctreeSceneStats stats;
void initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node); void initializeOctreeSendThread(OctreeServer* myServer, const SharedNodePointer& node);
bool isOctreeSendThreadInitalized() { return _octreeSendThread; } bool isOctreeSendThreadInitalized() { return _octreeSendThread; }
void dumpOutOfView(); void dumpOutOfView();
quint64 getLastRootTimestamp() const { return _lastRootTimestamp; } quint64 getLastRootTimestamp() const { return _lastRootTimestamp; }
void setLastRootTimestamp(quint64 timestamp) { _lastRootTimestamp = timestamp; } void setLastRootTimestamp(quint64 timestamp) { _lastRootTimestamp = timestamp; }
unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; } unsigned int getlastOctreePacketLength() const { return _lastOctreePacketLength; }
int getDuplicatePacketCount() const { return _duplicatePacketCount; } int getDuplicatePacketCount() const { return _duplicatePacketCount; }
void sceneStart(quint64 sceneSendStartTime) { _sceneSendStartTime = sceneSendStartTime; } void sceneStart(quint64 sceneSendStartTime) { _sceneSendStartTime = sceneSendStartTime; }
void nodeKilled(); void nodeKilled();
void forceNodeShutdown(); void forceNodeShutdown();
bool isShuttingDown() const { return _isShuttingDown; } bool isShuttingDown() const { return _isShuttingDown; }
void octreePacketSent(); void octreePacketSent() { packetSent(_octreePacket); }
void packetSent(unsigned char* packet, int packetLength); void packetSent(const NLPacket& packet);
void packetSent(const QByteArray& packet);
OCTREE_PACKET_SEQUENCE getSequenceNumber() const { return _sequenceNumber; } OCTREE_PACKET_SEQUENCE getSequenceNumber() const { return _sequenceNumber; }
void parseNackPacket(const QByteArray& packet); void parseNackPacket(const QByteArray& packet);
bool hasNextNackedPacket() const; bool hasNextNackedPacket() const;
const QByteArray* getNextNackedPacket(); NLPacket&& getNextNackedPacket();
private slots: private slots:
void sendThreadFinished(); void sendThreadFinished();
private: private:
OctreeQueryNode(const OctreeQueryNode &); OctreeQueryNode(const OctreeQueryNode &);
OctreeQueryNode& operator= (const OctreeQueryNode&); OctreeQueryNode& operator= (const OctreeQueryNode&);
bool _viewSent; bool _viewSent;
unsigned char* _octreePacket; std::unique_ptr<NLPacket> _octreePacket;
unsigned char* _octreePacketAt;
unsigned int _octreePacketAvailableBytes;
bool _octreePacketWaiting; bool _octreePacketWaiting;
unsigned char* _lastOctreePacket; char* _lastOctreePayload = nullptr;
unsigned int _lastOctreePacketLength; unsigned int _lastOctreePacketLength;
int _duplicatePacketCount; int _duplicatePacketCount;
quint64 _firstSuppressedPacket; quint64 _firstSuppressedPacket;
@ -154,7 +150,7 @@ private:
OCTREE_PACKET_SEQUENCE _sequenceNumber; OCTREE_PACKET_SEQUENCE _sequenceNumber;
quint64 _lastRootTimestamp; quint64 _lastRootTimestamp;
PacketType::Value _myPacketType; PacketType::Value _myPacketType;
bool _isShuttingDown; bool _isShuttingDown;

View file

@ -13,13 +13,11 @@
#include "SentPacketHistory.h" #include "SentPacketHistory.h"
#include <qdebug.h> #include <qdebug.h>
SentPacketHistory::SentPacketHistory(int size) SentPacketHistory::SentPacketHistory(int size)
: _sentPackets(size), : _sentPackets(size),
_newestSequenceNumber(std::numeric_limits<uint16_t>::max()) _newestSequenceNumber(std::numeric_limits<uint16_t>::max())
{ {
} }
void SentPacketHistory::packetSent(uint16_t sequenceNumber, const QByteArray& packet) { void SentPacketHistory::packetSent(uint16_t sequenceNumber, const QByteArray& packet) {

View file

@ -22,11 +22,11 @@ class SentPacketHistory {
public: public:
SentPacketHistory(int size = MAX_REASONABLE_SEQUENCE_GAP); SentPacketHistory(int size = MAX_REASONABLE_SEQUENCE_GAP);
void packetSent(uint16_t sequenceNumber, const QByteArray& packet); void packetSent(uint16_t sequenceNumber, const NLPacket& packet);
const QByteArray* getPacket(uint16_t sequenceNumber) const; const QByteArray* getPacket(uint16_t sequenceNumber) const;
private: private:
RingBufferHistory<QByteArray> _sentPackets; // circular buffer RingBufferHistory<NLPacket> _sentPackets; // circular buffer
uint16_t _newestSequenceNumber; uint16_t _newestSequenceNumber;
}; };