aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
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/LindenUDP/LLImageManager.cs
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/LindenUDP/LLImageManager.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs153
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