* Plumbing and basic setting of the GetMesh Cap Throttler.
* Last step is to flip the throttle distribution.avinationmerge
parent
e9153e1d1a
commit
5e0294815f
|
@ -152,6 +152,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
responsedata["keepalive"] = false;
|
responsedata["keepalive"] = false;
|
||||||
responsedata["str_response_string"] = "This range doesnt exist.";
|
responsedata["str_response_string"] = "This range doesnt exist.";
|
||||||
responsedata["reusecontext"] = false;
|
responsedata["reusecontext"] = false;
|
||||||
|
responsedata["int_lod"] = 3;
|
||||||
return responsedata;
|
return responsedata;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -162,6 +163,18 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
|
|
||||||
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
//m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID);
|
||||||
|
|
||||||
|
if (start > 20000)
|
||||||
|
{
|
||||||
|
responsedata["int_lod"] = 3;
|
||||||
|
}
|
||||||
|
else if (start < 4097)
|
||||||
|
{
|
||||||
|
responsedata["int_lod"] = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
responsedata["int_lod"] = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (start == 0 && len == mesh.Data.Length) // well redudante maybe
|
if (start == 0 && len == mesh.Data.Length) // well redudante maybe
|
||||||
|
@ -170,6 +183,8 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
responsedata["bin_response_data"] = mesh.Data;
|
responsedata["bin_response_data"] = mesh.Data;
|
||||||
responsedata["int_bytes"] = mesh.Data.Length;
|
responsedata["int_bytes"] = mesh.Data.Length;
|
||||||
responsedata["reusecontext"] = false;
|
responsedata["reusecontext"] = false;
|
||||||
|
responsedata["int_lod"] = 3;
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -193,6 +208,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||||
responsedata["int_response_code"] = 200;
|
responsedata["int_response_code"] = 200;
|
||||||
responsedata["reusecontext"] = false;
|
responsedata["reusecontext"] = false;
|
||||||
|
responsedata["int_lod"] = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -201,6 +217,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
responsedata["content_type"] = "application/vnd.ll.mesh";
|
responsedata["content_type"] = "application/vnd.ll.mesh";
|
||||||
responsedata["int_response_code"] = 200;
|
responsedata["int_response_code"] = 200;
|
||||||
responsedata["reusecontext"] = false;
|
responsedata["reusecontext"] = false;
|
||||||
|
responsedata["int_lod"] = 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Optionally add additional mesh types here
|
// Optionally add additional mesh types here
|
||||||
|
@ -211,6 +228,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
responsedata["keepalive"] = false;
|
responsedata["keepalive"] = false;
|
||||||
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
|
responsedata["str_response_string"] = "Unfortunately, this asset isn't a mesh.";
|
||||||
responsedata["reusecontext"] = false;
|
responsedata["reusecontext"] = false;
|
||||||
|
responsedata["int_lod"] = 1;
|
||||||
return responsedata;
|
return responsedata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,6 +239,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
responsedata["keepalive"] = false;
|
responsedata["keepalive"] = false;
|
||||||
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
|
responsedata["str_response_string"] = "Your Mesh wasn't found. Sorry!";
|
||||||
responsedata["reusecontext"] = false;
|
responsedata["reusecontext"] = false;
|
||||||
|
responsedata["int_lod"] = 0;
|
||||||
return responsedata;
|
return responsedata;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1135,6 +1135,8 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
void SetChildAgentThrottle(byte[] throttle);
|
void SetChildAgentThrottle(byte[] throttle);
|
||||||
|
|
||||||
|
void SetAgentThrottleSilent(int throttle, int setting);
|
||||||
|
|
||||||
void SendAvatarDataImmediate(ISceneEntity avatar);
|
void SendAvatarDataImmediate(ISceneEntity avatar);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -60,6 +60,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private IAssetService m_AssetService;
|
private IAssetService m_AssetService;
|
||||||
private bool m_Enabled = true;
|
private bool m_Enabled = true;
|
||||||
private string m_URL;
|
private string m_URL;
|
||||||
|
|
||||||
struct aPollRequest
|
struct aPollRequest
|
||||||
{
|
{
|
||||||
public PollServiceMeshEventArgs thepoll;
|
public PollServiceMeshEventArgs thepoll;
|
||||||
|
@ -71,6 +72,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
{
|
{
|
||||||
public Hashtable response;
|
public Hashtable response;
|
||||||
public int bytes;
|
public int bytes;
|
||||||
|
public int lod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,6 +114,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
// Cap doesn't exist
|
// Cap doesn't exist
|
||||||
if (m_URL != string.Empty)
|
if (m_URL != string.Empty)
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(Scene pScene)
|
public void AddRegion(Scene pScene)
|
||||||
|
@ -192,7 +195,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
PollServiceMeshEventArgs args;
|
PollServiceMeshEventArgs args;
|
||||||
if (m_pollservices.TryGetValue(user, out args))
|
if (m_pollservices.TryGetValue(user, out args))
|
||||||
{
|
{
|
||||||
args.UpdateThrottle(imagethrottle);
|
args.UpdateThrottle(imagethrottle, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -242,11 +245,12 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
new Dictionary<UUID, aPollResponse>();
|
new Dictionary<UUID, aPollResponse>();
|
||||||
|
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
private CapsDataThrottler m_throttler = new CapsDataThrottler(100000, 1400000, 10000);
|
private MeshCapsDataThrottler m_throttler;
|
||||||
public PollServiceMeshEventArgs(UUID pId, Scene scene) :
|
public PollServiceMeshEventArgs(UUID pId, Scene scene) :
|
||||||
base(null, null, null, null, pId, int.MaxValue)
|
base(null, null, null, null, pId, int.MaxValue)
|
||||||
{
|
{
|
||||||
m_scene = scene;
|
m_scene = scene;
|
||||||
|
m_throttler = new MeshCapsDataThrottler(100000, 1400000, 10000, scene);
|
||||||
// x is request id, y is userid
|
// x is request id, y is userid
|
||||||
HasEvents = (x, y) =>
|
HasEvents = (x, y) =>
|
||||||
{
|
{
|
||||||
|
@ -268,6 +272,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
m_throttler.ProcessTime();
|
||||||
responses.Remove(x);
|
responses.Remove(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +328,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
response["reusecontext"] = false;
|
response["reusecontext"] = false;
|
||||||
|
|
||||||
lock (responses)
|
lock (responses)
|
||||||
responses[requestID] = new aPollResponse() { bytes = 0, response = response };
|
responses[requestID] = new aPollResponse() { bytes = 0, response = response, lod = 0 };
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -334,6 +339,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
responses[requestID] = new aPollResponse()
|
responses[requestID] = new aPollResponse()
|
||||||
{
|
{
|
||||||
bytes = (int)response["int_bytes"],
|
bytes = (int)response["int_bytes"],
|
||||||
|
lod = (int)response["int_lod"],
|
||||||
response = response
|
response = response
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -341,9 +347,9 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_throttler.ProcessTime();
|
m_throttler.ProcessTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void UpdateThrottle(int pimagethrottle)
|
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
|
||||||
{
|
{
|
||||||
m_throttler.ThrottleBytes = pimagethrottle;
|
m_throttler.UpdateThrottle(pimagethrottle, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,18 +404,31 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal sealed class CapsDataThrottler
|
internal sealed class MeshCapsDataThrottler
|
||||||
{
|
{
|
||||||
|
|
||||||
private volatile int currenttime = 0;
|
private volatile int currenttime = 0;
|
||||||
private volatile int lastTimeElapsed = 0;
|
private volatile int lastTimeElapsed = 0;
|
||||||
private volatile int BytesSent = 0;
|
private volatile int BytesSent = 0;
|
||||||
private int oversizedImages = 0;
|
private int Lod3 = 0;
|
||||||
public CapsDataThrottler(int pBytes, int max, int min)
|
private int Lod2 = 0;
|
||||||
|
private int Lod1 = 0;
|
||||||
|
private int UserSetThrottle = 0;
|
||||||
|
private int UDPSetThrottle = 0;
|
||||||
|
private int CapSetThrottle = 0;
|
||||||
|
private float CapThrottleDistributon = 0.30f;
|
||||||
|
private readonly Scene m_scene;
|
||||||
|
private ThrottleOutPacketType Throttle;
|
||||||
|
|
||||||
|
public MeshCapsDataThrottler(int pBytes, int max, int min, Scene pScene)
|
||||||
{
|
{
|
||||||
ThrottleBytes = pBytes;
|
ThrottleBytes = pBytes;
|
||||||
lastTimeElapsed = Util.EnvironmentTickCount();
|
lastTimeElapsed = Util.EnvironmentTickCount();
|
||||||
|
Throttle = ThrottleOutPacketType.Task;
|
||||||
|
m_scene = pScene;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
|
public bool hasEvents(UUID key, Dictionary<UUID, aPollResponse> responses)
|
||||||
{
|
{
|
||||||
PassTime();
|
PassTime();
|
||||||
|
@ -427,17 +446,23 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
if (BytesSent + response.bytes <= ThrottleBytes)
|
if (BytesSent + response.bytes <= ThrottleBytes)
|
||||||
{
|
{
|
||||||
BytesSent += response.bytes;
|
BytesSent += response.bytes;
|
||||||
//TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + 1000, unlockyn = false };
|
|
||||||
//m_actions.Add(timeBasedAction);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Big textures
|
// Lod3 Over
|
||||||
else if (response.bytes > ThrottleBytes && oversizedImages <= ((ThrottleBytes % 50000) + 1))
|
else if (response.bytes > ThrottleBytes && Lod3 <= (((ThrottleBytes * .30f) % 50000) + 1))
|
||||||
{
|
{
|
||||||
Interlocked.Increment(ref oversizedImages);
|
Interlocked.Increment(ref Lod3);
|
||||||
BytesSent += response.bytes;
|
BytesSent += response.bytes;
|
||||||
//TimeBasedAction timeBasedAction = new TimeBasedAction { byteRemoval = response.bytes, requestId = key, timeMS = currenttime + (((response.bytes % ThrottleBytes)+1)*1000) , unlockyn = false };
|
|
||||||
//m_actions.Add(timeBasedAction);
|
return true;
|
||||||
|
}
|
||||||
|
// Lod2 Over
|
||||||
|
else if (response.bytes > ThrottleBytes && Lod2 <= (((ThrottleBytes * .30f) % 10000) + 1))
|
||||||
|
{
|
||||||
|
Interlocked.Increment(ref Lod2);
|
||||||
|
BytesSent += response.bytes;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -448,6 +473,11 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
return haskey;
|
return haskey;
|
||||||
}
|
}
|
||||||
|
public void SubtractBytes(int bytes,int lod)
|
||||||
|
{
|
||||||
|
BytesSent -= bytes;
|
||||||
|
}
|
||||||
|
|
||||||
public void ProcessTime()
|
public void ProcessTime()
|
||||||
{
|
{
|
||||||
PassTime();
|
PassTime();
|
||||||
|
@ -459,18 +489,42 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
currenttime = Util.EnvironmentTickCount();
|
currenttime = Util.EnvironmentTickCount();
|
||||||
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
|
int timeElapsed = Util.EnvironmentTickCountSubtract(currenttime, lastTimeElapsed);
|
||||||
//processTimeBasedActions(responses);
|
//processTimeBasedActions(responses);
|
||||||
if (Util.EnvironmentTickCountSubtract(currenttime, timeElapsed) >= 1000)
|
if (currenttime - timeElapsed >= 1000)
|
||||||
{
|
{
|
||||||
lastTimeElapsed = Util.EnvironmentTickCount();
|
lastTimeElapsed = Util.EnvironmentTickCount();
|
||||||
BytesSent -= ThrottleBytes;
|
BytesSent -= ThrottleBytes;
|
||||||
if (BytesSent < 0) BytesSent = 0;
|
if (BytesSent < 0) BytesSent = 0;
|
||||||
if (BytesSent < ThrottleBytes)
|
if (BytesSent < ThrottleBytes)
|
||||||
{
|
{
|
||||||
oversizedImages = 0;
|
Lod3 = 0;
|
||||||
|
Lod2 = 0;
|
||||||
|
Lod1 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public int ThrottleBytes;
|
private void AlterThrottle(int setting, ScenePresence p)
|
||||||
|
{
|
||||||
|
p.ControllingClient.SetAgentThrottleSilent((int)Throttle,setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int ThrottleBytes
|
||||||
|
{
|
||||||
|
get { return CapSetThrottle; }
|
||||||
|
set { CapSetThrottle = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void UpdateThrottle(int pimagethrottle, ScenePresence p)
|
||||||
|
{
|
||||||
|
// Client set throttle !
|
||||||
|
UserSetThrottle = pimagethrottle;
|
||||||
|
CapSetThrottle = (int)(pimagethrottle*CapThrottleDistributon);
|
||||||
|
UDPSetThrottle = (int) (pimagethrottle*(100 - CapThrottleDistributon));
|
||||||
|
if (CapSetThrottle < 4068)
|
||||||
|
CapSetThrottle = 4068; // at least two discovery mesh
|
||||||
|
p.ControllingClient.SetAgentThrottleSilent((int) Throttle, UDPSetThrottle);
|
||||||
|
ProcessTime();
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11883,6 +11883,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the throttles from values supplied by the client
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="throttles"></param>
|
||||||
|
public void SetAgentThrottleSilent(int throttle, int setting)
|
||||||
|
{
|
||||||
|
m_udpClient.ForceThrottleSetting(throttle,setting);
|
||||||
|
//m_udpClient.SetThrottles(throttles);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the current throttles for this client as a packed byte array
|
/// Get the current throttles for this client as a packed byte array
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -682,6 +682,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (m_nextOnQueueEmpty == 0)
|
if (m_nextOnQueueEmpty == 0)
|
||||||
m_nextOnQueueEmpty = 1;
|
m_nextOnQueueEmpty = 1;
|
||||||
}
|
}
|
||||||
|
internal void ForceThrottleSetting(int throttle, int setting)
|
||||||
|
{
|
||||||
|
m_throttleCategories[throttle].RequestedDripRate = Math.Max(setting, LLUDPServer.MTU); ;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
|
/// Converts a <seealso cref="ThrottleOutPacketType"/> integer to a
|
||||||
|
|
|
@ -1428,6 +1428,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetAgentThrottleSilent(int throttle, int setting)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
public byte[] GetThrottlesPacked(float multiplier)
|
public byte[] GetThrottlesPacked(float multiplier)
|
||||||
{
|
{
|
||||||
return new byte[0];
|
return new byte[0];
|
||||||
|
|
|
@ -596,6 +596,12 @@ namespace OpenSim.Region.OptionalModules.World.NPC
|
||||||
|
|
||||||
public virtual void SetChildAgentThrottle(byte[] throttle)
|
public virtual void SetChildAgentThrottle(byte[] throttle)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAgentThrottleSilent(int throttle, int setting)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public byte[] GetThrottlesPacked(float multiplier)
|
public byte[] GetThrottlesPacked(float multiplier)
|
||||||
{
|
{
|
||||||
|
|
|
@ -520,6 +520,12 @@ namespace OpenSim.Tests.Common.Mock
|
||||||
|
|
||||||
public virtual void SetChildAgentThrottle(byte[] throttle)
|
public virtual void SetChildAgentThrottle(byte[] throttle)
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetAgentThrottleSilent(int throttle, int setting)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
public byte[] GetThrottlesPacked(float multiplier)
|
public byte[] GetThrottlesPacked(float multiplier)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue