Reduce number of full updates sent on region crossing for attachments/huds to 1 from 3
This is one step towards reducing hud glitches on region crossing, since the viewer fails to display prims if it receives child full updates before the root prim full update This commit also introduces a mechanism in LLClientView to stop child attachment updates ever going out before the root one This is a very temporary mechanism and will be commented out when the next step of the fix (to give root prims higher udpate priority) is committed This code is a foreport from the equivalent changes in 0.6.9-post-fixessoprefactor
parent
d91bd7646d
commit
b6076d7b33
|
@ -331,6 +331,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
/// </value>
|
/// </value>
|
||||||
protected HashSet<uint> m_killRecord;
|
protected HashSet<uint> m_killRecord;
|
||||||
|
|
||||||
|
protected HashSet<uint> m_attachmentsSent;
|
||||||
|
|
||||||
private int m_moneyBalance;
|
private int m_moneyBalance;
|
||||||
private int m_animationSequenceNumber = 1;
|
private int m_animationSequenceNumber = 1;
|
||||||
private bool m_SendLogoutPacketWhenClosing = true;
|
private bool m_SendLogoutPacketWhenClosing = true;
|
||||||
|
@ -427,6 +429,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
|
m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
|
||||||
m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
|
m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
|
||||||
m_killRecord = new HashSet<uint>();
|
m_killRecord = new HashSet<uint>();
|
||||||
|
m_attachmentsSent = new HashSet<uint>();
|
||||||
|
|
||||||
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
m_assetService = m_scene.RequestModuleInterface<IAssetService>();
|
||||||
m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>();
|
m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>();
|
||||||
|
@ -3411,6 +3414,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
|
objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence);
|
||||||
|
|
||||||
OutPacket(objupdate, ThrottleOutPacketType.Task);
|
OutPacket(objupdate, ThrottleOutPacketType.Task);
|
||||||
|
|
||||||
|
// We need to record the avatar local id since the root prim of an attachment points to this.
|
||||||
|
m_attachmentsSent.Add(avatar.LocalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
public void SendCoarseLocationUpdate(List<UUID> users, List<Vector3> CoarseLocations)
|
||||||
|
@ -3466,7 +3472,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
double priority = m_prioritizer.GetUpdatePriority(this, entity);
|
double priority = m_prioritizer.GetUpdatePriority(this, entity);
|
||||||
|
|
||||||
lock (m_entityUpdates.SyncRoot)
|
lock (m_entityUpdates.SyncRoot)
|
||||||
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId);
|
m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags), entity.LocalId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ProcessEntityUpdates(int maxUpdates)
|
private void ProcessEntityUpdates(int maxUpdates)
|
||||||
|
@ -3542,9 +3548,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (!canUseImproved && !canUseCompressed)
|
if (!canUseImproved && !canUseCompressed)
|
||||||
{
|
{
|
||||||
if (update.Entity is ScenePresence)
|
if (update.Entity is ScenePresence)
|
||||||
|
{
|
||||||
objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
|
objectUpdateBlocks.Value.Add(CreateAvatarUpdateBlock((ScenePresence)update.Entity));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
|
{
|
||||||
|
if (update.Entity is SceneObjectPart && ((SceneObjectPart)update.Entity).IsAttachment)
|
||||||
|
{
|
||||||
|
SceneObjectPart sop = (SceneObjectPart)update.Entity;
|
||||||
|
string text = sop.Text;
|
||||||
|
if (text.IndexOf("\n") >= 0)
|
||||||
|
text = text.Remove(text.IndexOf("\n"));
|
||||||
|
|
||||||
|
if (m_attachmentsSent.Contains(sop.ParentID))
|
||||||
|
{
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[CLIENT]: Sending full info about attached prim {0} text {1}",
|
||||||
|
// sop.LocalId, text);
|
||||||
|
|
||||||
|
objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock(sop, this.m_agentId));
|
||||||
|
|
||||||
|
m_attachmentsSent.Add(sop.LocalId);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.DebugFormat(
|
||||||
|
"[CLIENT]: Requeueing full update of prim {0} text {1} since we haven't sent its parent {2} yet",
|
||||||
|
sop.LocalId, text, sop.ParentID);
|
||||||
|
|
||||||
|
m_entityUpdates.Enqueue(double.MaxValue, update, sop.LocalId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
objectUpdateBlocks.Value.Add(CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (!canUseImproved)
|
else if (!canUseImproved)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2066,8 +2066,34 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
sceneObject.ScheduleGroupForFullUpdate();
|
sceneObject.ScheduleGroupForFullUpdate();
|
||||||
|
|
||||||
return sceneObject;
|
return sceneObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add an object into the scene that has come from storage
|
||||||
|
/// </summary>
|
||||||
|
///
|
||||||
|
/// <param name="sceneObject"></param>
|
||||||
|
/// <param name="attachToBackup">
|
||||||
|
/// If true, changes to the object will be reflected in its persisted data
|
||||||
|
/// If false, the persisted data will not be changed even if the object in the scene is changed
|
||||||
|
/// </param>
|
||||||
|
/// <param name="alreadyPersisted">
|
||||||
|
/// If true, we won't persist this object until it changes
|
||||||
|
/// If false, we'll persist this object immediately
|
||||||
|
/// </param>
|
||||||
|
/// <param name="sendClientUpdates">
|
||||||
|
/// If true, we send updates to the client to tell it about this object
|
||||||
|
/// If false, we leave it up to the caller to do this
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// true if the object was added, false if an object with the same uuid was already in the scene
|
||||||
|
/// </returns>
|
||||||
|
public bool AddRestoredSceneObject(
|
||||||
|
SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
|
||||||
|
{
|
||||||
|
return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, sendClientUpdates);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add an object into the scene that has come from storage
|
/// Add an object into the scene that has come from storage
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2087,7 +2113,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public bool AddRestoredSceneObject(
|
public bool AddRestoredSceneObject(
|
||||||
SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
|
SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
|
||||||
{
|
{
|
||||||
return m_sceneGraph.AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted);
|
return AddRestoredSceneObject(sceneObject, attachToBackup, alreadyPersisted, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -2527,7 +2553,10 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
|
sceneObject.RootPart.AddFlag(PrimFlags.TemporaryOnRez);
|
||||||
sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
|
sceneObject.RootPart.AddFlag(PrimFlags.Phantom);
|
||||||
|
|
||||||
AddRestoredSceneObject(sceneObject, false, false);
|
|
||||||
|
// Don't sent a full update here because this will cause full updates to be sent twice for
|
||||||
|
// attachments on region crossings, resulting in viewer glitches.
|
||||||
|
AddRestoredSceneObject(sceneObject, false, false, false);
|
||||||
|
|
||||||
// Handle attachment special case
|
// Handle attachment special case
|
||||||
SceneObjectPart RootPrim = sceneObject.RootPart;
|
SceneObjectPart RootPrim = sceneObject.RootPart;
|
||||||
|
@ -2554,12 +2583,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_log.DebugFormat(
|
m_log.DebugFormat(
|
||||||
"[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
|
"[ATTACHMENT]: Attach to avatar {0} at position {1}", sp.UUID, grp.AbsolutePosition);
|
||||||
|
|
||||||
|
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
|
||||||
|
|
||||||
if (AttachmentsModule != null)
|
if (AttachmentsModule != null)
|
||||||
AttachmentsModule.AttachObject(
|
AttachmentsModule.AttachObject(
|
||||||
sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false);
|
sp.ControllingClient, grp.LocalId, (uint)0, grp.GroupRotation, grp.AbsolutePosition, false);
|
||||||
|
|
||||||
RootPrim.RemFlag(PrimFlags.TemporaryOnRez);
|
//grp.SendGroupFullUpdate();
|
||||||
grp.SendGroupFullUpdate();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -222,11 +222,15 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// If true, we won't persist this object until it changes
|
/// If true, we won't persist this object until it changes
|
||||||
/// If false, we'll persist this object immediately
|
/// If false, we'll persist this object immediately
|
||||||
/// </param>
|
/// </param>
|
||||||
|
/// <param name="sendClientUpdates">
|
||||||
|
/// If true, we send updates to the client to tell it about this object
|
||||||
|
/// If false, we leave it up to the caller to do this
|
||||||
|
/// </param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// true if the object was added, false if an object with the same uuid was already in the scene
|
/// true if the object was added, false if an object with the same uuid was already in the scene
|
||||||
/// </returns>
|
/// </returns>
|
||||||
protected internal bool AddRestoredSceneObject(
|
protected internal bool AddRestoredSceneObject(
|
||||||
SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted)
|
SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool sendClientUpdates)
|
||||||
{
|
{
|
||||||
if (!alreadyPersisted)
|
if (!alreadyPersisted)
|
||||||
{
|
{
|
||||||
|
@ -234,9 +238,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
sceneObject.HasGroupChanged = true;
|
sceneObject.HasGroupChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return AddSceneObject(sceneObject, attachToBackup, true);
|
return AddSceneObject(sceneObject, attachToBackup, sendClientUpdates);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a newly created object to the scene. This will both update the scene, and send information about the
|
/// Add a newly created object to the scene. This will both update the scene, and send information about the
|
||||||
/// new object to all clients interested in the scene.
|
/// new object to all clients interested in the scene.
|
||||||
|
|
|
@ -2012,7 +2012,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void ScheduleGroupForFullUpdate()
|
public void ScheduleGroupForFullUpdate()
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, UUID);
|
if (IsAttachment)
|
||||||
|
m_log.DebugFormat("[SOG]: Scheduling full update for {0} {1}", Name, LocalId);
|
||||||
|
|
||||||
checkAtTargets();
|
checkAtTargets();
|
||||||
RootPart.ScheduleFullUpdate();
|
RootPart.ScheduleFullUpdate();
|
||||||
|
|
Loading…
Reference in New Issue