aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLImageManager.cs135
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;