diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs | 32 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs | 153 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLPacketThrottle.cs | 7 |
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. |