mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 21:15:07 +02:00
Merge pull request #2498 from birarda/master
fix thread contention and reinstate distance based avatar-mixer sending
This commit is contained in:
commit
0d0784ef4b
4 changed files with 38 additions and 8 deletions
|
@ -114,28 +114,38 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
|
|
||||||
NodeList* nodeList = NodeList::getInstance();
|
NodeList* nodeList = NodeList::getInstance();
|
||||||
|
|
||||||
|
AvatarMixerClientData* nodeData = NULL;
|
||||||
|
AvatarMixerClientData* otherNodeData = NULL;
|
||||||
|
|
||||||
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
foreach (const SharedNodePointer& node, nodeList->getNodeHash()) {
|
||||||
if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()) {
|
if (node->getLinkedData() && node->getType() == NodeType::Agent && node->getActiveSocket()
|
||||||
|
&& (nodeData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData()))->getMutex().tryLock()) {
|
||||||
++_sumListeners;
|
++_sumListeners;
|
||||||
|
|
||||||
// reset packet pointers for this node
|
// reset packet pointers for this node
|
||||||
mixedAvatarByteArray.resize(numPacketHeaderBytes);
|
mixedAvatarByteArray.resize(numPacketHeaderBytes);
|
||||||
|
|
||||||
AvatarMixerClientData* myData = reinterpret_cast<AvatarMixerClientData*>(node->getLinkedData());
|
AvatarData& avatar = nodeData->getAvatar();
|
||||||
AvatarData& avatar = myData->getAvatar();
|
|
||||||
glm::vec3 myPosition = avatar.getPosition();
|
glm::vec3 myPosition = avatar.getPosition();
|
||||||
|
|
||||||
// this is an AGENT we have received head data from
|
// this is an AGENT we have received head data from
|
||||||
// send back a packet with other active node data to this node
|
// send back a packet with other active node data to this node
|
||||||
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
|
foreach (const SharedNodePointer& otherNode, nodeList->getNodeHash()) {
|
||||||
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()) {
|
if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()
|
||||||
|
&& (otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData()))->getMutex().tryLock()) {
|
||||||
|
|
||||||
AvatarMixerClientData* otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData());
|
AvatarMixerClientData* otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData());
|
||||||
AvatarData& otherAvatar = otherNodeData->getAvatar();
|
AvatarData& otherAvatar = otherNodeData->getAvatar();
|
||||||
glm::vec3 otherPosition = otherAvatar.getPosition();
|
glm::vec3 otherPosition = otherAvatar.getPosition();
|
||||||
|
|
||||||
// Decide whether to send this avatar's data based on current performance throttling
|
float distanceToAvatar = glm::length(myPosition - otherPosition);
|
||||||
if (_performanceThrottlingRatio == 0 || randFloat() < (1.0f - _performanceThrottlingRatio)) {
|
// The full rate distance is the distance at which EVERY update will be sent for this avatar
|
||||||
|
// at a distance of twice the full rate distance, there will be a 50% chance of sending this avatar's update
|
||||||
|
const float FULL_RATE_DISTANCE = 2.f;
|
||||||
|
|
||||||
|
// Decide whether to send this avatar's data based on it's distance from us
|
||||||
|
if ((_performanceThrottlingRatio == 0 || randFloat() < (1.0f - _performanceThrottlingRatio))
|
||||||
|
&& (distanceToAvatar == 0.f || randFloat() < FULL_RATE_DISTANCE / distanceToAvatar)) {
|
||||||
QByteArray avatarByteArray;
|
QByteArray avatarByteArray;
|
||||||
avatarByteArray.append(otherNode->getUUID().toRfc4122());
|
avatarByteArray.append(otherNode->getUUID().toRfc4122());
|
||||||
avatarByteArray.append(otherAvatar.toByteArray());
|
avatarByteArray.append(otherAvatar.toByteArray());
|
||||||
|
@ -152,7 +162,7 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
|
|
||||||
// if the receiving avatar has just connected make sure we send out the mesh and billboard
|
// if the receiving avatar has just connected make sure we send out the mesh and billboard
|
||||||
// for this avatar (assuming they exist)
|
// for this avatar (assuming they exist)
|
||||||
bool forceSend = !myData->checkAndSetHasReceivedFirstPackets();
|
bool forceSend = !nodeData->checkAndSetHasReceivedFirstPackets();
|
||||||
|
|
||||||
// we will also force a send of billboard or identity packet
|
// we will also force a send of billboard or identity packet
|
||||||
// if either has changed in the last frame
|
// if either has changed in the last frame
|
||||||
|
@ -185,10 +195,14 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
++_sumIdentityPackets;
|
++_sumIdentityPackets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
otherNodeData->getMutex().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeList->writeDatagram(mixedAvatarByteArray, node);
|
nodeList->writeDatagram(mixedAvatarByteArray, node);
|
||||||
|
|
||||||
|
nodeData->getMutex().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,6 +246,7 @@ void AvatarMixer::readPendingDatagrams() {
|
||||||
|
|
||||||
// parse the identity packet and update the change timestamp if appropriate
|
// parse the identity packet and update the change timestamp if appropriate
|
||||||
if (avatar.hasIdentityChangedAfterParsing(receivedPacket)) {
|
if (avatar.hasIdentityChangedAfterParsing(receivedPacket)) {
|
||||||
|
QMutexLocker nodeDataLocker(&nodeData->getMutex());
|
||||||
nodeData->setIdentityChangeTimestamp(QDateTime::currentMSecsSinceEpoch());
|
nodeData->setIdentityChangeTimestamp(QDateTime::currentMSecsSinceEpoch());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -248,6 +263,7 @@ void AvatarMixer::readPendingDatagrams() {
|
||||||
|
|
||||||
// parse the billboard packet and update the change timestamp if appropriate
|
// parse the billboard packet and update the change timestamp if appropriate
|
||||||
if (avatar.hasBillboardChangedAfterParsing(receivedPacket)) {
|
if (avatar.hasBillboardChangedAfterParsing(receivedPacket)) {
|
||||||
|
QMutexLocker nodeDataLocker(&nodeData->getMutex());
|
||||||
nodeData->setBillboardChangeTimestamp(QDateTime::currentMSecsSinceEpoch());
|
nodeData->setBillboardChangeTimestamp(QDateTime::currentMSecsSinceEpoch());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,12 @@
|
||||||
|
|
||||||
#include "NodeData.h"
|
#include "NodeData.h"
|
||||||
|
|
||||||
|
NodeData::NodeData() :
|
||||||
|
_mutex()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
NodeData::~NodeData() {
|
NodeData::~NodeData() {
|
||||||
|
|
||||||
}
|
}
|
|
@ -9,6 +9,7 @@
|
||||||
#ifndef hifi_NodeData_h
|
#ifndef hifi_NodeData_h
|
||||||
#define hifi_NodeData_h
|
#define hifi_NodeData_h
|
||||||
|
|
||||||
|
#include <QtCore/QMutex>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
class Node;
|
class Node;
|
||||||
|
@ -16,9 +17,14 @@ class Node;
|
||||||
class NodeData : public QObject {
|
class NodeData : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
NodeData();
|
||||||
virtual ~NodeData() = 0;
|
virtual ~NodeData() = 0;
|
||||||
virtual int parseData(const QByteArray& packet) = 0;
|
virtual int parseData(const QByteArray& packet) = 0;
|
||||||
|
|
||||||
|
QMutex& getMutex() { return _mutex; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QMutex _mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -317,6 +317,8 @@ int NodeList::updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode
|
||||||
linkedDataCreateCallback(matchingNode.data());
|
linkedDataCreateCallback(matchingNode.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMutexLocker linkedDataLocker(&matchingNode->getLinkedData()->getMutex());
|
||||||
|
|
||||||
return matchingNode->getLinkedData()->parseData(packet);
|
return matchingNode->getLinkedData()->parseData(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue