void OctreeRenderer::processDatagram(ReceivedMessage& message, SharedNodePointer sourceNode) { bool extraDebugging = false; if (extraDebugging) { qCDebug(octree) << "OctreeRenderer::processDatagram()"; } if (!_tree) { qCDebug(octree) << "OctreeRenderer::processDatagram() called before init, calling init()..."; this->init(); } bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()", showTimingDetails); if (message.getType() == getExpectedPacketType()) { PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PacketType", showTimingDetails); // if we are getting inbound packets, then our tree is also viewing, and we should remember that fact. _tree->setIsViewing(true); OCTREE_PACKET_FLAGS flags; message.readPrimitive(&flags); OCTREE_PACKET_SEQUENCE sequence; message.readPrimitive(&sequence); OCTREE_PACKET_SENT_TIME sentAt; message.readPrimitive(&sentAt); bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT); bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT); OCTREE_PACKET_SENT_TIME arrivedAt = usecTimestampNow(); int clockSkew = sourceNode ? sourceNode->getClockSkewUsec() : 0; int flightTime = arrivedAt - sentAt + clockSkew; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; if (extraDebugging) { qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section" " color:%s compressed:%s sequence: %u flight:%d usec size:%lld data:%lld", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, message.getSize(), message.getBytesLeftToRead()); } _packetsInLastWindow++; int elementsPerPacket = 0; int entitiesPerPacket = 0; quint64 totalWaitingForLock = 0; quint64 totalUncompress = 0; quint64 totalReadBitsteam = 0; const QUuid& sourceUUID = message.getSourceID(); int subsection = 1; bool error = false; while (message.getBytesLeftToRead() > 0 && !error) { if (packetIsCompressed) { if (message.getBytesLeftToRead() > (qint64) sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { message.readPrimitive(§ionLength); } else { sectionLength = 0; error = true; } } else { sectionLength = message.getBytesLeftToRead(); } if (sectionLength) { // ask the VoxelTree to read the bitstream into the tree ReadBitstreamToTreeParams args(WANT_EXISTS_BITS, NULL, sourceUUID, sourceNode, false, message.getVersion()); quint64 startUncompress, startLock = usecTimestampNow(); quint64 startReadBitsteam, endReadBitsteam; // 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->withWriteLock([&] { startUncompress = usecTimestampNow(); OctreePacketData packetData(packetIsCompressed); packetData.loadFinalizedContent(reinterpret_cast<const unsigned char*>(message.getRawMessage() + message.getPosition()), sectionLength); if (extraDebugging) { qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section" " color:%s compressed:%s sequence: %u flight:%d usec size:%lld data:%lld" " subsection:%d sectionLength:%d uncompressed:%d", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, message.getSize(), message.getBytesLeftToRead(), subsection, sectionLength, packetData.getUncompressedSize()); } if (extraDebugging) { qCDebug(octree) << "OctreeRenderer::processDatagram() ******* START _tree->readBitstreamToTree()..."; } startReadBitsteam = usecTimestampNow(); _tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args); endReadBitsteam = usecTimestampNow(); if (extraDebugging) { qCDebug(octree) << "OctreeRenderer::processDatagram() ******* END _tree->readBitstreamToTree()..."; } }); // seek forwards in packet message.seek(message.getPosition() + sectionLength); elementsPerPacket += args.elementsPerPacket; entitiesPerPacket += args.entitiesPerPacket; _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) { _lastWindowAt = now; } quint64 sinceLastWindow = now - _lastWindowAt; 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; } } }
void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const SharedNodePointer& sourceNode) { bool extraDebugging = false; if (extraDebugging) { qCDebug(octree) << "OctreeRenderer::processDatagram()"; } if (!_tree) { qCDebug(octree) << "OctreeRenderer::processDatagram() called before init, calling init()..."; this->init(); } bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()",showTimingDetails); unsigned int packetLength = dataByteArray.size(); PacketType command = packetTypeForPacket(dataByteArray); unsigned int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray); QUuid sourceUUID = uuidFromPacketHeader(dataByteArray); PacketType expectedType = getExpectedPacketType(); // packetVersion is the second byte PacketVersion packetVersion = dataByteArray[1]; if(command == expectedType) { PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PacketType", showTimingDetails); // if we are getting inbound packets, then our tree is also viewing, and we should remember that fact. _tree->setIsViewing(true); const unsigned char* dataAt = reinterpret_cast<const unsigned char*>(dataByteArray.data()) + numBytesPacketHeader; OCTREE_PACKET_FLAGS flags = (*(OCTREE_PACKET_FLAGS*)(dataAt)); dataAt += sizeof(OCTREE_PACKET_FLAGS); OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt); dataAt += sizeof(OCTREE_PACKET_SEQUENCE); OCTREE_PACKET_SENT_TIME sentAt = (*(OCTREE_PACKET_SENT_TIME*)dataAt); dataAt += sizeof(OCTREE_PACKET_SENT_TIME); bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT); bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT); OCTREE_PACKET_SENT_TIME arrivedAt = usecTimestampNow(); int clockSkew = sourceNode ? sourceNode->getClockSkewUsec() : 0; int flightTime = arrivedAt - sentAt + clockSkew; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; unsigned int dataBytes = packetLength - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); if (extraDebugging) { qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section" " color:%s compressed:%s sequence: %u flight:%d usec size:%u data:%u", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packetLength, dataBytes); } int subsection = 1; while (dataBytes > 0) { if (packetIsCompressed) { if (dataBytes > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { sectionLength = (*(OCTREE_PACKET_INTERNAL_SECTION_SIZE*)dataAt); dataAt += sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); dataBytes -= sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); } else { sectionLength = 0; dataBytes = 0; // stop looping something is wrong } } else { sectionLength = dataBytes; } if (sectionLength) { // 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); _tree->lockForWrite(); OctreePacketData packetData(packetIsCompressed); packetData.loadFinalizedContent(dataAt, sectionLength); if (extraDebugging) { qCDebug(octree, "OctreeRenderer::processDatagram() ... Got Packet Section" " color:%s compressed:%s sequence: %u flight:%d usec size:%u data:%u" " subsection:%d sectionLength:%d uncompressed:%d", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packetLength, dataBytes, subsection, sectionLength, packetData.getUncompressedSize()); } if (extraDebugging) { qCDebug(octree) << "OctreeRenderer::processDatagram() ******* START _tree->readBitstreamToTree()..."; } _tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args); if (extraDebugging) { qCDebug(octree) << "OctreeRenderer::processDatagram() ******* END _tree->readBitstreamToTree()..."; } _tree->unlock(); dataBytes -= sectionLength; dataAt += sectionLength; } } subsection++; } }
void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const HifiSockAddr& senderSockAddr, Node* sourceNode) { bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); bool extraDebugging = false; // Menu::getInstance()->isOptionChecked(MenuOption::ExtraDebugging) PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()",showTimingDetails); const unsigned char* packetData = (const unsigned char*)dataByteArray.constData(); int packetLength = dataByteArray.size(); unsigned char command = *packetData; int numBytesPacketHeader = numBytesForPacketHeader(packetData); PACKET_TYPE expectedType = getExpectedPacketType(); if(command == expectedType) { PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram expected PACKET_TYPE",showTimingDetails); const unsigned char* dataAt = packetData + numBytesPacketHeader; OCTREE_PACKET_FLAGS flags = (*(OCTREE_PACKET_FLAGS*)(dataAt)); dataAt += sizeof(OCTREE_PACKET_FLAGS); OCTREE_PACKET_SEQUENCE sequence = (*(OCTREE_PACKET_SEQUENCE*)dataAt); dataAt += sizeof(OCTREE_PACKET_SEQUENCE); OCTREE_PACKET_SENT_TIME sentAt = (*(OCTREE_PACKET_SENT_TIME*)dataAt); dataAt += sizeof(OCTREE_PACKET_SENT_TIME); bool packetIsColored = oneAtBit(flags, PACKET_IS_COLOR_BIT); bool packetIsCompressed = oneAtBit(flags, PACKET_IS_COMPRESSED_BIT); OCTREE_PACKET_SENT_TIME arrivedAt = usecTimestampNow(); int clockSkew = sourceNode ? sourceNode->getClockSkewUsec() : 0; int flightTime = arrivedAt - sentAt + clockSkew; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; int dataBytes = packetLength - OCTREE_PACKET_HEADER_SIZE; if (extraDebugging) { qDebug("OctreeRenderer::processDatagram() ... Got Packet Section" " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d" "\n", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packetLength, dataBytes); } int subsection = 1; while (dataBytes > 0) { if (packetIsCompressed) { if (dataBytes > sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE)) { sectionLength = (*(OCTREE_PACKET_INTERNAL_SECTION_SIZE*)dataAt); dataAt += sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); dataBytes -= sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE); } else { sectionLength = 0; dataBytes = 0; // stop looping something is wrong } } else { sectionLength = dataBytes; } if (sectionLength) { // ask the VoxelTree to read the bitstream into the tree ReadBitstreamToTreeParams args(packetIsColored ? WANT_COLOR : NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceUUID(), sourceNode); _tree->lockForWrite(); OctreePacketData packetData(packetIsCompressed); packetData.loadFinalizedContent(dataAt, sectionLength); if (extraDebugging) { qDebug("OctreeRenderer::processDatagram() ... Got Packet Section" " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d" " subsection:%d sectionLength:%d uncompressed:%d\n", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packetLength, dataBytes, subsection, sectionLength, packetData.getUncompressedSize()); } _tree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args); _tree->unlock(); dataBytes -= sectionLength; dataAt += sectionLength; } } subsection++; } }