diff options
author | Robert Adams | 2014-05-31 14:21:39 -0700 |
---|---|---|
committer | Robert Adams | 2014-05-31 14:21:39 -0700 |
commit | a2ea844494168f23e98d818d60b84e2171eb103e (patch) | |
tree | 10cac45f4dadab5d01a778c1685e09c458755519 /OpenSim/Services | |
parent | Modifications to debugging printouts. No functional changes. (diff) | |
download | opensim-SC-a2ea844494168f23e98d818d60b84e2171eb103e.zip opensim-SC-a2ea844494168f23e98d818d60b84e2171eb103e.tar.gz opensim-SC-a2ea844494168f23e98d818d60b84e2171eb103e.tar.bz2 opensim-SC-a2ea844494168f23e98d818d60b84e2171eb103e.tar.xz |
Move the generation of the multi-resolution map tiles off the main
region creation thread. For varregions or simulators with many regions,
this will speed up simulator startup and elimiate some thread timeout
warnings.
Diffstat (limited to 'OpenSim/Services')
-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) |