diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs | 135 |
1 files changed, 112 insertions, 23 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs index e3a881f..073c357 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs | |||
@@ -55,18 +55,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
55 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 55 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
56 | private bool m_shuttingdown; | 56 | private bool m_shuttingdown; |
57 | private AssetBase m_missingImage; | 57 | private AssetBase m_missingImage; |
58 | private LLClientView m_client; //Client we're assigned to | 58 | private IAssetService m_assetCache; |
59 | private IAssetService m_assetCache; //Asset Cache | 59 | private IJ2KDecoder m_j2kDecodeModule; |
60 | private IJ2KDecoder m_j2kDecodeModule; //Our J2K module | 60 | |
61 | /// <summary> | ||
62 | /// Priority queue for determining which image to send first. | ||
63 | /// </summary> | ||
61 | private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer()); | 64 | private C5.IntervalHeap<J2KImage> m_priorityQueue = new C5.IntervalHeap<J2KImage>(10, new J2KImageComparer()); |
65 | |||
66 | /// <summary> | ||
67 | /// Used to control thread access to the priority queue. | ||
68 | /// </summary> | ||
62 | private object m_syncRoot = new object(); | 69 | private object m_syncRoot = new object(); |
63 | 70 | ||
64 | public LLClientView Client { get { return m_client; } } | 71 | /// <summary> |
72 | /// Client served by this image manager | ||
73 | /// </summary> | ||
74 | public IClientAPI Client { get; private set; } | ||
75 | |||
65 | public AssetBase MissingImage { get { return m_missingImage; } } | 76 | public AssetBase MissingImage { get { return m_missingImage; } } |
66 | 77 | ||
67 | public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule) | 78 | public LLImageManager(IClientAPI client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule) |
68 | { | 79 | { |
69 | m_client = client; | 80 | Client = client; |
70 | m_assetCache = pAssetCache; | 81 | m_assetCache = pAssetCache; |
71 | 82 | ||
72 | if (pAssetCache != null) | 83 | if (pAssetCache != null) |
@@ -84,7 +95,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
84 | /// <param name="newRequest"></param> | 95 | /// <param name="newRequest"></param> |
85 | public void EnqueueReq(TextureRequestArgs newRequest) | 96 | public void EnqueueReq(TextureRequestArgs newRequest) |
86 | { | 97 | { |
87 | //Make sure we're not shutting down.. | ||
88 | if (!m_shuttingdown) | 98 | if (!m_shuttingdown) |
89 | { | 99 | { |
90 | J2KImage imgrequest; | 100 | J2KImage imgrequest; |
@@ -99,19 +109,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
99 | { | 109 | { |
100 | //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID); | 110 | //m_log.Debug("[TEX]: (CAN) ID=" + newRequest.RequestedAssetID); |
101 | 111 | ||
102 | try | 112 | try |
103 | { | 113 | { |
104 | lock (m_syncRoot) | 114 | lock (m_syncRoot) |
105 | m_priorityQueue.Delete(imgrequest.PriorityQueueHandle); | 115 | m_priorityQueue.Delete(imgrequest.PriorityQueueHandle); |
106 | } | 116 | } |
107 | catch (Exception) { } | 117 | catch (Exception) { } |
108 | } | 118 | } |
109 | else | 119 | else |
110 | { | 120 | { |
111 | //m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}", | 121 | // m_log.DebugFormat( |
112 | // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); | 122 | // "[LL IMAGE MANAGER]: Received duplicate of existing request for {0}, start packet {1} from {2}", |
123 | // newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name); | ||
124 | |||
125 | // m_log.DebugFormat("[TEX]: (UPD) ID={0}: D={1}, S={2}, P={3}", | ||
126 | // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); | ||
113 | 127 | ||
114 | //Check the packet sequence to make sure this isn't older than | 128 | //Check the packet sequence to make sure this isn't older than |
115 | //one we've already received | 129 | //one we've already received |
116 | if (newRequest.requestSequence > imgrequest.LastSequence) | 130 | if (newRequest.requestSequence > imgrequest.LastSequence) |
117 | { | 131 | { |
@@ -126,11 +140,34 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
126 | 140 | ||
127 | //Update the requested priority | 141 | //Update the requested priority |
128 | imgrequest.Priority = newRequest.Priority; | 142 | imgrequest.Priority = newRequest.Priority; |
143 | |||
129 | UpdateImageInQueue(imgrequest); | 144 | UpdateImageInQueue(imgrequest); |
130 | 145 | ||
131 | //Run an update | ||
132 | imgrequest.RunUpdate(); | 146 | imgrequest.RunUpdate(); |
147 | |||
148 | // J2KImage imgrequest2 = new J2KImage(this); | ||
149 | // imgrequest2.J2KDecoder = m_j2kDecodeModule; | ||
150 | // imgrequest2.AssetService = m_assetCache; | ||
151 | // imgrequest2.AgentID = m_client.AgentId; | ||
152 | // imgrequest2.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>(); | ||
153 | // imgrequest2.DiscardLevel = newRequest.DiscardLevel; | ||
154 | // imgrequest2.StartPacket = Math.Max(1, newRequest.PacketNumber); | ||
155 | // imgrequest2.Priority = newRequest.Priority; | ||
156 | // imgrequest2.TextureID = newRequest.RequestedAssetID; | ||
157 | // imgrequest2.Priority = newRequest.Priority; | ||
158 | // | ||
159 | // //Add this download to the priority queue | ||
160 | // AddImageToQueue(imgrequest2); | ||
161 | // | ||
162 | // imgrequest2.RunUpdate(); | ||
163 | |||
133 | } | 164 | } |
165 | // else | ||
166 | // { | ||
167 | // m_log.DebugFormat( | ||
168 | // "[LL IMAGE MANAGER]: Ignoring duplicate of existing request for {0} (sequence {1}) from {2} as its request sequence {3} is not greater", | ||
169 | // newRequest.RequestedAssetID, imgrequest.LastSequence, m_client.Name, newRequest.requestSequence); | ||
170 | // } | ||
134 | } | 171 | } |
135 | } | 172 | } |
136 | else | 173 | else |
@@ -142,14 +179,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
142 | } | 179 | } |
143 | else | 180 | else |
144 | { | 181 | { |
182 | // m_log.DebugFormat( | ||
183 | // "[LL IMAGE MANAGER]: Received request for {0}, start packet {1} from {2}", | ||
184 | // newRequest.RequestedAssetID, newRequest.PacketNumber, m_client.Name); | ||
185 | |||
145 | //m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}", | 186 | //m_log.DebugFormat("[TEX]: (NEW) ID={0}: D={1}, S={2}, P={3}", |
146 | // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); | 187 | // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); |
147 | 188 | ||
148 | imgrequest = new J2KImage(this); | 189 | imgrequest = new J2KImage(this); |
149 | imgrequest.J2KDecoder = m_j2kDecodeModule; | 190 | imgrequest.J2KDecoder = m_j2kDecodeModule; |
150 | imgrequest.AssetService = m_assetCache; | 191 | imgrequest.AssetService = m_assetCache; |
151 | imgrequest.AgentID = m_client.AgentId; | 192 | imgrequest.AgentID = Client.AgentId; |
152 | imgrequest.InventoryAccessModule = m_client.Scene.RequestModuleInterface<IInventoryAccessModule>(); | 193 | imgrequest.InventoryAccessModule = Client.Scene.RequestModuleInterface<IInventoryAccessModule>(); |
153 | imgrequest.DiscardLevel = newRequest.DiscardLevel; | 194 | imgrequest.DiscardLevel = newRequest.DiscardLevel; |
154 | imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber); | 195 | imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber); |
155 | imgrequest.Priority = newRequest.Priority; | 196 | imgrequest.Priority = newRequest.Priority; |
@@ -159,7 +200,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
159 | //Add this download to the priority queue | 200 | //Add this download to the priority queue |
160 | AddImageToQueue(imgrequest); | 201 | AddImageToQueue(imgrequest); |
161 | 202 | ||
162 | //Run an update | ||
163 | imgrequest.RunUpdate(); | 203 | imgrequest.RunUpdate(); |
164 | } | 204 | } |
165 | } | 205 | } |
@@ -176,12 +216,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
176 | 216 | ||
177 | // If null was returned, the texture priority queue is currently empty | 217 | // If null was returned, the texture priority queue is currently empty |
178 | if (image == null) | 218 | if (image == null) |
179 | return false; | 219 | break; |
180 | 220 | ||
181 | if (image.IsDecoded) | 221 | if (image.IsDecoded) |
182 | { | 222 | { |
183 | int sent; | 223 | int sent; |
184 | bool imageDone = image.SendPackets(m_client, packetsToSend - packetsSent, out sent); | 224 | bool imageDone = image.SendPackets(Client, packetsToSend - packetsSent, out sent); |
185 | packetsSent += sent; | 225 | packetsSent += sent; |
186 | 226 | ||
187 | // If the send is complete, destroy any knowledge of this transfer | 227 | // If the send is complete, destroy any knowledge of this transfer |
@@ -194,10 +234,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
194 | // written. Undecoded textures should not be going into the priority | 234 | // written. Undecoded textures should not be going into the priority |
195 | // queue, because a high priority undecoded texture will clog up the | 235 | // queue, because a high priority undecoded texture will clog up the |
196 | // pipeline for a client | 236 | // pipeline for a client |
197 | return true; | 237 | // m_log.DebugFormat( |
238 | // "[LL IMAGE MANAGER]: Exiting image queue processing early on encountering undecoded image {0}", | ||
239 | // image.TextureID); | ||
240 | |||
241 | break; | ||
198 | } | 242 | } |
199 | } | 243 | } |
200 | 244 | ||
245 | // if (packetsSent != 0) | ||
246 | // m_log.DebugFormat("[LL IMAGE MANAGER]: Processed {0} packets from image queue", packetsSent); | ||
247 | |||
201 | return m_priorityQueue.Count > 0; | 248 | return m_priorityQueue.Count > 0; |
202 | } | 249 | } |
203 | 250 | ||
@@ -209,6 +256,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
209 | m_shuttingdown = true; | 256 | m_shuttingdown = true; |
210 | } | 257 | } |
211 | 258 | ||
259 | /// <summary> | ||
260 | /// Clear the image queue. | ||
261 | /// </summary> | ||
262 | /// <returns>The number of requests cleared.</returns> | ||
263 | public int ClearImageQueue() | ||
264 | { | ||
265 | int requestsDeleted; | ||
266 | |||
267 | lock (m_priorityQueue) | ||
268 | { | ||
269 | requestsDeleted = m_priorityQueue.Count; | ||
270 | |||
271 | // Surprisingly, there doesn't seem to be a clear method at this time. | ||
272 | while (!m_priorityQueue.IsEmpty) | ||
273 | m_priorityQueue.DeleteMax(); | ||
274 | } | ||
275 | |||
276 | return requestsDeleted; | ||
277 | } | ||
278 | |||
279 | /// <summary> | ||
280 | /// Returns an array containing all the images in the queue. | ||
281 | /// </summary> | ||
282 | /// <returns></returns> | ||
283 | public J2KImage[] GetImages() | ||
284 | { | ||
285 | lock (m_priorityQueue) | ||
286 | return m_priorityQueue.ToArray(); | ||
287 | } | ||
288 | |||
212 | #region Priority Queue Helpers | 289 | #region Priority Queue Helpers |
213 | 290 | ||
214 | private J2KImage GetHighestPriorityImage() | 291 | private J2KImage GetHighestPriorityImage() |
@@ -219,7 +296,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
219 | { | 296 | { |
220 | if (m_priorityQueue.Count > 0) | 297 | if (m_priorityQueue.Count > 0) |
221 | { | 298 | { |
222 | try { image = m_priorityQueue.FindMax(); } | 299 | try |
300 | { | ||
301 | image = m_priorityQueue.FindMax(); | ||
302 | } | ||
223 | catch (Exception) { } | 303 | catch (Exception) { } |
224 | } | 304 | } |
225 | } | 305 | } |
@@ -232,7 +312,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
232 | 312 | ||
233 | lock (m_syncRoot) | 313 | lock (m_syncRoot) |
234 | { | 314 | { |
235 | try { m_priorityQueue.Add(ref image.PriorityQueueHandle, image); } | 315 | try |
316 | { | ||
317 | m_priorityQueue.Add(ref image.PriorityQueueHandle, image); | ||
318 | } | ||
236 | catch (Exception) { } | 319 | catch (Exception) { } |
237 | } | 320 | } |
238 | } | 321 | } |
@@ -241,7 +324,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
241 | { | 324 | { |
242 | lock (m_syncRoot) | 325 | lock (m_syncRoot) |
243 | { | 326 | { |
244 | try { m_priorityQueue.Delete(image.PriorityQueueHandle); } | 327 | try |
328 | { | ||
329 | m_priorityQueue.Delete(image.PriorityQueueHandle); | ||
330 | } | ||
245 | catch (Exception) { } | 331 | catch (Exception) { } |
246 | } | 332 | } |
247 | } | 333 | } |
@@ -250,7 +336,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
250 | { | 336 | { |
251 | lock (m_syncRoot) | 337 | lock (m_syncRoot) |
252 | { | 338 | { |
253 | try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); } | 339 | try |
340 | { | ||
341 | m_priorityQueue.Replace(image.PriorityQueueHandle, image); | ||
342 | } | ||
254 | catch (Exception) | 343 | catch (Exception) |
255 | { | 344 | { |
256 | image.PriorityQueueHandle = null; | 345 | image.PriorityQueueHandle = null; |