diff options
author | Dr Scofield | 2009-06-25 07:42:06 +0000 |
---|---|---|
committer | Dr Scofield | 2009-06-25 07:42:06 +0000 |
commit | afd5f76648740b80fdfe6cfdfca82e3def5baf03 (patch) | |
tree | 1adbd4b99be8e3c1fc0f38dcb4de08283f6d0f9d /OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs | |
parent | - fixes a "collection out of sync" exception in the ODE physics (diff) | |
download | opensim-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.cs | 81 |
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 | ||
28 | using System; | 28 | using System; |
29 | using System.Threading; | ||
29 | using System.Collections.Generic; | 30 | using System.Collections.Generic; |
30 | using OpenMetaverse; | 31 | using OpenMetaverse; |
31 | using OpenMetaverse.Imaging; | 32 | using 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 |