aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorCharles Krinke2009-04-18 18:35:03 +0000
committerCharles Krinke2009-04-18 18:35:03 +0000
commit2578db3dfad2d12519f5b1c0f5e63145475c0d07 (patch)
tree676c260058b39666a0dac750a2b1cb0e025c2b46 /OpenSim/Region/ClientStack
parentRemove the default plywood texture from the library. Its presence can cause u... (diff)
downloadopensim-SC-2578db3dfad2d12519f5b1c0f5e63145475c0d07.zip
opensim-SC-2578db3dfad2d12519f5b1c0f5e63145475c0d07.tar.gz
opensim-SC-2578db3dfad2d12519f5b1c0f5e63145475c0d07.tar.bz2
opensim-SC-2578db3dfad2d12519f5b1c0f5e63145475c0d07.tar.xz
Thank you kindly, RemedyTomm for a patch that:
Following feedback from 0003440, i've made some changes to the new texture pipeline to optimise performance. The changes are: - Fixed a math issue where a small percentage of images with a certain size (on the packet boundary) would not have their final data delivered. This issue has been present since pre- 0003440 - It was suggested that a discardlevel of -1 and a prioriy of 0 meant to abandon the transfer, this is incorrect and caused some textures to clog. - The texture throttle blocking queue is now only filled in relation to the actual throttle amount.. i.e, on a connection throttled to 300k, only twenty packets will be placed in the queue at a time, on a larger connection it will be much more. This is to balance responsiveness to requests and speed, and to minimise wasted packets. - The engine now keeps track of the number of pending textures, and the stack will not be walked if there's no textures pending, saving CPU. Textures are only considered "pending" when they've already been decoded. - As part of the above, some textures may receive twice as much data per cycle if the number of pending textures is below the cycle threshold, this should prevent loading from slowing down when there are fewer textures in the queue.
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs32
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs153
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs7
3 files changed, 134 insertions, 58 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
index 276dfbe..a93a3e5 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs
@@ -48,6 +48,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
48 48
49 public class J2KImage 49 public class J2KImage
50 { 50 {
51
51 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 public double m_designatedPriorityKey; 53 public double m_designatedPriorityKey;
53 public double m_requestedPriority = 0.0d; 54 public double m_requestedPriority = 0.0d;
@@ -61,7 +62,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
61 public AssetBase m_MissingSubstitute = null; 62 public AssetBase m_MissingSubstitute = null;
62 public bool m_decoded = false; 63 public bool m_decoded = false;
63 public bool m_completedSendAtCurrentDiscardLevel; 64 public bool m_completedSendAtCurrentDiscardLevel;
64 65
65 private sbyte m_discardLevel=-1; 66 private sbyte m_discardLevel=-1;
66 private uint m_packetNumber; 67 private uint m_packetNumber;
67 private bool m_decoderequested = false; 68 private bool m_decoderequested = false;
@@ -72,7 +73,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
72 private const int cImagePacketSize = 1000; 73 private const int cImagePacketSize = 1000;
73 private const int cFirstPacketSize = 600; 74 private const int cFirstPacketSize = 600;
74 private AssetBase m_asset = null; 75 private AssetBase m_asset = null;
75 76 private LLImageManager m_image;
77 public J2KImage(LLImageManager image)
78 {
79 m_image = image;
80 }
76 81
77 public uint m_pPacketNumber 82 public uint m_pPacketNumber
78 { 83 {
@@ -103,6 +108,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
103 108
104 public void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) 109 public void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers)
105 { 110 {
111 m_image.m_outstandingtextures++;
106 Layers = layers; 112 Layers = layers;
107 m_decoded = true; 113 m_decoded = true;
108 RunUpdate(); 114 RunUpdate();
@@ -130,8 +136,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
130 { 136 {
131 if (m_packetNumber == 1) 137 if (m_packetNumber == 1)
132 return m_asset.Data.Length; 138 return m_asset.Data.Length;
133 return (m_asset.Data.Length - cFirstPacketSize) % cImagePacketSize; 139 int lastsize = (m_asset.Data.Length - cFirstPacketSize) % cImagePacketSize;
134 } 140 //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary
141 if (lastsize == 0)
142 {
143 lastsize = cImagePacketSize;
144 }
145 return lastsize;
146 }
147
135 148
136 public int CurrentBytePosition() 149 public int CurrentBytePosition()
137 { 150 {
@@ -247,7 +260,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
247 m_sentinfo = true; 260 m_sentinfo = true;
248 m_packetNumber++; 261 m_packetNumber++;
249 } 262 }
250 263 bool ignoreStop = false;
251 if (m_packetNumber < 2) 264 if (m_packetNumber < 2)
252 { 265 {
253 m_packetNumber = 2; 266 m_packetNumber = 2;
@@ -260,6 +273,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
260 SendMore = SendPacket(client); 273 SendMore = SendPacket(client);
261 m_packetNumber++; 274 m_packetNumber++;
262 } 275 }
276
263 if (m_packetNumber > m_stopPacket) 277 if (m_packetNumber > m_stopPacket)
264 { 278 {
265 279
@@ -339,11 +353,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
339 { 353 {
340 m_discardLevel = m_requestedDiscardLevel; 354 m_discardLevel = m_requestedDiscardLevel;
341 } 355 }
342 356
343 //Calculate the m_stopPacket 357 //Calculate the m_stopPacket
344 if (Layers.Length > 0) 358 if (Layers.Length > 0)
345 { 359 {
346 m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - m_discardLevel].End); 360 m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - m_discardLevel].End);
361 //I don't know why, but the viewer seems to expect the final packet if the file
362 //is just one packet bigger.
363 if (TexturePacketCount() == m_stopPacket + 1)
364 {
365 m_stopPacket = TexturePacketCount();
366 }
347 } 367 }
348 else 368 else
349 { 369 {
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
index f0fd74b..169bab2 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
@@ -46,7 +46,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
46 //ProcessImageQueue 46 //ProcessImageQueue
47 //Close 47 //Close
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 private bool m_shuttingdown = false; 49 private bool m_shuttingdown = false;
50 private long m_lastloopprocessed = 0;
50 51
51 private LLClientView m_client; //Client we're assigned to 52 private LLClientView m_client; //Client we're assigned to
52 private IAssetCache m_assetCache; //Asset Cache 53 private IAssetCache m_assetCache; //Asset Cache
@@ -58,6 +59,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
58 private Dictionary<int, int> m_priorityresolver; //Enabling super fast assignment of images with the same priorities 59 private Dictionary<int, int> m_priorityresolver; //Enabling super fast assignment of images with the same priorities
59 60
60 private const double doubleMinimum = .0000001; 61 private const double doubleMinimum = .0000001;
62
63 public int m_outstandingtextures = 0;
61 //Constructor 64 //Constructor
62 public LLImageManager(LLClientView client, IAssetCache pAssetCache, IJ2KDecoder pJ2kDecodeModule) 65 public LLImageManager(LLClientView client, IAssetCache pAssetCache, IJ2KDecoder pJ2kDecodeModule)
63 { 66 {
@@ -92,20 +95,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
92 95
93 J2KImage imgrequest = m_imagestore[newRequest.RequestedAssetID]; 96 J2KImage imgrequest = m_imagestore[newRequest.RequestedAssetID];
94 97
95 //if (newRequest.requestSequence > imgrequest.m_lastSequence) 98 if (newRequest.requestSequence > imgrequest.m_lastSequence)
96 //{ 99 {
97 imgrequest.m_lastSequence = newRequest.requestSequence; 100 imgrequest.m_lastSequence = newRequest.requestSequence;
98 101
99 //First of all, is this being killed? 102 //First of all, is this being killed?
100 if (newRequest.Priority == 0.0f && newRequest.DiscardLevel == -1) 103 //if (newRequest.Priority == 0.0f && newRequest.DiscardLevel == -1)
101 { 104 //{
102 //Remove the old priority 105 //Do nothing (leaving the if for future use)
103 m_priorities.Remove(imgrequest.m_designatedPriorityKey); 106 //}
104 m_imagestore.Remove(imgrequest.m_requestedUUID); 107 //else
105 imgrequest = null; 108 //{
106 }
107 else
108 {
109 109
110 110
111 //Check the priority 111 //Check the priority
@@ -125,14 +125,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
125 //Update the requested packet number 125 //Update the requested packet number
126 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; 126 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber;
127 127
128 //Run an update 128 //Check if this will create an outstanding texture request
129 imgrequest.RunUpdate(); 129 bool activated = imgrequest.m_completedSendAtCurrentDiscardLevel;
130 } 130 //Run an update
131 //} 131 imgrequest.RunUpdate();
132 if (activated && !imgrequest.m_completedSendAtCurrentDiscardLevel && imgrequest.m_decoded)
133 {
134 m_outstandingtextures++;
135 }
136
137 //}
138 }
132 } 139 }
133 else 140 else
134 { 141 {
135 J2KImage imgrequest = new J2KImage(); 142 J2KImage imgrequest = new J2KImage(this);
136 143
137 //Assign our missing substitute 144 //Assign our missing substitute
138 imgrequest.m_MissingSubstitute = m_missingsubstitute; 145 imgrequest.m_MissingSubstitute = m_missingsubstitute;
@@ -198,20 +205,50 @@ namespace OpenSim.Region.ClientStack.LindenUDP
198 //since we're processing in a more efficient manner. 205 //since we're processing in a more efficient manner.
199 206
200 int numCollected = 0; 207 int numCollected = 0;
201 //First of all make sure our packet queue isn't above our threshold
202 if (m_client == null)
203 return;
204 208
205 if (m_client.PacketHandler == null) 209 //Calculate our threshold
206 return; 210 int threshold;
211 if (m_lastloopprocessed == 0)
212 {
213 //This is decent for a semi fast machine, but we'll calculate it more accurately based on time below
214 threshold = m_client.PacketHandler.PacketQueue.TextureThrottle.Current / 6300;
215 m_lastloopprocessed = DateTime.Now.Ticks;
216 }
217 else
218 {
219 double throttleseconds = ((double)DateTime.Now.Ticks - (double)m_lastloopprocessed) / (double)TimeSpan.TicksPerSecond;
220 throttleseconds = throttleseconds * m_client.PacketHandler.PacketQueue.TextureThrottle.Current;
221
222 //Average of 1000 bytes per packet
223 throttleseconds = throttleseconds / 1000;
224
225 //Safe-zone multiplier of 2.0
226 threshold = (int)(throttleseconds * 2.0);
227 m_lastloopprocessed = DateTime.Now.Ticks;
228
229 }
230
231 if (threshold < 10)
232 {
233 threshold = 10;
234 }
235
236 if (m_client.PacketHandler == null)
237 return;
238
239 if (m_client.PacketHandler.PacketQueue == null)
240 return;
241
242 //First of all make sure our packet queue isn't above our threshold
207 243
208 if (m_client.PacketHandler.PacketQueue == null) 244 //Uncomment this to see what the texture stack is doing
209 return; 245 //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount.ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString());
246 if (m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount < threshold && m_outstandingtextures > 0)
247 {
248 bool justreset = false;
249
210 250
211 251
212 if (m_client.PacketHandler.PacketQueue.TextureOutgoingPacketQueueCount < 200)
213 {
214
215 for (int x = m_priorities.Count - 1; x > -1; x--) 252 for (int x = m_priorities.Count - 1; x > -1; x--)
216 { 253 {
217 254
@@ -221,41 +258,55 @@ namespace OpenSim.Region.ClientStack.LindenUDP
221 258
222 numCollected++; 259 numCollected++;
223 //SendPackets will send up to ten packets per cycle 260 //SendPackets will send up to ten packets per cycle
224 //m_log.Debug("Processing packet with priority of " + imagereq.m_designatedPriorityKey.ToString());
225 if (imagereq.SendPackets(m_client)) 261 if (imagereq.SendPackets(m_client))
226 { 262 {
227 //Send complete 263 //Send complete
228 imagereq.m_completedSendAtCurrentDiscardLevel = true; 264 if (!imagereq.m_completedSendAtCurrentDiscardLevel)
229 //Re-assign priority to bottom
230 //Remove the old priority
231 m_priorities.Remove(imagereq.m_designatedPriorityKey);
232 int lowest;
233 if (m_priorities.Count > 0)
234 { 265 {
235 lowest = (int)m_priorities.Keys[0]; 266 imagereq.m_completedSendAtCurrentDiscardLevel = true;
236 lowest--; 267 m_outstandingtextures--;
237 } 268 //Re-assign priority to bottom
238 else 269 //Remove the old priority
239 { 270 m_priorities.Remove(imagereq.m_designatedPriorityKey);
240 lowest = -10000; 271 int lowest;
241 } 272 if (m_priorities.Count > 0)
242 m_priorities.Add((double)lowest, imagereq.m_requestedUUID); 273 {
243 imagereq.m_designatedPriorityKey = (double)lowest; 274 lowest = (int)m_priorities.Keys[0];
244 if (m_priorityresolver.ContainsKey((int)lowest)) 275 lowest--;
245 { 276 }
246 m_priorityresolver[(int)lowest]++; 277 else
247 } 278 {
248 else 279 lowest = -10000;
249 { 280 }
250 m_priorityresolver.Add((int)lowest, 0); 281 m_priorities.Add((double)lowest, imagereq.m_requestedUUID);
282 imagereq.m_designatedPriorityKey = (double)lowest;
283 if (m_priorityresolver.ContainsKey((int)lowest))
284 {
285 m_priorityresolver[(int)lowest]++;
286 }
287 else
288 {
289 m_priorityresolver.Add((int)lowest, 0);
290 }
251 } 291 }
252 } 292 }
253 //m_log.Debug("...now has priority of " + imagereq.m_designatedPriorityKey.ToString());
254 if (numCollected == count) 293 if (numCollected == count)
255 { 294 {
256 break; 295 break;
257 } 296 }
258 } 297 }
298 if (numCollected == count || m_outstandingtextures == 0)
299 break;
300 if (numCollected % m_outstandingtextures == 0 && !justreset)
301 {
302 //We've gotten as much as we can from the stack,
303 //reset to the top so that we can send MOAR DATA (nomnomnom)!
304 x = m_priorities.Count - 1;
305
306 justreset = true; //prevents us from getting stuck in a loop
307 }
308
309
259 } 310 }
260 } 311 }
261 312
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs
index 6d199ad..bda87a1 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs
@@ -49,7 +49,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
49 public int Min 49 public int Min
50 { 50 {
51 get { return m_minAllowableThrottle; } 51 get { return m_minAllowableThrottle; }
52 } 52 }
53
54 public int Current
55 {
56 get { return m_currentThrottle; }
57 }
53 58
54 /// <summary> 59 /// <summary>
55 /// Constructor. 60 /// Constructor.