* Fixed a regression where all object updates were sent to the client the first time OnQueueEmpty fired

* Removed PrimTerseUpdatesPerPacket, AvatarTerseUpdatesPerPacket, PrimFullUpdatesPerPacket, and replaced with PrimUpdatesPerCallback
* Changed CreateImprovedTerseBlock() to work with SceneObjectPart and ScenePresence
slimupdates
John Hurliman 2010-05-05 13:14:03 -07:00
parent ce106a0c0b
commit d5a5cae58b
3 changed files with 69 additions and 76 deletions

View File

@ -3436,12 +3436,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId); m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId);
} }
private void ProcessEntityUpdates() private void ProcessEntityUpdates(int maxUpdates)
{ {
Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>(); Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
int updatesThisCall = 0;
lock (m_entityUpdates.SyncRoot) lock (m_entityUpdates.SyncRoot)
{ {
EntityUpdate update; EntityUpdate update;
@ -3516,50 +3518,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{ {
bool avatar = (update.Entity is ScenePresence); terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)));
uint localID = update.Entity.LocalId;
uint attachPoint;
Vector4 collisionPlane;
Vector3 position, velocity, acceleration, angularVelocity;
Quaternion rotation;
byte[] textureEntry;
if (update.Entity is ScenePresence)
{
ScenePresence presence = (ScenePresence)update.Entity;
attachPoint = 0;
collisionPlane = presence.CollisionPlane;
position = presence.OffsetPosition;
velocity = presence.Velocity;
acceleration = Vector3.Zero;
angularVelocity = Vector3.Zero;
rotation = presence.Rotation;
if (updateFlags.HasFlag(PrimUpdateFlags.Textures))
textureEntry = presence.Appearance.Texture.GetBytes();
else
textureEntry = null;
}
else
{
SceneObjectPart part = (SceneObjectPart)update.Entity;
attachPoint = part.AttachmentPoint;
collisionPlane = Vector4.Zero;
position = part.RelativePosition;
velocity = part.Velocity;
acceleration = part.Acceleration;
angularVelocity = part.AngularVelocity;
rotation = part.RotationOffset;
textureEntry = part.Shape.TextureEntry;
}
terseUpdateBlocks.Value.Add(CreateImprovedTerseBlock(avatar, localID, attachPoint, collisionPlane, position,
velocity, acceleration, rotation, angularVelocity, textureEntry));
} }
#endregion Block Construction #endregion Block Construction
++updatesThisCall;
if (maxUpdates > 0 && updatesThisCall >= maxUpdates)
break;
} }
} }
@ -3618,6 +3584,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void ReprioritizeUpdates(UpdatePriorityHandler handler) public void ReprioritizeUpdates(UpdatePriorityHandler handler)
{ {
//m_log.Debug("[CLIENT]: Reprioritizing prim updates for " + m_firstName + " " + m_lastName);
PriorityQueue<double, EntityUpdate>.UpdatePriorityHandler update_priority_handler = PriorityQueue<double, EntityUpdate>.UpdatePriorityHandler update_priority_handler =
delegate(ref double priority, uint local_id) delegate(ref double priority, uint local_id)
{ {
@ -3631,8 +3599,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void FlushPrimUpdates() public void FlushPrimUpdates()
{ {
m_log.Debug("[CLIENT]: Flushing prim updates to " + m_firstName + " " + m_lastName);
while (m_entityUpdates.Count > 0) while (m_entityUpdates.Count > 0)
ProcessEntityUpdates(); ProcessEntityUpdates(-1);
} }
#endregion Primitive Packet/Data Sending Methods #endregion Primitive Packet/Data Sending Methods
@ -3665,11 +3635,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
if ((categories & ThrottleOutPacketTypeFlags.State) != 0) if ((categories & ThrottleOutPacketTypeFlags.State) != 0)
{ {
lock (m_entityUpdates.SyncRoot) if (m_entityUpdates.Count > 0)
{ ProcessEntityUpdates(m_udpServer.PrimUpdatesPerCallback);
if (m_entityUpdates.Count > 0)
ProcessEntityUpdates();
}
} }
if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0) if ((categories & ThrottleOutPacketTypeFlags.Texture) != 0)
@ -4327,10 +4294,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region Helper Methods #region Helper Methods
protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(bool avatar, uint localID, uint attachPoint, protected ImprovedTerseObjectUpdatePacket.ObjectDataBlock CreateImprovedTerseBlock(ISceneEntity entity, bool sendTexture)
Vector4 collisionPlane, Vector3 position, Vector3 velocity, Vector3 acceleration, Quaternion rotation,
Vector3 angularVelocity, byte[] textureEntry)
{ {
#region ScenePresence/SOP Handling
bool avatar = (entity is ScenePresence);
uint localID = entity.LocalId;
uint attachPoint;
Vector4 collisionPlane;
Vector3 position, velocity, acceleration, angularVelocity;
Quaternion rotation;
byte[] textureEntry;
if (entity is ScenePresence)
{
ScenePresence presence = (ScenePresence)entity;
attachPoint = 0;
collisionPlane = presence.CollisionPlane;
position = presence.OffsetPosition;
velocity = presence.Velocity;
acceleration = Vector3.Zero;
angularVelocity = Vector3.Zero;
rotation = presence.Rotation;
if (sendTexture)
textureEntry = presence.Appearance.Texture.GetBytes();
else
textureEntry = null;
}
else
{
SceneObjectPart part = (SceneObjectPart)entity;
attachPoint = part.AttachmentPoint;
collisionPlane = Vector4.Zero;
position = part.RelativePosition;
velocity = part.Velocity;
acceleration = part.Acceleration;
angularVelocity = part.AngularVelocity;
rotation = part.RotationOffset;
textureEntry = part.Shape.TextureEntry;
}
#endregion ScenePresence/SOP Handling
int pos = 0; int pos = 0;
byte[] data = new byte[(avatar ? 60 : 44)]; byte[] data = new byte[(avatar ? 60 : 44)];

View File

@ -99,15 +99,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <summary>The measured resolution of Environment.TickCount</summary> /// <summary>The measured resolution of Environment.TickCount</summary>
public readonly float TickCountResolution; public readonly float TickCountResolution;
/// <summary>Number of terse prim updates to put on the queue each time the /// <summary>Number of prim updates to put on the queue each time the
/// OnQueueEmpty event is triggered for updates</summary> /// OnQueueEmpty event is triggered for updates</summary>
public readonly int PrimTerseUpdatesPerPacket; public readonly int PrimUpdatesPerCallback;
/// <summary>Number of terse avatar updates to put on the queue each time the
/// OnQueueEmpty event is triggered for updates</summary>
public readonly int AvatarTerseUpdatesPerPacket;
/// <summary>Number of full prim updates to put on the queue each time the
/// OnQueueEmpty event is triggered for updates</summary>
public readonly int PrimFullUpdatesPerPacket;
/// <summary>Number of texture packets to put on the queue each time the /// <summary>Number of texture packets to put on the queue each time the
/// OnQueueEmpty event is triggered for textures</summary> /// OnQueueEmpty event is triggered for textures</summary>
public readonly int TextureSendLimit; public readonly int TextureSendLimit;
@ -191,9 +185,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
PrimTerseUpdatesPerPacket = config.GetInt("PrimTerseUpdatesPerPacket", 25); PrimUpdatesPerCallback = config.GetInt("PrimUpdatesPerCallback", 100);
AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10);
PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100);
TextureSendLimit = config.GetInt("TextureSendLimit", 20); TextureSendLimit = config.GetInt("TextureSendLimit", 20);
m_defaultRTO = config.GetInt("DefaultRTO", 0); m_defaultRTO = config.GetInt("DefaultRTO", 0);
@ -201,9 +193,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{ {
PrimTerseUpdatesPerPacket = 25; PrimUpdatesPerCallback = 100;
AvatarTerseUpdatesPerPacket = 10;
PrimFullUpdatesPerPacket = 100;
TextureSendLimit = 20; TextureSendLimit = 20;
} }

View File

@ -369,18 +369,13 @@
;asset_limit = 27500 ;asset_limit = 27500
;state_limit = 37000 ;state_limit = 37000
; Configures how ObjectUpdates are aggregated. These numbers ; Configures how scene graph updates are sent to clients.
; do not literally mean how many updates will be put in each ; This controls the balance between responsiveness of interest
; packet that goes over the wire, as packets are ; list updates and total throughput. A higher value will ensure
; automatically split on a 1400 byte boundary. These control ; more full-sized packets and faster sending of data, but more
; the balance between responsiveness of interest list updates ; delay in updating client interest lists
; and total throughput. Higher numbers will ensure more full-
; sized packets and faster sending of data, but more delay in
; updating interest lists
; ;
;PrimTerseUpdatesPerPacket = 25 PrimUpdatesPerCallback = 100
;AvatarTerseUpdatesPerPacket = 10
;PrimFullUpdatesPerPacket = 100
; TextureSendLimit determines how many packets will be put on ; TextureSendLimit determines how many packets will be put on
; the outgoing queue each cycle. Like the settings above, this ; the outgoing queue each cycle. Like the settings above, this