diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP')
5 files changed, 161 insertions, 241 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs index 5f549b5..0e3630c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs | |||
@@ -47,69 +47,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
47 | 47 | ||
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 | 49 | ||
50 | public uint m_lastSequence; | 50 | public uint LastSequence; |
51 | public float m_requestedPriority; | 51 | public float Priority; |
52 | public uint m_requestedPacketNumber; | 52 | public uint StartPacket; |
53 | public sbyte m_requestedDiscardLevel; | 53 | public sbyte DiscardLevel; |
54 | public UUID m_requestedUUID; | 54 | public UUID TextureID; |
55 | public IJ2KDecoder m_j2kDecodeModule; | 55 | public IJ2KDecoder J2KDecoder; |
56 | public IAssetService m_assetCache; | 56 | public IAssetService AssetService; |
57 | public OpenJPEG.J2KLayerInfo[] m_layers; | 57 | public OpenJPEG.J2KLayerInfo[] Layers; |
58 | public bool m_decoded; | 58 | public bool IsDecoded; |
59 | public bool m_hasasset; | 59 | public bool HasAsset; |
60 | public C5.IPriorityQueueHandle<J2KImage> m_priorityQueueHandle; | 60 | public C5.IPriorityQueueHandle<J2KImage> PriorityQueueHandle; |
61 | 61 | ||
62 | private uint m_packetNumber; | 62 | private uint m_currentPacket; |
63 | private bool m_decoderequested; | 63 | private bool m_decodeRequested; |
64 | private bool m_asset_requested; | 64 | private bool m_assetRequested; |
65 | private bool m_sentinfo; | 65 | private bool m_sentInfo; |
66 | private uint m_stopPacket; | 66 | private uint m_stopPacket; |
67 | private AssetBase m_asset; | 67 | private byte[] m_asset; |
68 | private int m_assetDataLength; | ||
69 | private LLImageManager m_imageManager; | 68 | private LLImageManager m_imageManager; |
70 | 69 | ||
71 | #region Properties | ||
72 | |||
73 | public uint m_pPacketNumber | ||
74 | { | ||
75 | get { return m_packetNumber; } | ||
76 | } | ||
77 | public uint m_pStopPacketNumber | ||
78 | { | ||
79 | get { return m_stopPacket; } | ||
80 | } | ||
81 | |||
82 | public byte[] Data | ||
83 | { | ||
84 | get | ||
85 | { | ||
86 | if (m_asset != null) | ||
87 | return m_asset.Data; | ||
88 | else | ||
89 | return null; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | public ushort TexturePacketCount() | ||
94 | { | ||
95 | if (!m_decoded) | ||
96 | return 0; | ||
97 | |||
98 | try | ||
99 | { | ||
100 | return (ushort)(((m_assetDataLength - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1); | ||
101 | } | ||
102 | catch (Exception) | ||
103 | { | ||
104 | // If the asset is missing/destroyed/truncated, we will land | ||
105 | // here | ||
106 | // | ||
107 | return 0; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | #endregion Properties | ||
112 | |||
113 | public J2KImage(LLImageManager imageManager) | 70 | public J2KImage(LLImageManager imageManager) |
114 | { | 71 | { |
115 | m_imageManager = imageManager; | 72 | m_imageManager = imageManager; |
@@ -117,33 +74,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
117 | 74 | ||
118 | public bool SendPackets(LLClientView client, int maxpack) | 75 | public bool SendPackets(LLClientView client, int maxpack) |
119 | { | 76 | { |
120 | if (m_packetNumber <= m_stopPacket) | 77 | if (m_currentPacket <= m_stopPacket) |
121 | { | 78 | { |
122 | bool SendMore = true; | 79 | bool SendMore = true; |
123 | if (!m_sentinfo || (m_packetNumber == 0)) | 80 | if (!m_sentInfo || (m_currentPacket == 0)) |
124 | { | 81 | { |
125 | if (SendFirstPacket(client)) | 82 | if (SendFirstPacket(client)) |
126 | { | 83 | { |
127 | SendMore = false; | 84 | SendMore = false; |
128 | } | 85 | } |
129 | m_sentinfo = true; | 86 | m_sentInfo = true; |
130 | m_packetNumber++; | 87 | m_currentPacket++; |
131 | } | 88 | } |
132 | // bool ignoreStop = false; | 89 | if (m_currentPacket < 2) |
133 | if (m_packetNumber < 2) | ||
134 | { | 90 | { |
135 | m_packetNumber = 2; | 91 | m_currentPacket = 2; |
136 | } | 92 | } |
137 | 93 | ||
138 | int count = 0; | 94 | int count = 0; |
139 | while (SendMore && count < maxpack && m_packetNumber <= m_stopPacket) | 95 | while (SendMore && count < maxpack && m_currentPacket <= m_stopPacket) |
140 | { | 96 | { |
141 | count++; | 97 | count++; |
142 | SendMore = SendPacket(client); | 98 | SendMore = SendPacket(client); |
143 | m_packetNumber++; | 99 | m_currentPacket++; |
144 | } | 100 | } |
145 | 101 | ||
146 | if (m_packetNumber > m_stopPacket) | 102 | if (m_currentPacket > m_stopPacket) |
147 | return true; | 103 | return true; |
148 | } | 104 | } |
149 | 105 | ||
@@ -156,68 +112,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
156 | //and assign the real discardLevel and packetNumber | 112 | //and assign the real discardLevel and packetNumber |
157 | //assuming of course that the connected client might be bonkers | 113 | //assuming of course that the connected client might be bonkers |
158 | 114 | ||
159 | if (!m_hasasset) | 115 | if (!HasAsset) |
160 | { | 116 | { |
161 | if (!m_asset_requested) | 117 | if (!m_assetRequested) |
162 | { | 118 | { |
163 | m_asset_requested = true; | 119 | m_assetRequested = true; |
164 | m_assetCache.Get(m_requestedUUID.ToString(), this, AssetReceived); | 120 | AssetService.Get(TextureID.ToString(), this, AssetReceived); |
165 | } | 121 | } |
166 | } | 122 | } |
167 | else | 123 | else |
168 | { | 124 | { |
169 | if (!m_decoded) | 125 | if (!IsDecoded) |
170 | { | 126 | { |
171 | //We need to decode the requested image first | 127 | //We need to decode the requested image first |
172 | if (!m_decoderequested) | 128 | if (!m_decodeRequested) |
173 | { | 129 | { |
174 | //Request decode | 130 | //Request decode |
175 | m_decoderequested = true; | 131 | m_decodeRequested = true; |
176 | // Do we have a jpeg decoder? | 132 | // Do we have a jpeg decoder? |
177 | if (m_j2kDecodeModule != null) | 133 | if (J2KDecoder != null) |
178 | { | 134 | { |
179 | if (Data == null) | 135 | if (m_asset == null) |
180 | { | 136 | { |
181 | J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); | 137 | J2KDecodedCallback(TextureID, new OpenJPEG.J2KLayerInfo[0]); |
182 | } | 138 | } |
183 | else | 139 | else |
184 | { | 140 | { |
185 | // Send it off to the jpeg decoder | 141 | // Send it off to the jpeg decoder |
186 | m_j2kDecodeModule.BeginDecode(m_requestedUUID, Data, J2KDecodedCallback); | 142 | J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback); |
187 | } | 143 | } |
188 | 144 | ||
189 | } | 145 | } |
190 | else | 146 | else |
191 | { | 147 | { |
192 | J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); | 148 | J2KDecodedCallback(TextureID, new OpenJPEG.J2KLayerInfo[0]); |
193 | } | 149 | } |
194 | } | 150 | } |
195 | } | 151 | } |
196 | else | 152 | else |
197 | { | 153 | { |
198 | // Check for missing image asset data | 154 | // Check for missing image asset data |
199 | if (m_asset == null || m_asset.Data == null) | 155 | if (m_asset == null) |
200 | { | 156 | { |
201 | // FIXME: | 157 | m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing asset data (no missing image texture?). Canceling texture transfer"); |
202 | m_packetNumber = m_stopPacket; | 158 | m_currentPacket = m_stopPacket; |
203 | return; | 159 | return; |
204 | } | 160 | } |
205 | 161 | ||
206 | if (m_requestedDiscardLevel >= 0 || m_stopPacket == 0) | 162 | if (DiscardLevel >= 0 || m_stopPacket == 0) |
207 | { | 163 | { |
208 | int maxDiscardLevel = Math.Max(0, m_layers.Length - 1); | 164 | int maxDiscardLevel = Math.Max(0, Layers.Length - 1); |
209 | 165 | ||
210 | // Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel | 166 | // Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel |
211 | if (m_requestedDiscardLevel < 0 && m_stopPacket == 0) | 167 | if (DiscardLevel < 0 && m_stopPacket == 0) |
212 | m_requestedDiscardLevel = (sbyte)maxDiscardLevel; | 168 | DiscardLevel = (sbyte)maxDiscardLevel; |
213 | 169 | ||
214 | // Clamp at the highest discard level | 170 | // Clamp at the highest discard level |
215 | m_requestedDiscardLevel = (sbyte)Math.Min(m_requestedDiscardLevel, maxDiscardLevel); | 171 | DiscardLevel = (sbyte)Math.Min(DiscardLevel, maxDiscardLevel); |
216 | 172 | ||
217 | //Calculate the m_stopPacket | 173 | //Calculate the m_stopPacket |
218 | if (m_layers.Length > 0) | 174 | if (Layers.Length > 0) |
219 | { | 175 | { |
220 | m_stopPacket = (uint)GetPacketForBytePosition(m_layers[(m_layers.Length - 1) - m_requestedDiscardLevel].End); | 176 | m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - DiscardLevel].End); |
221 | //I don't know why, but the viewer seems to expect the final packet if the file | 177 | //I don't know why, but the viewer seems to expect the final packet if the file |
222 | //is just one packet bigger. | 178 | //is just one packet bigger. |
223 | if (TexturePacketCount() == m_stopPacket + 1) | 179 | if (TexturePacketCount() == m_stopPacket + 1) |
@@ -230,7 +186,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
230 | m_stopPacket = TexturePacketCount(); | 186 | m_stopPacket = TexturePacketCount(); |
231 | } | 187 | } |
232 | 188 | ||
233 | m_packetNumber = m_requestedPacketNumber; | 189 | m_currentPacket = StartPacket; |
234 | } | 190 | } |
235 | 191 | ||
236 | if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0) | 192 | if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0) |
@@ -242,20 +198,52 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
242 | } | 198 | } |
243 | } | 199 | } |
244 | 200 | ||
201 | private bool SendFirstPacket(LLClientView client) | ||
202 | { | ||
203 | if (m_asset == null) | ||
204 | { | ||
205 | m_log.Warn("[J2KIMAGE]: Sending ImageNotInDatabase for texture " + TextureID); | ||
206 | client.SendImageNotFound(TextureID); | ||
207 | return true; | ||
208 | } | ||
209 | else if (m_asset.Length <= FIRST_PACKET_SIZE) | ||
210 | { | ||
211 | // We have less then one packet's worth of data | ||
212 | client.SendImageFirstPart(1, TextureID, (uint)m_asset.Length, m_asset, 2); | ||
213 | m_stopPacket = 0; | ||
214 | return true; | ||
215 | } | ||
216 | else | ||
217 | { | ||
218 | // This is going to be a multi-packet texture download | ||
219 | byte[] firstImageData = new byte[FIRST_PACKET_SIZE]; | ||
220 | |||
221 | try { Buffer.BlockCopy(m_asset, 0, firstImageData, 0, FIRST_PACKET_SIZE); } | ||
222 | catch (Exception) | ||
223 | { | ||
224 | m_log.ErrorFormat("[J2KIMAGE]: Texture block copy for the first packet failed. textureid={0}, assetlength={1}", TextureID, m_asset.Length); | ||
225 | return true; | ||
226 | } | ||
227 | |||
228 | client.SendImageFirstPart(TexturePacketCount(), TextureID, (uint)m_asset.Length, firstImageData, (byte)ImageCodec.J2C); | ||
229 | } | ||
230 | return false; | ||
231 | } | ||
232 | |||
245 | private bool SendPacket(LLClientView client) | 233 | private bool SendPacket(LLClientView client) |
246 | { | 234 | { |
247 | bool complete = false; | 235 | bool complete = false; |
248 | int imagePacketSize = ((int)m_packetNumber == (TexturePacketCount())) ? LastPacketSize() : IMAGE_PACKET_SIZE; | 236 | int imagePacketSize = ((int)m_currentPacket == (TexturePacketCount())) ? LastPacketSize() : IMAGE_PACKET_SIZE; |
249 | 237 | ||
250 | try | 238 | try |
251 | { | 239 | { |
252 | if ((CurrentBytePosition() + IMAGE_PACKET_SIZE) > m_assetDataLength) | 240 | if ((CurrentBytePosition() + IMAGE_PACKET_SIZE) > m_asset.Length) |
253 | { | 241 | { |
254 | imagePacketSize = LastPacketSize(); | 242 | imagePacketSize = LastPacketSize(); |
255 | complete = true; | 243 | complete = true; |
256 | if ((CurrentBytePosition() + imagePacketSize) > m_assetDataLength) | 244 | if ((CurrentBytePosition() + imagePacketSize) > m_asset.Length) |
257 | { | 245 | { |
258 | imagePacketSize = m_assetDataLength - CurrentBytePosition(); | 246 | imagePacketSize = m_asset.Length - CurrentBytePosition(); |
259 | complete = true; | 247 | complete = true; |
260 | } | 248 | } |
261 | } | 249 | } |
@@ -266,27 +254,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
266 | if (imagePacketSize > 0) | 254 | if (imagePacketSize > 0) |
267 | { | 255 | { |
268 | byte[] imageData = new byte[imagePacketSize]; | 256 | byte[] imageData = new byte[imagePacketSize]; |
269 | try | 257 | int currentPosition = CurrentBytePosition(); |
270 | { | 258 | |
271 | Buffer.BlockCopy(m_asset.Data, CurrentBytePosition(), imageData, 0, imagePacketSize); | 259 | try { Buffer.BlockCopy(m_asset, currentPosition, imageData, 0, imagePacketSize); } |
272 | } | ||
273 | catch (Exception e) | 260 | catch (Exception e) |
274 | { | 261 | { |
275 | m_log.Error("Error copying texture block. Out of memory? imagePacketSize was " + imagePacketSize.ToString() + " on packet " + m_packetNumber.ToString() + " out of " + m_stopPacket.ToString() + ". Exception: " + e.ToString()); | 262 | m_log.ErrorFormat("[J2KIMAGE]: Texture block copy for the first packet failed. textureid={0}, assetlength={1}, currentposition={2}, imagepacketsize={3}, exception={4}", |
263 | TextureID, m_asset.Length, currentPosition, imagePacketSize, e.Message); | ||
276 | return false; | 264 | return false; |
277 | } | 265 | } |
278 | 266 | ||
279 | //Send the packet | 267 | //Send the packet |
280 | client.SendImageNextPart((ushort)(m_packetNumber - 1), m_requestedUUID, imageData); | 268 | client.SendImageNextPart((ushort)(m_currentPacket - 1), TextureID, imageData); |
281 | } | ||
282 | if (complete) | ||
283 | { | ||
284 | return false; | ||
285 | } | ||
286 | else | ||
287 | { | ||
288 | return true; | ||
289 | } | 269 | } |
270 | |||
271 | return !complete; | ||
290 | } | 272 | } |
291 | catch (Exception) | 273 | catch (Exception) |
292 | { | 274 | { |
@@ -294,6 +276,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
294 | } | 276 | } |
295 | } | 277 | } |
296 | 278 | ||
279 | private ushort TexturePacketCount() | ||
280 | { | ||
281 | if (!IsDecoded) | ||
282 | return 0; | ||
283 | |||
284 | if (m_asset == null) | ||
285 | return 0; | ||
286 | |||
287 | if (m_asset.Length <= FIRST_PACKET_SIZE) | ||
288 | return 1; | ||
289 | |||
290 | return (ushort)(((m_asset.Length - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1); | ||
291 | } | ||
292 | |||
297 | private int GetPacketForBytePosition(int bytePosition) | 293 | private int GetPacketForBytePosition(int bytePosition) |
298 | { | 294 | { |
299 | return ((bytePosition - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1; | 295 | return ((bytePosition - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1; |
@@ -301,9 +297,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
301 | 297 | ||
302 | private int LastPacketSize() | 298 | private int LastPacketSize() |
303 | { | 299 | { |
304 | if (m_packetNumber == 1) | 300 | if (m_currentPacket == 1) |
305 | return m_assetDataLength; | 301 | return m_asset.Length; |
306 | int lastsize = (m_assetDataLength - FIRST_PACKET_SIZE) % IMAGE_PACKET_SIZE; | 302 | int lastsize = (m_asset.Length - FIRST_PACKET_SIZE) % IMAGE_PACKET_SIZE; |
307 | //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary | 303 | //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary |
308 | if (lastsize == 0) | 304 | if (lastsize == 0) |
309 | { | 305 | { |
@@ -314,12 +310,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
314 | 310 | ||
315 | private int CurrentBytePosition() | 311 | private int CurrentBytePosition() |
316 | { | 312 | { |
317 | if (m_packetNumber == 0) | 313 | if (m_currentPacket == 0) |
318 | return 0; | 314 | return 0; |
319 | if (m_packetNumber == 1) | 315 | if (m_currentPacket == 1) |
320 | return FIRST_PACKET_SIZE; | 316 | return FIRST_PACKET_SIZE; |
321 | 317 | ||
322 | int result = FIRST_PACKET_SIZE + ((int)m_packetNumber - 2) * IMAGE_PACKET_SIZE; | 318 | int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE; |
323 | if (result < 0) | 319 | if (result < 0) |
324 | { | 320 | { |
325 | result = FIRST_PACKET_SIZE; | 321 | result = FIRST_PACKET_SIZE; |
@@ -327,68 +323,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
327 | return result; | 323 | return result; |
328 | } | 324 | } |
329 | 325 | ||
330 | private bool SendFirstPacket(LLClientView client) | ||
331 | { | ||
332 | // this means we don't have | ||
333 | if (Data == null) | ||
334 | { | ||
335 | client.SendImageNotFound(m_requestedUUID); | ||
336 | m_log.WarnFormat("[TEXTURE]: Got null Data element on a asset {0}.. and the missing image Data property is also null", m_requestedUUID); | ||
337 | return true; | ||
338 | } | ||
339 | // Do we have less then 1 packet's worth of data? | ||
340 | else if (m_assetDataLength <= FIRST_PACKET_SIZE) | ||
341 | { | ||
342 | // Send only 1 packet | ||
343 | client.SendImageFirstPart(1, m_requestedUUID, (uint)m_assetDataLength, m_asset.Data, 2); | ||
344 | m_stopPacket = 0; | ||
345 | return true; | ||
346 | } | ||
347 | else | ||
348 | { | ||
349 | byte[] firstImageData = new byte[FIRST_PACKET_SIZE]; | ||
350 | try | ||
351 | { | ||
352 | Buffer.BlockCopy(m_asset.Data, 0, firstImageData, 0, (int)FIRST_PACKET_SIZE); | ||
353 | client.SendImageFirstPart(TexturePacketCount(), m_requestedUUID, (uint)m_assetDataLength, firstImageData, 2); | ||
354 | } | ||
355 | catch (Exception) | ||
356 | { | ||
357 | m_log.Error("Texture block copy failed. Possibly out of memory?"); | ||
358 | return true; | ||
359 | } | ||
360 | } | ||
361 | return false; | ||
362 | } | ||
363 | |||
364 | private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) | 326 | private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) |
365 | { | 327 | { |
366 | m_layers = layers; | 328 | Layers = layers; |
367 | m_decoded = true; | 329 | IsDecoded = true; |
368 | RunUpdate(); | 330 | RunUpdate(); |
369 | } | 331 | } |
370 | 332 | ||
371 | private void AssetDataCallback(UUID AssetID, AssetBase asset) | 333 | private void AssetDataCallback(UUID AssetID, AssetBase asset) |
372 | { | 334 | { |
373 | m_hasasset = true; | 335 | HasAsset = true; |
374 | 336 | ||
375 | if (asset == null || asset.Data == null) | 337 | if (asset == null || asset.Data == null) |
376 | { | 338 | { |
377 | if (m_imageManager.MissingImage != null) | 339 | if (m_imageManager.MissingImage != null) |
378 | { | 340 | { |
379 | m_asset = m_imageManager.MissingImage; | 341 | m_asset = m_imageManager.MissingImage.Data; |
380 | m_assetDataLength = m_asset.Data.Length; | ||
381 | } | 342 | } |
382 | else | 343 | else |
383 | { | 344 | { |
384 | m_asset = null; | 345 | m_asset = null; |
385 | m_decoded = true; | 346 | IsDecoded = true; |
386 | } | 347 | } |
387 | } | 348 | } |
388 | else | 349 | else |
389 | { | 350 | { |
390 | m_asset = asset; | 351 | m_asset = asset.Data; |
391 | m_assetDataLength = m_asset.Data.Length; | ||
392 | } | 352 | } |
393 | 353 | ||
394 | RunUpdate(); | 354 | RunUpdate(); |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index f05c490..43d29fd 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -3131,26 +3131,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3131 | } | 3131 | } |
3132 | } | 3132 | } |
3133 | 3133 | ||
3134 | // Unlike the other timers, this one is only started after | ||
3135 | // the first request is seen. | ||
3136 | |||
3137 | void HandleQueueEmpty(ThrottleOutPacketType queue) | 3134 | void HandleQueueEmpty(ThrottleOutPacketType queue) |
3138 | { | 3135 | { |
3139 | switch (queue) | 3136 | switch (queue) |
3140 | { | 3137 | { |
3141 | case ThrottleOutPacketType.Texture: | 3138 | case ThrottleOutPacketType.Texture: |
3142 | ProcessTextureRequests(); | 3139 | ProcessTextureRequests(); |
3143 | break; | 3140 | break; |
3144 | } | 3141 | } |
3145 | } | 3142 | } |
3146 | 3143 | ||
3147 | void ProcessTextureRequests() | 3144 | void ProcessTextureRequests() |
3148 | { | 3145 | { |
3149 | if (m_imageManager != null) | 3146 | if (m_imageManager != null) |
3150 | { | 3147 | m_imageManager.ProcessImageQueue(m_textureSendLimit, m_textureDataLimit); |
3151 | m_imageManager.ProcessImageQueue(m_textureSendLimit, | ||
3152 | m_textureDataLimit); | ||
3153 | } | ||
3154 | } | 3148 | } |
3155 | 3149 | ||
3156 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) | 3150 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index a484fdf..d641b6c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs | |||
@@ -45,7 +45,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
45 | { | 45 | { |
46 | public int Compare(J2KImage x, J2KImage y) | 46 | public int Compare(J2KImage x, J2KImage y) |
47 | { | 47 | { |
48 | return x.m_requestedPriority.CompareTo(y.m_requestedPriority); | 48 | return x.Priority.CompareTo(y.Priority); |
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
@@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
94 | 94 | ||
95 | // Do a linear search for this texture download | 95 | // Do a linear search for this texture download |
96 | lock (m_priorityQueue) | 96 | lock (m_priorityQueue) |
97 | m_priorityQueue.Find(delegate(J2KImage img) { return img.m_requestedUUID == newRequest.RequestedAssetID; }, out imgrequest); | 97 | m_priorityQueue.Find(delegate(J2KImage img) { return img.TextureID == newRequest.RequestedAssetID; }, out imgrequest); |
98 | 98 | ||
99 | if (imgrequest != null) | 99 | if (imgrequest != null) |
100 | { | 100 | { |
@@ -105,7 +105,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
105 | try | 105 | try |
106 | { | 106 | { |
107 | lock (m_priorityQueue) | 107 | lock (m_priorityQueue) |
108 | m_priorityQueue.Delete(imgrequest.m_priorityQueueHandle); | 108 | m_priorityQueue.Delete(imgrequest.PriorityQueueHandle); |
109 | } | 109 | } |
110 | catch (Exception) { } | 110 | catch (Exception) { } |
111 | } | 111 | } |
@@ -116,29 +116,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
116 | 116 | ||
117 | //Check the packet sequence to make sure this isn't older than | 117 | //Check the packet sequence to make sure this isn't older than |
118 | //one we've already received | 118 | //one we've already received |
119 | if (newRequest.requestSequence > imgrequest.m_lastSequence) | 119 | if (newRequest.requestSequence > imgrequest.LastSequence) |
120 | { | 120 | { |
121 | //Update the sequence number of the last RequestImage packet | 121 | //Update the sequence number of the last RequestImage packet |
122 | imgrequest.m_lastSequence = newRequest.requestSequence; | 122 | imgrequest.LastSequence = newRequest.requestSequence; |
123 | 123 | ||
124 | //Update the requested discard level | 124 | //Update the requested discard level |
125 | imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; | 125 | imgrequest.DiscardLevel = newRequest.DiscardLevel; |
126 | 126 | ||
127 | //Update the requested packet number | 127 | //Update the requested packet number |
128 | imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; | 128 | imgrequest.StartPacket = newRequest.PacketNumber; |
129 | 129 | ||
130 | //Update the requested priority | 130 | //Update the requested priority |
131 | imgrequest.m_requestedPriority = newRequest.Priority; | 131 | imgrequest.Priority = newRequest.Priority; |
132 | try | 132 | try |
133 | { | 133 | { |
134 | lock (m_priorityQueue) | 134 | lock (m_priorityQueue) |
135 | m_priorityQueue.Replace(imgrequest.m_priorityQueueHandle, imgrequest); | 135 | m_priorityQueue.Replace(imgrequest.PriorityQueueHandle, imgrequest); |
136 | } | 136 | } |
137 | catch (Exception) | 137 | catch (Exception) |
138 | { | 138 | { |
139 | imgrequest.m_priorityQueueHandle = null; | 139 | imgrequest.PriorityQueueHandle = null; |
140 | lock (m_priorityQueue) | 140 | lock (m_priorityQueue) |
141 | m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest); | 141 | m_priorityQueue.Add(ref imgrequest.PriorityQueueHandle, imgrequest); |
142 | } | 142 | } |
143 | 143 | ||
144 | //Run an update | 144 | //Run an update |
@@ -161,29 +161,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
161 | imgrequest = new J2KImage(this); | 161 | imgrequest = new J2KImage(this); |
162 | 162 | ||
163 | //Assign our decoder module | 163 | //Assign our decoder module |
164 | imgrequest.m_j2kDecodeModule = m_j2kDecodeModule; | 164 | imgrequest.J2KDecoder = m_j2kDecodeModule; |
165 | 165 | ||
166 | //Assign our asset cache module | 166 | //Assign our asset cache module |
167 | imgrequest.m_assetCache = m_assetCache; | 167 | imgrequest.AssetService = m_assetCache; |
168 | 168 | ||
169 | //Assign the requested discard level | 169 | //Assign the requested discard level |
170 | imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; | 170 | imgrequest.DiscardLevel = newRequest.DiscardLevel; |
171 | 171 | ||
172 | //Assign the requested packet number | 172 | //Assign the requested packet number |
173 | imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; | 173 | imgrequest.StartPacket = newRequest.PacketNumber; |
174 | 174 | ||
175 | //Assign the requested priority | 175 | //Assign the requested priority |
176 | imgrequest.m_requestedPriority = newRequest.Priority; | 176 | imgrequest.Priority = newRequest.Priority; |
177 | 177 | ||
178 | //Assign the asset uuid | 178 | //Assign the asset uuid |
179 | imgrequest.m_requestedUUID = newRequest.RequestedAssetID; | 179 | imgrequest.TextureID = newRequest.RequestedAssetID; |
180 | 180 | ||
181 | //Assign the requested priority | 181 | //Assign the requested priority |
182 | imgrequest.m_requestedPriority = newRequest.Priority; | 182 | imgrequest.Priority = newRequest.Priority; |
183 | 183 | ||
184 | //Add this download to the priority queue | 184 | //Add this download to the priority queue |
185 | lock (m_priorityQueue) | 185 | lock (m_priorityQueue) |
186 | m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest); | 186 | m_priorityQueue.Add(ref imgrequest.PriorityQueueHandle, imgrequest); |
187 | 187 | ||
188 | //Run an update | 188 | //Run an update |
189 | imgrequest.RunUpdate(); | 189 | imgrequest.RunUpdate(); |
@@ -249,12 +249,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
249 | lock (m_priorityQueue) | 249 | lock (m_priorityQueue) |
250 | imagereq = m_priorityQueue.FindMax(); | 250 | imagereq = m_priorityQueue.FindMax(); |
251 | 251 | ||
252 | if (imagereq.m_decoded == true) | 252 | if (imagereq.IsDecoded == true) |
253 | { | 253 | { |
254 | // we need to test this here now that we are dropping assets | 254 | // we need to test this here now that we are dropping assets |
255 | if (!imagereq.m_hasasset) | 255 | if (!imagereq.HasAsset) |
256 | { | 256 | { |
257 | m_log.WarnFormat("[LLIMAGE MANAGER]: Re-requesting the image asset {0}", imagereq.m_requestedUUID); | 257 | m_log.WarnFormat("[LLIMAGE MANAGER]: Re-requesting the image asset {0}", imagereq.TextureID); |
258 | imagereq.RunUpdate(); | 258 | imagereq.RunUpdate(); |
259 | continue; | 259 | continue; |
260 | } | 260 | } |
@@ -268,7 +268,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
268 | try | 268 | try |
269 | { | 269 | { |
270 | lock (m_priorityQueue) | 270 | lock (m_priorityQueue) |
271 | m_priorityQueue.Delete(imagereq.m_priorityQueueHandle); | 271 | m_priorityQueue.Delete(imagereq.PriorityQueueHandle); |
272 | } | 272 | } |
273 | catch (Exception) { } | 273 | catch (Exception) { } |
274 | } | 274 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs index 37f6ca7..e98a360 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketHandler.cs | |||
@@ -776,10 +776,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
776 | { | 776 | { |
777 | QueueEmpty handlerQueueEmpty = OnQueueEmpty; | 777 | QueueEmpty handlerQueueEmpty = OnQueueEmpty; |
778 | 778 | ||
779 | if (handlerQueueEmpty == null) | 779 | if (handlerQueueEmpty != null) |
780 | return; | 780 | handlerQueueEmpty(queue); |
781 | |||
782 | handlerQueueEmpty(queue); | ||
783 | } | 781 | } |
784 | 782 | ||
785 | // Convert the packet to bytes and stuff it onto the send queue | 783 | // Convert the packet to bytes and stuff it onto the send queue |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs index 8484846..0f1acb1 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketQueue.cs | |||
@@ -273,55 +273,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
273 | { | 273 | { |
274 | lock (this) | 274 | lock (this) |
275 | { | 275 | { |
276 | while (PacketsWaiting()) | 276 | // These categories do not contain transactional packets so we can safely drop any pending data in them |
277 | LandOutgoingPacketQueue.Clear(); | ||
278 | WindOutgoingPacketQueue.Clear(); | ||
279 | CloudOutgoingPacketQueue.Clear(); | ||
280 | TextureOutgoingPacketQueue.Clear(); | ||
281 | AssetOutgoingPacketQueue.Clear(); | ||
282 | |||
283 | // Now comes the fun part.. we dump all remaining resend and task packets into the send queue | ||
284 | while (ResendOutgoingPacketQueue.Count > 0 || TaskOutgoingPacketQueue.Count > 0 || TaskLowpriorityPacketQueue.Count > 0) | ||
277 | { | 285 | { |
278 | //Now comes the fun part.. we dump all our elements into m_packetQueue that we've saved up. | ||
279 | if (ResendOutgoingPacketQueue.Count > 0) | 286 | if (ResendOutgoingPacketQueue.Count > 0) |
280 | { | ||
281 | SendQueue.Enqueue(ResendOutgoingPacketQueue.Dequeue()); | 287 | SendQueue.Enqueue(ResendOutgoingPacketQueue.Dequeue()); |
282 | } | 288 | |
283 | if (LandOutgoingPacketQueue.Count > 0) | ||
284 | { | ||
285 | SendQueue.Enqueue(LandOutgoingPacketQueue.Dequeue()); | ||
286 | TriggerOnQueueEmpty(ThrottleOutPacketType.Land); | ||
287 | } | ||
288 | if (WindOutgoingPacketQueue.Count > 0) | ||
289 | { | ||
290 | SendQueue.Enqueue(WindOutgoingPacketQueue.Dequeue()); | ||
291 | TriggerOnQueueEmpty(ThrottleOutPacketType.Wind); | ||
292 | } | ||
293 | if (CloudOutgoingPacketQueue.Count > 0) | ||
294 | { | ||
295 | SendQueue.Enqueue(CloudOutgoingPacketQueue.Dequeue()); | ||
296 | TriggerOnQueueEmpty(ThrottleOutPacketType.Cloud); | ||
297 | } | ||
298 | bool tasksSent = false; | ||
299 | if (TaskOutgoingPacketQueue.Count > 0) | 289 | if (TaskOutgoingPacketQueue.Count > 0) |
300 | { | ||
301 | tasksSent = true; | ||
302 | SendQueue.PriorityEnqueue(TaskOutgoingPacketQueue.Dequeue()); | 290 | SendQueue.PriorityEnqueue(TaskOutgoingPacketQueue.Dequeue()); |
303 | } | 291 | |
304 | if (TaskLowpriorityPacketQueue.Count > 0) | 292 | if (TaskLowpriorityPacketQueue.Count > 0) |
305 | { | ||
306 | tasksSent = true; | ||
307 | SendQueue.Enqueue(TaskLowpriorityPacketQueue.Dequeue()); | 293 | SendQueue.Enqueue(TaskLowpriorityPacketQueue.Dequeue()); |
308 | } | ||
309 | if (tasksSent) | ||
310 | { | ||
311 | TriggerOnQueueEmpty(ThrottleOutPacketType.Task); | ||
312 | } | ||
313 | if (TextureOutgoingPacketQueue.Count > 0) | ||
314 | { | ||
315 | SendQueue.Enqueue(TextureOutgoingPacketQueue.Dequeue()); | ||
316 | TriggerOnQueueEmpty(ThrottleOutPacketType.Texture); | ||
317 | } | ||
318 | if (AssetOutgoingPacketQueue.Count > 0) | ||
319 | { | ||
320 | SendQueue.Enqueue(AssetOutgoingPacketQueue.Dequeue()); | ||
321 | TriggerOnQueueEmpty(ThrottleOutPacketType.Asset); | ||
322 | } | ||
323 | } | 294 | } |
324 | // m_log.Info("[THROTTLE]: Processed " + throttleLoops + " packets"); | ||
325 | } | 295 | } |
326 | } | 296 | } |
327 | 297 | ||
@@ -530,10 +500,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
530 | { | 500 | { |
531 | QueueEmpty handlerQueueEmpty = OnQueueEmpty; | 501 | QueueEmpty handlerQueueEmpty = OnQueueEmpty; |
532 | 502 | ||
533 | if (handlerQueueEmpty == null) | 503 | if (handlerQueueEmpty != null) |
534 | return; | 504 | handlerQueueEmpty(queue); |
535 | |||
536 | handlerQueueEmpty(queue); | ||
537 | } | 505 | } |
538 | 506 | ||
539 | private void ThrottleTimerElapsed(object sender, ElapsedEventArgs e) | 507 | private void ThrottleTimerElapsed(object sender, ElapsedEventArgs e) |