aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
diff options
context:
space:
mode:
authorDr Scofield2009-06-25 07:42:06 +0000
committerDr Scofield2009-06-25 07:42:06 +0000
commitafd5f76648740b80fdfe6cfdfca82e3def5baf03 (patch)
tree1adbd4b99be8e3c1fc0f38dcb4de08283f6d0f9d /OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
parent- fixes a "collection out of sync" exception in the ODE physics (diff)
downloadopensim-SC_OLD-afd5f76648740b80fdfe6cfdfca82e3def5baf03.zip
opensim-SC_OLD-afd5f76648740b80fdfe6cfdfca82e3def5baf03.tar.gz
opensim-SC_OLD-afd5f76648740b80fdfe6cfdfca82e3def5baf03.tar.bz2
opensim-SC_OLD-afd5f76648740b80fdfe6cfdfca82e3def5baf03.tar.xz
From: Alan Webb <alan_webb@us.ibm.com>
This change moves texture send processing out of the main packet processing loop and moves it to a timer based processing cycle. Texture packets are sent to the client consistently over time. The timer is discontinued whenever there are no textures to transmit. The behavior of the texture sending mechanism is controlled by three variables in the LLCLient section of the config file: [1] TextureRequestRate (mS) determines how many times per second texture send processing will occur. The default is 100mS. [2] TextureSendLimit determines how many different textures will be considered on each cycle. Textures are selected by priority. The old mechanism specified a value of 10 for this parameter and this is the default [3] TextureDataLimit determines how many packets will be sent for each of the selected textures. The old mechanism specified a value of 5, so this is the default. So the net effect is that TextureSendLimit*TextureDataLimit packets will be sent every TextureRequestRate mS. Once we have gotten a reasonable feeling for how these parameters affect overall processing, it would be nice to autonmically manage these values using information about the current status of the region and network. Note that this also resolves the pathologcal problem that previously existed which was that a seated avatar generated very few in-bound packets (theoretically) and would therefore be the least able to retrieve the images being displayed by a projector script.
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs81
1 files changed, 37 insertions, 44 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
index 587579d..295a5e6 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Threading;
29using System.Collections.Generic; 30using System.Collections.Generic;
30using OpenMetaverse; 31using OpenMetaverse;
31using OpenMetaverse.Imaging; 32using OpenMetaverse.Imaging;
@@ -96,46 +97,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP
96 97
97 J2KImage imgrequest = m_imagestore[newRequest.RequestedAssetID]; 98 J2KImage imgrequest = m_imagestore[newRequest.RequestedAssetID];
98 99
100 // This is the inbound request sequence number. We can ignore
101 // "old" ones.
102
99 if (newRequest.requestSequence > imgrequest.m_lastSequence) 103 if (newRequest.requestSequence > imgrequest.m_lastSequence)
100 { 104 {
105
101 imgrequest.m_lastSequence = newRequest.requestSequence; 106 imgrequest.m_lastSequence = newRequest.requestSequence;
102 107
103 //First of all, is this being killed? 108 //Check the priority
104 //if (newRequest.Priority == 0.0f && newRequest.DiscardLevel == -1)
105 //{
106 //Do nothing (leaving the if for future use)
107 //}
108 //else
109 //{
110 109
110 double priority = imgrequest.m_requestedPriority;
111 if (priority != newRequest.Priority)
112 {
113 //Remove the old priority
114 m_priorities.Remove(imgrequest.m_designatedPriorityKey);
115 //Assign a new unique priority
116 imgrequest.m_requestedPriority = newRequest.Priority;
117 imgrequest.m_designatedPriorityKey = AssignPriority(newRequest.RequestedAssetID, newRequest.Priority);
118 }
111 119
112 //Check the priority 120 //Update the requested discard level
113 double priority = imgrequest.m_requestedPriority; 121 imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel;
114 if (priority != newRequest.Priority)
115 {
116 //Remove the old priority
117 m_priorities.Remove(imgrequest.m_designatedPriorityKey);
118 //Assign a new unique priority
119 imgrequest.m_requestedPriority = newRequest.Priority;
120 imgrequest.m_designatedPriorityKey = AssignPriority(newRequest.RequestedAssetID, newRequest.Priority);
121 }
122 122
123 //Update the requested discard level 123 //Update the requested packet number
124 imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; 124 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber;
125 125
126 //Update the requested packet number 126 //Check if this will create an outstanding texture request
127 imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; 127 bool activated = imgrequest.m_completedSendAtCurrentDiscardLevel;
128 //Run an update
128 129
129 //Check if this will create an outstanding texture request 130 imgrequest.RunUpdate();
130 bool activated = imgrequest.m_completedSendAtCurrentDiscardLevel;
131 //Run an update
132 imgrequest.RunUpdate();
133 if (activated && !imgrequest.m_completedSendAtCurrentDiscardLevel && imgrequest.m_decoded)
134 {
135 m_outstandingtextures++;
136 }
137 131
138 //} 132 if (activated && !imgrequest.m_completedSendAtCurrentDiscardLevel && imgrequest.m_decoded)
133 {
134 Interlocked.Increment(ref m_outstandingtextures);
135 }
139 } 136 }
140 } 137 }
141 else 138 else
@@ -198,10 +195,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
198 195
199 } 196 }
200 197
201 public void ProcessImageQueue(int count) 198 public bool ProcessImageQueue(int count, int maxpack)
202 { 199 {
200
203 // this can happen during Close() 201 // this can happen during Close()
204 if (m_client == null) return; 202 if (m_client == null)
203 return false;
205 204
206 //Count is the number of textures we want to process in one go. 205 //Count is the number of textures we want to process in one go.
207 //As part of this class re-write, that number will probably rise 206 //As part of this class re-write, that number will probably rise
@@ -214,7 +213,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
214 if (m_lastloopprocessed == 0) 213 if (m_lastloopprocessed == 0)
215 { 214 {
216 if (m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null || m_client.PacketHandler.PacketQueue.TextureThrottle == null) 215 if (m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null || m_client.PacketHandler.PacketQueue.TextureThrottle == null)
217 return; 216 return false;
218 //This is decent for a semi fast machine, but we'll calculate it more accurately based on time below 217 //This is decent for a semi fast machine, but we'll calculate it more accurately based on time below
219 threshold = m_client.PacketHandler.PacketQueue.TextureThrottle.Current / 6300; 218 threshold = m_client.PacketHandler.PacketQueue.TextureThrottle.Current / 6300;
220 m_lastloopprocessed = DateTime.Now.Ticks; 219 m_lastloopprocessed = DateTime.Now.Ticks;
@@ -239,10 +238,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
239 } 238 }
240 239
241 if (m_client.PacketHandler == null) 240 if (m_client.PacketHandler == null)
242 return; 241 return false;
243 242
244 if (m_client.PacketHandler.PacketQueue == null) 243 if (m_client.PacketHandler.PacketQueue == null)
245 return; 244 return false;
246 245
247 //First of all make sure our packet queue isn't above our threshold 246 //First of all make sure our packet queue isn't above our threshold
248 247
@@ -252,24 +251,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
252 { 251 {
253 bool justreset = false; 252 bool justreset = false;
254 253
255
256
257 for (int x = m_priorities.Count - 1; x > -1; x--) 254 for (int x = m_priorities.Count - 1; x > -1; x--)
258 { 255 {
259 256
260 J2KImage imagereq = m_imagestore[m_priorities.Values[x]]; 257 J2KImage imagereq = m_imagestore[m_priorities.Values[x]];
261 if (imagereq.m_decoded == true && !imagereq.m_completedSendAtCurrentDiscardLevel) 258 if (imagereq.m_decoded == true && !imagereq.m_completedSendAtCurrentDiscardLevel)
262 { 259 {
263
264 numCollected++; 260 numCollected++;
265 //SendPackets will send up to ten packets per cycle 261 //SendPackets will send up to ten packets per cycle
266 if (imagereq.SendPackets(m_client)) 262 if (imagereq.SendPackets(m_client, maxpack))
267 { 263 {
268 //Send complete 264 //Send complete
269 if (!imagereq.m_completedSendAtCurrentDiscardLevel) 265 if (!imagereq.m_completedSendAtCurrentDiscardLevel)
270 { 266 {
271 imagereq.m_completedSendAtCurrentDiscardLevel = true; 267 imagereq.m_completedSendAtCurrentDiscardLevel = true;
272 m_outstandingtextures--; 268 Interlocked.Decrement(ref m_outstandingtextures);
273 //Re-assign priority to bottom 269 //Re-assign priority to bottom
274 //Remove the old priority 270 //Remove the old priority
275 m_priorities.Remove(imagereq.m_designatedPriorityKey); 271 m_priorities.Remove(imagereq.m_designatedPriorityKey);
@@ -310,13 +306,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
310 306
311 justreset = true; //prevents us from getting stuck in a loop 307 justreset = true; //prevents us from getting stuck in a loop
312 } 308 }
313
314
315 } 309 }
316 } 310 }
317 311
318 312 return m_outstandingtextures != 0;
319
320 } 313 }
321 314
322 //Faux destructor 315 //Faux destructor