diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs | 153 |
1 files changed, 102 insertions, 51 deletions
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 | ||