aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-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.