diff options
Diffstat (limited to 'OpenSim/Services/MapImageService/MapImageService.cs')
-rw-r--r-- | OpenSim/Services/MapImageService/MapImageService.cs | 82 |
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; | |||
36 | using System.IO; | 36 | using System.IO; |
37 | using System.Net; | 37 | using System.Net; |
38 | using System.Reflection; | 38 | using System.Reflection; |
39 | using System.Threading; | ||
39 | 40 | ||
40 | using Nini.Config; | 41 | using Nini.Config; |
41 | using log4net; | 42 | using 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) |