aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Services/MapImageService/MapImageService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Services/MapImageService/MapImageService.cs')
-rw-r--r--OpenSim/Services/MapImageService/MapImageService.cs82
1 files changed, 66 insertions, 16 deletions
diff --git a/OpenSim/Services/MapImageService/MapImageService.cs b/OpenSim/Services/MapImageService/MapImageService.cs
index 31e147b..0e425f8 100644
--- a/OpenSim/Services/MapImageService/MapImageService.cs
+++ b/OpenSim/Services/MapImageService/MapImageService.cs
@@ -36,6 +36,7 @@ using System.Drawing.Imaging;
36using System.IO; 36using System.IO;
37using System.Net; 37using System.Net;
38using System.Reflection; 38using System.Reflection;
39using System.Threading;
39 40
40using Nini.Config; 41using Nini.Config;
41using log4net; 42using log4net;
@@ -53,6 +54,7 @@ namespace OpenSim.Services.MapImageService
53 private static readonly ILog m_log = 54 private static readonly ILog m_log =
54 LogManager.GetLogger( 55 LogManager.GetLogger(
55 MethodBase.GetCurrentMethod().DeclaringType); 56 MethodBase.GetCurrentMethod().DeclaringType);
57 private string LogHeader = "[MAP IMAGE SERVICE]";
56 58
57 private const int ZOOM_LEVELS = 8; 59 private const int ZOOM_LEVELS = 8;
58 private const int IMAGE_WIDTH = 256; 60 private const int IMAGE_WIDTH = 256;
@@ -114,7 +116,7 @@ namespace OpenSim.Services.MapImageService
114 } 116 }
115 } 117 }
116 118
117 return UpdateMultiResolutionFiles(x, y, out reason); 119 return UpdateMultiResolutionFilesAsync(x, y, out reason);
118 } 120 }
119 121
120 public bool RemoveMapTile(int x, int y, out string reason) 122 public bool RemoveMapTile(int x, int y, out string reason)
@@ -136,33 +138,81 @@ namespace OpenSim.Services.MapImageService
136 } 138 }
137 } 139 }
138 140
139 return UpdateMultiResolutionFiles(x, y, out reason); 141 return UpdateMultiResolutionFilesAsync(x, y, out reason);
140 } 142 }
141 143
142 private bool UpdateMultiResolutionFiles(int x, int y, out string reason) 144 // When large varregions start up, they can send piles of new map tiles. This causes
145 // this multi-resolution routine to be called a zillion times an causes much CPU
146 // time to be spent creating multi-resolution tiles that will be replaced when
147 // the next maptile arrives.
148 private class mapToMultiRez
149 {
150 public int xx;
151 public int yy;
152 public mapToMultiRez(int pX, int pY)
153 {
154 xx = pX;
155 yy = pY;
156 }
157 };
158 private Queue<mapToMultiRez> multiRezToBuild = new Queue<mapToMultiRez>();
159 private bool UpdateMultiResolutionFilesAsync(int x, int y, out string reason)
143 { 160 {
144 reason = String.Empty; 161 reason = String.Empty;
145 lock (m_Sync) 162 lock (multiRezToBuild)
146 { 163 {
147 // Stitch seven more aggregate tiles together 164 // m_log.DebugFormat("{0} UpdateMultiResolutionFilesAsync: scheduling update for <{1},{2}>", LogHeader, x, y);
148 for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++) 165 multiRezToBuild.Enqueue(new mapToMultiRez(x, y));
166 if (multiRezToBuild.Count == 1)
167 Util.FireAndForget(DoUpdateMultiResolutionFilesAsync);
168 }
169
170 return true;
171 }
172
173 private void DoUpdateMultiResolutionFilesAsync(object o)
174 {
175 // This sleep causes the FireAndForget thread to be different than the invocation thread.
176 // It also allows other tiles to be uploaded so the multi-rez images are more likely
177 // to be correct.
178 Thread.Sleep(1 * 1000);
179
180 while (multiRezToBuild.Count > 0)
181 {
182 mapToMultiRez toMultiRez = null;
183 lock (multiRezToBuild)
149 { 184 {
150 // Calculate the width (in full resolution tiles) and bottom-left 185 if (multiRezToBuild.Count > 0)
151 // corner of the current zoom level 186 toMultiRez = multiRezToBuild.Dequeue();
152 int width = (int)Math.Pow(2, (double)(zoomLevel - 1)); 187 }
153 int x1 = x - (x % width); 188 if (toMultiRez != null)
154 int y1 = y - (y % width); 189 {
190 int x = toMultiRez.xx;
191 int y = toMultiRez.yy;
192 // m_log.DebugFormat("{0} DoUpdateMultiResolutionFilesAsync: doing build for <{1},{2}>", LogHeader, x, y);
155 193
156 if (!CreateTile(zoomLevel, x1, y1)) 194 // Stitch seven more aggregate tiles together
195 for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++)
157 { 196 {
158 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0},{1} at zoom level {1}", x, y, zoomLevel); 197 // Calculate the width (in full resolution tiles) and bottom-left
159 reason = string.Format("Map tile at zoom level {0} failed", zoomLevel); 198 // corner of the current zoom level
160 return false; 199 int width = (int)Math.Pow(2, (double)(zoomLevel - 1));
200 int x1 = x - (x % width);
201 int y1 = y - (y % width);
202
203 lock (m_Sync) // must lock the reading and writing of the maptile files
204 {
205 if (!CreateTile(zoomLevel, x1, y1))
206 {
207 m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0},{1} at zoom level {1}", x, y, zoomLevel);
208 return;
209 }
210 }
161 } 211 }
162 } 212 }
163 } 213 }
164 214
165 return true; 215 return;
166 } 216 }
167 217
168 public byte[] GetMapTile(string fileName, out string format) 218 public byte[] GetMapTile(string fileName, out string format)