mirror of
https://github.com/overte-org/overte.git
synced 2025-04-16 00:41:16 +02:00
support piggybacking voxel and voxel stats messages into single packet
This commit is contained in:
parent
d9c8a59929
commit
2cc42f6773
4 changed files with 85 additions and 30 deletions
|
@ -3339,12 +3339,6 @@ void* Application::networkReceive(void* args) {
|
|||
if (packetVersionMatch(app->_incomingPacket)) {
|
||||
// only process this packet if we have a match on the packet version
|
||||
switch (app->_incomingPacket[0]) {
|
||||
case PACKET_TYPE_VOXEL_STATS:{
|
||||
VoxelSceneStats stats;
|
||||
int statsMessageLength = stats.unpackFromMessage(app->_incomingPacket, bytesReceived);
|
||||
stats.printDebugDetails();
|
||||
break;
|
||||
}
|
||||
case PACKET_TYPE_TRANSMITTER_DATA_V2:
|
||||
// V2 = IOS transmitter app
|
||||
app->_myTransmitter.processIncomingData(app->_incomingPacket, bytesReceived);
|
||||
|
@ -3357,16 +3351,39 @@ void* Application::networkReceive(void* args) {
|
|||
case PACKET_TYPE_VOXEL_DATA_MONOCHROME:
|
||||
case PACKET_TYPE_Z_COMMAND:
|
||||
case PACKET_TYPE_ERASE_VOXEL:
|
||||
case PACKET_TYPE_VOXEL_STATS:
|
||||
case PACKET_TYPE_ENVIRONMENT_DATA: {
|
||||
|
||||
unsigned char* messageData = app->_incomingPacket;
|
||||
ssize_t messageLength = bytesReceived;
|
||||
|
||||
// note: PACKET_TYPE_VOXEL_STATS can have PACKET_TYPE_VOXEL_DATA or PACKET_TYPE_VOXEL_DATA_MONOCHROME
|
||||
// immediately following them inside the same packet. So, we process the PACKET_TYPE_VOXEL_STATS first
|
||||
// then process any remaining bytes as if it was another packet
|
||||
if (messageData[0] == PACKET_TYPE_VOXEL_STATS) {
|
||||
VoxelSceneStats stats;
|
||||
int statsMessageLength = stats.unpackFromMessage(messageData, messageLength);
|
||||
stats.printDebugDetails();
|
||||
if (messageLength > statsMessageLength) {
|
||||
messageData += statsMessageLength;
|
||||
messageLength -= statsMessageLength;
|
||||
if (!packetVersionMatch(messageData)) {
|
||||
break; // bail since piggyback data doesn't match our versioning
|
||||
}
|
||||
} else {
|
||||
break; // bail since no piggyback data
|
||||
}
|
||||
} // fall through to piggyback message
|
||||
|
||||
if (app->_renderVoxels->isChecked()) {
|
||||
Node* voxelServer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_VOXEL_SERVER);
|
||||
if (voxelServer) {
|
||||
voxelServer->lock();
|
||||
|
||||
if (app->_incomingPacket[0] == PACKET_TYPE_ENVIRONMENT_DATA) {
|
||||
app->_environment.parseData(&senderAddress, app->_incomingPacket, bytesReceived);
|
||||
if (messageData[0] == PACKET_TYPE_ENVIRONMENT_DATA) {
|
||||
app->_environment.parseData(&senderAddress, messageData, messageLength);
|
||||
} else {
|
||||
app->_voxels.parseData(app->_incomingPacket, bytesReceived);
|
||||
app->_voxels.parseData(messageData, messageLength);
|
||||
}
|
||||
|
||||
voxelServer->unlock();
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
VoxelSceneStats::VoxelSceneStats() {
|
||||
reset();
|
||||
_readyToSend = false;
|
||||
}
|
||||
|
||||
VoxelSceneStats::~VoxelSceneStats() {
|
||||
|
@ -29,6 +30,9 @@ void VoxelSceneStats::sceneStarted(bool fullScene, bool moving) {
|
|||
void VoxelSceneStats::sceneCompleted() {
|
||||
_end = usecTimestampNow();
|
||||
_elapsed = _end - _start;
|
||||
|
||||
_statsMessageLength = packIntoMessage(_statsMessage, sizeof(_statsMessage));
|
||||
_readyToSend = true;
|
||||
}
|
||||
|
||||
void VoxelSceneStats::encodeStarted() {
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define __hifi__VoxelSceneStats__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <NodeList.h>
|
||||
|
||||
class VoxelNode;
|
||||
|
||||
|
@ -20,6 +21,7 @@ public:
|
|||
void reset();
|
||||
void sceneStarted(bool fullScene, bool moving);
|
||||
void sceneCompleted();
|
||||
|
||||
void printDebugDetails();
|
||||
void packetSent(int bytes);
|
||||
|
||||
|
@ -41,8 +43,18 @@ public:
|
|||
|
||||
int packIntoMessage(unsigned char* destinationBuffer, int availableBytes);
|
||||
int unpackFromMessage(unsigned char* sourceBuffer, int availableBytes);
|
||||
|
||||
bool readyToSend() const { return _readyToSend; }
|
||||
void markAsSent() { _readyToSend = false; }
|
||||
unsigned char* getStatsMessage() { return &_statsMessage[0]; }
|
||||
int getStatsMessageLength() const { return _statsMessageLength; }
|
||||
|
||||
|
||||
private:
|
||||
bool _readyToSend;
|
||||
unsigned char _statsMessage[MAX_PACKET_SIZE];
|
||||
int _statsMessageLength;
|
||||
|
||||
// scene timing data in usecs
|
||||
uint64_t _start;
|
||||
uint64_t _end;
|
||||
|
|
|
@ -112,6 +112,44 @@ void eraseVoxelTreeAndCleanupNodeVisitData() {
|
|||
|
||||
pthread_mutex_t treeLock;
|
||||
|
||||
void handlePacketSend(NodeList* nodeList,
|
||||
NodeList::iterator& node,
|
||||
VoxelNodeData* nodeData,
|
||||
int& trueBytesSent, int& truePacketsSent) {
|
||||
// If we've got a stats message ready to send, then see if we can piggyback them together
|
||||
if (nodeData->stats.readyToSend()) {
|
||||
// Send the stats message to the client
|
||||
unsigned char* statsMessage = nodeData->stats.getStatsMessage();
|
||||
int statsMessageLength = nodeData->stats.getStatsMessageLength();
|
||||
|
||||
// If the size of the stats message and the voxel message will fit in a packet, then piggyback them
|
||||
if (nodeData->getPacketLength() + statsMessageLength < MAX_PACKET_SIZE) {
|
||||
|
||||
// copy voxel message to back of stats message
|
||||
memcpy(statsMessage + statsMessageLength, nodeData->getPacket(), nodeData->getPacketLength());
|
||||
statsMessageLength += nodeData->getPacketLength();
|
||||
|
||||
// actually send it
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(), statsMessage, statsMessageLength);
|
||||
} else {
|
||||
// not enough room in the packet, send two packets
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(), statsMessage, statsMessageLength);
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(),
|
||||
nodeData->getPacket(), nodeData->getPacketLength());
|
||||
}
|
||||
} else {
|
||||
// just send the voxel packet
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(),
|
||||
nodeData->getPacket(), nodeData->getPacketLength());
|
||||
}
|
||||
// remember to track our stats
|
||||
nodeData->stats.packetSent(nodeData->getPacketLength());
|
||||
trueBytesSent += nodeData->getPacketLength();
|
||||
truePacketsSent++;
|
||||
nodeData->resetVoxelPacket();
|
||||
}
|
||||
|
||||
|
||||
// Version of voxel distributor that sends the deepest LOD level at once
|
||||
void deepestLevelVoxelDistributor(NodeList* nodeList,
|
||||
NodeList::iterator& node,
|
||||
|
@ -142,12 +180,9 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
|
|||
printf("wantColor=%s --- SENDING PARTIAL PACKET! nodeData->getCurrentPacketIsColor()=%s\n",
|
||||
debug::valueOf(wantColor), debug::valueOf(nodeData->getCurrentPacketIsColor()));
|
||||
}
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(),
|
||||
nodeData->getPacket(), nodeData->getPacketLength());
|
||||
nodeData->stats.packetSent(nodeData->getPacketLength());
|
||||
trueBytesSent += nodeData->getPacketLength();
|
||||
truePacketsSent++;
|
||||
nodeData->resetVoxelPacket();
|
||||
|
||||
handlePacketSend(nodeList, node, nodeData, trueBytesSent, truePacketsSent);
|
||||
|
||||
} else {
|
||||
if (::debugVoxelSending) {
|
||||
printf("wantColor=%s --- FIXING HEADER! nodeData->getCurrentPacketIsColor()=%s\n",
|
||||
|
@ -209,11 +244,6 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
|
|||
if (::displayVoxelStats) {
|
||||
nodeData->stats.printDebugDetails();
|
||||
}
|
||||
|
||||
// Send the stats message to the client
|
||||
unsigned char statsMessage[MAX_PACKET_SIZE];
|
||||
int statsMessageLength = nodeData->stats.packIntoMessage(statsMessage, sizeof(statsMessage));
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(), statsMessage, statsMessageLength);
|
||||
|
||||
// This is the start of "resending" the scene.
|
||||
nodeData->nodeBag.insert(serverTree.rootNode);
|
||||
|
@ -271,22 +301,14 @@ void deepestLevelVoxelDistributor(NodeList* nodeList,
|
|||
if (nodeData->getAvailable() >= bytesWritten) {
|
||||
nodeData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
|
||||
} else {
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(),
|
||||
nodeData->getPacket(), nodeData->getPacketLength());
|
||||
nodeData->stats.packetSent(nodeData->getPacketLength());
|
||||
trueBytesSent += nodeData->getPacketLength();
|
||||
truePacketsSent++;
|
||||
handlePacketSend(nodeList, node, nodeData, trueBytesSent, truePacketsSent);
|
||||
packetsSentThisInterval++;
|
||||
nodeData->resetVoxelPacket();
|
||||
nodeData->writeToPacket(&tempOutputBuffer[0], bytesWritten);
|
||||
}
|
||||
} else {
|
||||
if (nodeData->isPacketWaiting()) {
|
||||
nodeList->getNodeSocket()->send(node->getActiveSocket(),
|
||||
nodeData->getPacket(), nodeData->getPacketLength());
|
||||
nodeData->stats.packetSent(nodeData->getPacketLength());
|
||||
trueBytesSent += nodeData->getPacketLength();
|
||||
truePacketsSent++;
|
||||
handlePacketSend(nodeList, node, nodeData, trueBytesSent, truePacketsSent);
|
||||
nodeData->resetVoxelPacket();
|
||||
}
|
||||
packetsSentThisInterval = PACKETS_PER_CLIENT_PER_INTERVAL; // done for now, no nodes left
|
||||
|
|
Loading…
Reference in a new issue