Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
commit
2b506cffb1
|
@ -49,12 +49,8 @@ using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Services.Interfaces;
|
using OpenSim.Services.Interfaces;
|
||||||
|
|
||||||
|
|
||||||
[assembly: Addin("FlotsamAssetCache", "1.1")]
|
namespace OpenSim.Region.CoreModules.Asset
|
||||||
[assembly: AddinDependency("OpenSim", "0.5")]
|
|
||||||
|
|
||||||
namespace Flotsam.RegionModules.AssetCache
|
|
||||||
{
|
{
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
|
||||||
public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService
|
public class FlotsamAssetCache : ISharedRegionModule, IImprovedAssetCache, IAssetService
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log =
|
private static readonly ILog m_log =
|
||||||
|
|
|
@ -35,7 +35,7 @@ using Nini.Config;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.Assets;
|
using OpenMetaverse.Assets;
|
||||||
using Flotsam.RegionModules.AssetCache;
|
using OpenSim.Region.CoreModules.Asset;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using OpenSim.Region.Framework.Scenes.Serialization;
|
using OpenSim.Region.Framework.Scenes.Serialization;
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<RegionModule id="LureModule" type="OpenSim.Region.CoreModules.Avatar.Lure.LureModule" />
|
<RegionModule id="LureModule" type="OpenSim.Region.CoreModules.Avatar.Lure.LureModule" />
|
||||||
<RegionModule id="InventoryTransferModule" type="OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.InventoryTransferModule" />
|
<RegionModule id="InventoryTransferModule" type="OpenSim.Region.CoreModules.Avatar.Inventory.Transfer.InventoryTransferModule" />
|
||||||
<RegionModule id="CoreAssetCache" type="OpenSim.Region.CoreModules.Asset.CoreAssetCache" />
|
<RegionModule id="CoreAssetCache" type="OpenSim.Region.CoreModules.Asset.CoreAssetCache" />
|
||||||
|
<RegionModule id="FlotsamAssetCache" type="OpenSim.Region.CoreModules.Asset.FlotsamAssetCache" />
|
||||||
<RegionModule id="GlynnTuckerAssetCache" type="OpenSim.Region.CoreModules.Asset.GlynnTuckerAssetCache" />
|
<RegionModule id="GlynnTuckerAssetCache" type="OpenSim.Region.CoreModules.Asset.GlynnTuckerAssetCache" />
|
||||||
<RegionModule id="CenomeMemoryAssetCache" type="OpenSim.Region.CoreModules.Asset.CenomeMemoryAssetCache"/>
|
<RegionModule id="CenomeMemoryAssetCache" type="OpenSim.Region.CoreModules.Asset.CenomeMemoryAssetCache"/>
|
||||||
<RegionModule id="LibraryModule" type="OpenSim.Region.CoreModules.Framework.Library.LibraryModule"/>
|
<RegionModule id="LibraryModule" type="OpenSim.Region.CoreModules.Framework.Library.LibraryModule"/>
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
||||||
|
{
|
||||||
|
public class DynamicTexture : IDynamicTexture
|
||||||
|
{
|
||||||
|
public string InputCommands { get; private set; }
|
||||||
|
public Uri InputUri { get; private set; }
|
||||||
|
public string InputParams { get; private set; }
|
||||||
|
public byte[] Data { get; private set; }
|
||||||
|
public Size Size { get; private set; }
|
||||||
|
public bool IsReuseable { get; private set; }
|
||||||
|
|
||||||
|
public DynamicTexture(string inputCommands, string inputParams, byte[] data, Size size, bool isReuseable)
|
||||||
|
{
|
||||||
|
InputCommands = inputCommands;
|
||||||
|
InputParams = inputParams;
|
||||||
|
Data = data;
|
||||||
|
Size = size;
|
||||||
|
IsReuseable = isReuseable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DynamicTexture(Uri inputUri, string inputParams, byte[] data, Size size, bool isReuseable)
|
||||||
|
{
|
||||||
|
InputUri = inputUri;
|
||||||
|
InputParams = inputParams;
|
||||||
|
Data = data;
|
||||||
|
Size = size;
|
||||||
|
IsReuseable = isReuseable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
||||||
{
|
{
|
||||||
public class DynamicTextureModule : IRegionModule, IDynamicTextureManager
|
public class DynamicTextureModule : IRegionModule, IDynamicTextureManager
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private const int ALL_SIDES = -1;
|
private const int ALL_SIDES = -1;
|
||||||
|
|
||||||
|
@ -54,6 +54,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool ReuseTextures { get; set; }
|
public bool ReuseTextures { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If false, then textures which have a low data size are not reused when ReuseTextures = true.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// LL viewers 3.3.4 and before appear to not fully render textures pulled from the viewer cache if those
|
||||||
|
/// textures have a relatively high pixel surface but a small data size. Typically, this appears to happen
|
||||||
|
/// if the data size is smaller than the viewer's discard level 2 size estimate. So if this is setting is
|
||||||
|
/// false, textures smaller than the calculation in IsSizeReuseable are always regenerated rather than reused
|
||||||
|
/// to work around this problem.</remarks>
|
||||||
|
public bool ReuseLowDataTextures { get; set; }
|
||||||
|
|
||||||
private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
|
private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
|
||||||
|
|
||||||
private Dictionary<string, IDynamicTextureRender> RenderPlugins =
|
private Dictionary<string, IDynamicTextureRender> RenderPlugins =
|
||||||
|
@ -83,18 +94,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Called by code which actually renders the dynamic texture to supply texture data.
|
/// Called by code which actually renders the dynamic texture to supply texture data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id"></param>
|
/// <param name="updaterId"></param>
|
||||||
/// <param name="data"></param>
|
/// <param name="texture"></param>
|
||||||
/// <param name="isReuseable">True if the data generated can be reused for subsequent identical requests</param>
|
public void ReturnData(UUID updaterId, IDynamicTexture texture)
|
||||||
public void ReturnData(UUID id, byte[] data, bool isReuseable)
|
|
||||||
{
|
{
|
||||||
DynamicTextureUpdater updater = null;
|
DynamicTextureUpdater updater = null;
|
||||||
|
|
||||||
lock (Updaters)
|
lock (Updaters)
|
||||||
{
|
{
|
||||||
if (Updaters.ContainsKey(id))
|
if (Updaters.ContainsKey(updaterId))
|
||||||
{
|
{
|
||||||
updater = Updaters[id];
|
updater = Updaters[updaterId];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,11 +113,16 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
||||||
if (RegisteredScenes.ContainsKey(updater.SimUUID))
|
if (RegisteredScenes.ContainsKey(updater.SimUUID))
|
||||||
{
|
{
|
||||||
Scene scene = RegisteredScenes[updater.SimUUID];
|
Scene scene = RegisteredScenes[updater.SimUUID];
|
||||||
UUID newTextureID = updater.DataReceived(data, scene);
|
UUID newTextureID = updater.DataReceived(texture.Data, scene);
|
||||||
|
|
||||||
if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture)
|
if (ReuseTextures
|
||||||
|
&& !updater.BlendWithOldTexture
|
||||||
|
&& texture.IsReuseable
|
||||||
|
&& (ReuseLowDataTextures || IsDataSizeReuseable(texture)))
|
||||||
|
{
|
||||||
m_reuseableDynamicTextures.Store(
|
m_reuseableDynamicTextures.Store(
|
||||||
GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID);
|
GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,6 +138,27 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the texture is reuseable based on its data size.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is a workaround for a viewer bug where very small data size textures relative to their pixel size
|
||||||
|
/// are not redisplayed properly when pulled from cache. The calculation here is based on the typical discard
|
||||||
|
/// level of 2, a 'rate' of 0.125 and 4 components (which makes for a factor of 0.5).
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns></returns>
|
||||||
|
private bool IsDataSizeReuseable(IDynamicTexture texture)
|
||||||
|
{
|
||||||
|
// Console.WriteLine("{0} {1}", texture.Size.Width, texture.Size.Height);
|
||||||
|
int discardLevel2DataThreshold = (int)Math.Ceiling((texture.Size.Width >> 2) * (texture.Size.Height >> 2) * 0.5);
|
||||||
|
|
||||||
|
// m_log.DebugFormat(
|
||||||
|
// "[DYNAMIC TEXTURE MODULE]: Discard level 2 threshold {0}, texture data length {1}",
|
||||||
|
// discardLevel2DataThreshold, texture.Data.Length);
|
||||||
|
|
||||||
|
return discardLevel2DataThreshold < texture.Data.Length;
|
||||||
|
}
|
||||||
|
|
||||||
public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
|
public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
|
||||||
string extraParams, int updateTimer)
|
string extraParams, int updateTimer)
|
||||||
{
|
{
|
||||||
|
@ -293,7 +329,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
|
||||||
{
|
{
|
||||||
IConfig texturesConfig = config.Configs["Textures"];
|
IConfig texturesConfig = config.Configs["Textures"];
|
||||||
if (texturesConfig != null)
|
if (texturesConfig != null)
|
||||||
|
{
|
||||||
ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false);
|
ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false);
|
||||||
|
ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false);
|
||||||
|
}
|
||||||
|
|
||||||
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
|
if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,7 @@ using System.Net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.Imaging;
|
using OpenMetaverse.Imaging;
|
||||||
|
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -73,12 +74,12 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
|
||||||
// return false;
|
// return false;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public byte[] ConvertUrl(string url, string extraParams)
|
public IDynamicTexture ConvertUrl(string url, string extraParams)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] ConvertData(string bodyData, string extraParams)
|
public IDynamicTexture ConvertData(string bodyData, string extraParams)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -171,11 +172,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
|
||||||
|
|
||||||
private void HttpRequestReturn(IAsyncResult result)
|
private void HttpRequestReturn(IAsyncResult result)
|
||||||
{
|
{
|
||||||
|
|
||||||
RequestState state = (RequestState) result.AsyncState;
|
RequestState state = (RequestState) result.AsyncState;
|
||||||
WebRequest request = (WebRequest) state.Request;
|
WebRequest request = (WebRequest) state.Request;
|
||||||
Stream stream = null;
|
Stream stream = null;
|
||||||
byte[] imageJ2000 = new byte[0];
|
byte[] imageJ2000 = new byte[0];
|
||||||
|
Size newSize = new Size(0, 0);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -188,38 +189,44 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Bitmap image = new Bitmap(stream);
|
Bitmap image = new Bitmap(stream);
|
||||||
Size newsize;
|
|
||||||
|
|
||||||
// TODO: make this a bit less hard coded
|
// TODO: make this a bit less hard coded
|
||||||
if ((image.Height < 64) && (image.Width < 64))
|
if ((image.Height < 64) && (image.Width < 64))
|
||||||
{
|
{
|
||||||
newsize = new Size(32, 32);
|
newSize.Width = 32;
|
||||||
|
newSize.Height = 32;
|
||||||
}
|
}
|
||||||
else if ((image.Height < 128) && (image.Width < 128))
|
else if ((image.Height < 128) && (image.Width < 128))
|
||||||
{
|
{
|
||||||
newsize = new Size(64, 64);
|
newSize.Width = 64;
|
||||||
|
newSize.Height = 64;
|
||||||
}
|
}
|
||||||
else if ((image.Height < 256) && (image.Width < 256))
|
else if ((image.Height < 256) && (image.Width < 256))
|
||||||
{
|
{
|
||||||
newsize = new Size(128, 128);
|
newSize.Width = 128;
|
||||||
|
newSize.Height = 128;
|
||||||
}
|
}
|
||||||
else if ((image.Height < 512 && image.Width < 512))
|
else if ((image.Height < 512 && image.Width < 512))
|
||||||
{
|
{
|
||||||
newsize = new Size(256, 256);
|
newSize.Width = 256;
|
||||||
|
newSize.Height = 256;
|
||||||
}
|
}
|
||||||
else if ((image.Height < 1024 && image.Width < 1024))
|
else if ((image.Height < 1024 && image.Width < 1024))
|
||||||
{
|
{
|
||||||
newsize = new Size(512, 512);
|
newSize.Width = 512;
|
||||||
|
newSize.Height = 512;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
newsize = new Size(1024, 1024);
|
newSize.Width = 1024;
|
||||||
|
newSize.Height = 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitmap resize = new Bitmap(image, newsize);
|
using (Bitmap resize = new Bitmap(image, newSize))
|
||||||
|
{
|
||||||
imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
|
imageJ2000 = OpenJPEG.EncodeFromImage(resize, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
m_log.Error("[LOADIMAGEURLMODULE]: OpenJpeg Conversion Failed. Empty byte data returned!");
|
m_log.Error("[LOADIMAGEURLMODULE]: OpenJpeg Conversion Failed. Empty byte data returned!");
|
||||||
|
@ -233,7 +240,6 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
|
||||||
}
|
}
|
||||||
catch (WebException)
|
catch (WebException)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
@ -243,10 +249,13 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}",
|
m_log.DebugFormat("[LOADIMAGEURLMODULE]: Returning {0} bytes of image data for request {1}",
|
||||||
imageJ2000.Length, state.RequestID);
|
imageJ2000.Length, state.RequestID);
|
||||||
|
|
||||||
m_textureManager.ReturnData(state.RequestID, imageJ2000, false);
|
m_textureManager.ReturnData(
|
||||||
|
state.RequestID,
|
||||||
|
new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
|
||||||
|
request.RequestUri, null, imageJ2000, newSize, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Nested type: RequestState
|
#region Nested type: RequestState
|
||||||
|
|
|
@ -57,6 +57,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
||||||
|
|
||||||
m_dtm = new DynamicTextureModule();
|
m_dtm = new DynamicTextureModule();
|
||||||
m_dtm.ReuseTextures = reuseTextures;
|
m_dtm.ReuseTextures = reuseTextures;
|
||||||
|
// m_dtm.ReuseLowDataTextures = reuseTextures;
|
||||||
|
|
||||||
m_vrm = new VectorRenderModule();
|
m_vrm = new VectorRenderModule();
|
||||||
|
|
||||||
|
@ -201,6 +202,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
||||||
public void TestRepeatSameDrawReusingTexture()
|
public void TestRepeatSameDrawReusingTexture()
|
||||||
{
|
{
|
||||||
TestHelpers.InMethod();
|
TestHelpers.InMethod();
|
||||||
|
// TestHelpers.EnableLogging();
|
||||||
|
|
||||||
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
|
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
|
||||||
|
|
||||||
|
@ -228,6 +230,46 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
|
||||||
Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Test a low data dynamically generated texture such that it is treated as a low data texture that causes
|
||||||
|
/// problems for current viewers.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// As we do not set DynamicTextureModule.ReuseLowDataTextures = true in this test, it should not reuse the
|
||||||
|
/// texture
|
||||||
|
/// </remarks>
|
||||||
|
[Test]
|
||||||
|
public void TestRepeatSameDrawLowDataTexture()
|
||||||
|
{
|
||||||
|
TestHelpers.InMethod();
|
||||||
|
// TestHelpers.EnableLogging();
|
||||||
|
|
||||||
|
string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
|
||||||
|
|
||||||
|
SetupScene(true);
|
||||||
|
SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
|
||||||
|
|
||||||
|
m_dtm.AddDynamicTextureData(
|
||||||
|
m_scene.RegionInfo.RegionID,
|
||||||
|
so.UUID,
|
||||||
|
m_vrm.GetContentType(),
|
||||||
|
dtText,
|
||||||
|
"1024",
|
||||||
|
0);
|
||||||
|
|
||||||
|
UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
|
||||||
|
|
||||||
|
m_dtm.AddDynamicTextureData(
|
||||||
|
m_scene.RegionInfo.RegionID,
|
||||||
|
so.UUID,
|
||||||
|
m_vrm.GetContentType(),
|
||||||
|
dtText,
|
||||||
|
"1024",
|
||||||
|
0);
|
||||||
|
|
||||||
|
Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
|
public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@ using System.Net;
|
||||||
using Nini.Config;
|
using Nini.Config;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenMetaverse.Imaging;
|
using OpenMetaverse.Imaging;
|
||||||
|
using OpenSim.Region.CoreModules.Scripting.DynamicTexture;
|
||||||
using OpenSim.Region.Framework.Interfaces;
|
using OpenSim.Region.Framework.Interfaces;
|
||||||
using OpenSim.Region.Framework.Scenes;
|
using OpenSim.Region.Framework.Scenes;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -85,20 +86,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
||||||
// return lines.Any((str, r) => str.StartsWith("Image"));
|
// return lines.Any((str, r) => str.StartsWith("Image"));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
public byte[] ConvertUrl(string url, string extraParams)
|
public IDynamicTexture ConvertUrl(string url, string extraParams)
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] ConvertData(string bodyData, string extraParams)
|
public IDynamicTexture ConvertData(string bodyData, string extraParams)
|
||||||
{
|
{
|
||||||
bool reuseable;
|
return Draw(bodyData, extraParams);
|
||||||
return Draw(bodyData, extraParams, out reuseable);
|
|
||||||
}
|
|
||||||
|
|
||||||
private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable)
|
|
||||||
{
|
|
||||||
return Draw(bodyData, extraParams, out reuseable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool AsyncConvertUrl(UUID id, string url, string extraParams)
|
public bool AsyncConvertUrl(UUID id, string url, string extraParams)
|
||||||
|
@ -109,10 +104,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
||||||
public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
|
public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
|
||||||
{
|
{
|
||||||
// XXX: This isn't actually being done asynchronously!
|
// XXX: This isn't actually being done asynchronously!
|
||||||
bool reuseable;
|
m_textureManager.ReturnData(id, ConvertData(bodyData, extraParams));
|
||||||
byte[] data = ConvertData(bodyData, extraParams, out reuseable);
|
|
||||||
|
|
||||||
m_textureManager.ReturnData(id, data, reuseable);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -191,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private byte[] Draw(string data, string extraParams, out bool reuseable)
|
private IDynamicTexture Draw(string data, string extraParams)
|
||||||
{
|
{
|
||||||
// We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
|
// We need to cater for old scripts that didnt use extraParams neatly, they use either an integer size which represents both width and height, or setalpha
|
||||||
// we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
|
// we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
|
||||||
|
@ -334,6 +326,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
||||||
|
|
||||||
Bitmap bitmap = null;
|
Bitmap bitmap = null;
|
||||||
Graphics graph = null;
|
Graphics graph = null;
|
||||||
|
bool reuseable = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -396,7 +389,8 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
|
||||||
e.Message, e.StackTrace);
|
e.Message, e.StackTrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
return imageJ2000;
|
return new OpenSim.Region.CoreModules.Scripting.DynamicTexture.DynamicTexture(
|
||||||
|
data, extraParams, imageJ2000, new Size(width, height), reuseable);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,7 +43,7 @@ using OpenSim.Tests.Common;
|
||||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
|
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Grid.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class GridConnectorsTests
|
public class GridConnectorsTests : OpenSimTestCase
|
||||||
{
|
{
|
||||||
LocalGridServicesConnector m_LocalConnector;
|
LocalGridServicesConnector m_LocalConnector;
|
||||||
private void SetUp()
|
private void SetUp()
|
||||||
|
|
|
@ -51,7 +51,7 @@ using RegionSettings = OpenSim.Framework.RegionSettings;
|
||||||
namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
namespace OpenSim.Region.CoreModules.World.Archiver.Tests
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class ArchiverTests
|
public class ArchiverTests : OpenSimTestCase
|
||||||
{
|
{
|
||||||
private Guid m_lastRequestId;
|
private Guid m_lastRequestId;
|
||||||
private string m_lastErrorMessage;
|
private string m_lastErrorMessage;
|
||||||
|
|
|
@ -208,6 +208,10 @@ namespace OpenSim.Region.CoreModules.World.Warp3DMap
|
||||||
bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height);
|
bitmap = ImageUtils.ResizeImage(origBitmap, viewport.Width, viewport.Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// XXX: It shouldn't really be necesary to force a GC here as one should occur anyway pretty shortly
|
||||||
|
// afterwards. It's generally regarded as a bad idea to manually GC. If Warp3D is using lots of memory
|
||||||
|
// then this may be some issue with the Warp3D code itself, though it's also quite possible that generating
|
||||||
|
// this map tile simply takes a lot of memory.
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()");
|
m_log.Debug("[WARP 3D IMAGE MODULE]: GC.Collect()");
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
@ -33,7 +35,14 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
public interface IDynamicTextureManager
|
public interface IDynamicTextureManager
|
||||||
{
|
{
|
||||||
void RegisterRender(string handleType, IDynamicTextureRender render);
|
void RegisterRender(string handleType, IDynamicTextureRender render);
|
||||||
void ReturnData(UUID id, byte[] data, bool isReuseable);
|
|
||||||
|
/// <summary>
|
||||||
|
/// Used by IDynamicTextureRender implementations to return renders
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='id'></param>
|
||||||
|
/// <param name='data'></param>
|
||||||
|
/// <param name='isReuseable'></param>
|
||||||
|
void ReturnData(UUID id, IDynamicTexture texture);
|
||||||
|
|
||||||
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
|
UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, string extraParams,
|
||||||
int updateTimer);
|
int updateTimer);
|
||||||
|
@ -125,11 +134,53 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
// /// <param name='extraParams'></param>
|
// /// <param name='extraParams'></param>
|
||||||
// bool AlwaysIdenticalConversion(string bodyData, string extraParams);
|
// bool AlwaysIdenticalConversion(string bodyData, string extraParams);
|
||||||
|
|
||||||
byte[] ConvertUrl(string url, string extraParams);
|
IDynamicTexture ConvertUrl(string url, string extraParams);
|
||||||
byte[] ConvertData(string bodyData, string extraParams);
|
IDynamicTexture ConvertData(string bodyData, string extraParams);
|
||||||
|
|
||||||
bool AsyncConvertUrl(UUID id, string url, string extraParams);
|
bool AsyncConvertUrl(UUID id, string url, string extraParams);
|
||||||
bool AsyncConvertData(UUID id, string bodyData, string extraParams);
|
bool AsyncConvertData(UUID id, string bodyData, string extraParams);
|
||||||
|
|
||||||
void GetDrawStringSize(string text, string fontName, int fontSize,
|
void GetDrawStringSize(string text, string fontName, int fontSize,
|
||||||
out double xSize, out double ySize);
|
out double xSize, out double ySize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface IDynamicTexture
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Input commands used to generate this data.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Null if input commands were not used.
|
||||||
|
/// </remarks>
|
||||||
|
string InputCommands { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uri used to generate this data.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Null if a uri was not used.
|
||||||
|
/// </remarks>
|
||||||
|
Uri InputUri { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extra input params used to generate this data.
|
||||||
|
/// </summary>
|
||||||
|
string InputParams { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Texture data.
|
||||||
|
/// </summary>
|
||||||
|
byte[] Data { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Size of texture.
|
||||||
|
/// </summary>
|
||||||
|
Size Size { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Signal whether the texture is reuseable (i.e. whether the same input data will always generate the same
|
||||||
|
/// texture).
|
||||||
|
/// </summary>
|
||||||
|
bool IsReuseable { get; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,11 +39,9 @@ using OpenSim.Framework.Console;
|
||||||
using OpenSim.Region.Physics.Manager;
|
using OpenSim.Region.Physics.Manager;
|
||||||
using Mono.Addins;
|
using Mono.Addins;
|
||||||
|
|
||||||
[assembly: Addin("RegionCombinerModule", "0.1")]
|
|
||||||
[assembly: AddinDependency("OpenSim", "0.5")]
|
|
||||||
namespace OpenSim.Region.RegionCombinerModule
|
namespace OpenSim.Region.RegionCombinerModule
|
||||||
{
|
{
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
|
|
||||||
public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule
|
public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<Addin id="RegionCombinerModule" version="0.2">
|
||||||
|
<Runtime>
|
||||||
|
<Import assembly="OpenSim.Region.RegionCombinerModule.dll"/>
|
||||||
|
</Runtime>
|
||||||
|
|
||||||
|
<Dependencies>
|
||||||
|
<Addin id="OpenSim" version="0.5" />
|
||||||
|
</Dependencies>
|
||||||
|
|
||||||
|
<Extension path = "/OpenSim/RegionModules">
|
||||||
|
<RegionModule id="RegionCombinerModule" type="OpenSim.Region.RegionCombinerModule" />
|
||||||
|
</Extension>
|
||||||
|
</Addin>
|
||||||
|
|
|
@ -703,6 +703,13 @@
|
||||||
; Default is false.
|
; Default is false.
|
||||||
ReuseDynamicTextures = false
|
ReuseDynamicTextures = false
|
||||||
|
|
||||||
|
; If true, then textures generated dynamically that have a low data size relative to their pixel size are not reused
|
||||||
|
; This is to workaround an apparent LL 3.3.4 and earlier viewer bug where such textures are not redisplayed properly when pulled from the viewer cache.
|
||||||
|
; Only set this to true if you are sure that all the viewers using your simulator will not suffer from this problem.
|
||||||
|
; This setting only has an affect is ReuseDynamicTextures = true
|
||||||
|
; Default is false
|
||||||
|
ReuseDynamicLowDataTextures = false
|
||||||
|
|
||||||
|
|
||||||
[ODEPhysicsSettings]
|
[ODEPhysicsSettings]
|
||||||
; ##
|
; ##
|
||||||
|
|
Loading…
Reference in New Issue