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.bullet-2.82
parent
0300ec45eb
commit
a2ea844494
|
@ -36,6 +36,7 @@ using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -53,6 +54,7 @@ namespace OpenSim.Services.MapImageService
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log =
|
||||||
LogManager.GetLogger(
|
LogManager.GetLogger(
|
||||||
MethodBase.GetCurrentMethod().DeclaringType);
|
MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private string LogHeader = "[MAP IMAGE SERVICE]";
|
||||||
|
|
||||||
private const int ZOOM_LEVELS = 8;
|
private const int ZOOM_LEVELS = 8;
|
||||||
private const int IMAGE_WIDTH = 256;
|
private const int IMAGE_WIDTH = 256;
|
||||||
|
@ -114,7 +116,7 @@ namespace OpenSim.Services.MapImageService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return UpdateMultiResolutionFiles(x, y, out reason);
|
return UpdateMultiResolutionFilesAsync(x, y, out reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RemoveMapTile(int x, int y, out string reason)
|
public bool RemoveMapTile(int x, int y, out string reason)
|
||||||
|
@ -136,33 +138,81 @@ namespace OpenSim.Services.MapImageService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return UpdateMultiResolutionFiles(x, y, out reason);
|
return UpdateMultiResolutionFilesAsync(x, y, out reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool UpdateMultiResolutionFiles(int x, int y, out string reason)
|
// When large varregions start up, they can send piles of new map tiles. This causes
|
||||||
|
// this multi-resolution routine to be called a zillion times an causes much CPU
|
||||||
|
// time to be spent creating multi-resolution tiles that will be replaced when
|
||||||
|
// the next maptile arrives.
|
||||||
|
private class mapToMultiRez
|
||||||
|
{
|
||||||
|
public int xx;
|
||||||
|
public int yy;
|
||||||
|
public mapToMultiRez(int pX, int pY)
|
||||||
|
{
|
||||||
|
xx = pX;
|
||||||
|
yy = pY;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
private Queue<mapToMultiRez> multiRezToBuild = new Queue<mapToMultiRez>();
|
||||||
|
private bool UpdateMultiResolutionFilesAsync(int x, int y, out string reason)
|
||||||
{
|
{
|
||||||
reason = String.Empty;
|
reason = String.Empty;
|
||||||
lock (m_Sync)
|
lock (multiRezToBuild)
|
||||||
{
|
{
|
||||||
// Stitch seven more aggregate tiles together
|
// m_log.DebugFormat("{0} UpdateMultiResolutionFilesAsync: scheduling update for <{1},{2}>", LogHeader, x, y);
|
||||||
for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++)
|
multiRezToBuild.Enqueue(new mapToMultiRez(x, y));
|
||||||
{
|
if (multiRezToBuild.Count == 1)
|
||||||
// Calculate the width (in full resolution tiles) and bottom-left
|
Util.FireAndForget(DoUpdateMultiResolutionFilesAsync);
|
||||||
// corner of the current zoom level
|
}
|
||||||
int width = (int)Math.Pow(2, (double)(zoomLevel - 1));
|
|
||||||
int x1 = x - (x % width);
|
|
||||||
int y1 = y - (y % width);
|
|
||||||
|
|
||||||
if (!CreateTile(zoomLevel, x1, y1))
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DoUpdateMultiResolutionFilesAsync(object o)
|
||||||
|
{
|
||||||
|
// This sleep causes the FireAndForget thread to be different than the invocation thread.
|
||||||
|
// It also allows other tiles to be uploaded so the multi-rez images are more likely
|
||||||
|
// to be correct.
|
||||||
|
Thread.Sleep(1 * 1000);
|
||||||
|
|
||||||
|
while (multiRezToBuild.Count > 0)
|
||||||
|
{
|
||||||
|
mapToMultiRez toMultiRez = null;
|
||||||
|
lock (multiRezToBuild)
|
||||||
|
{
|
||||||
|
if (multiRezToBuild.Count > 0)
|
||||||
|
toMultiRez = multiRezToBuild.Dequeue();
|
||||||
|
}
|
||||||
|
if (toMultiRez != null)
|
||||||
|
{
|
||||||
|
int x = toMultiRez.xx;
|
||||||
|
int y = toMultiRez.yy;
|
||||||
|
// m_log.DebugFormat("{0} DoUpdateMultiResolutionFilesAsync: doing build for <{1},{2}>", LogHeader, x, y);
|
||||||
|
|
||||||
|
// Stitch seven more aggregate tiles together
|
||||||
|
for (uint zoomLevel = 2; zoomLevel <= ZOOM_LEVELS; zoomLevel++)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0},{1} at zoom level {1}", x, y, zoomLevel);
|
// Calculate the width (in full resolution tiles) and bottom-left
|
||||||
reason = string.Format("Map tile at zoom level {0} failed", zoomLevel);
|
// corner of the current zoom level
|
||||||
return false;
|
int width = (int)Math.Pow(2, (double)(zoomLevel - 1));
|
||||||
|
int x1 = x - (x % width);
|
||||||
|
int y1 = y - (y % width);
|
||||||
|
|
||||||
|
lock (m_Sync) // must lock the reading and writing of the maptile files
|
||||||
|
{
|
||||||
|
if (!CreateTile(zoomLevel, x1, y1))
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[MAP IMAGE SERVICE]: Unable to create tile for {0},{1} at zoom level {1}", x, y, zoomLevel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] GetMapTile(string fileName, out string format)
|
public byte[] GetMapTile(string fileName, out string format)
|
||||||
|
|
Loading…
Reference in New Issue