aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting
diff options
context:
space:
mode:
authorMelanie2012-08-29 03:31:13 +0100
committerMelanie2012-08-29 03:31:13 +0100
commit899337b4a0584ce2371c3bfcc44387d0f090b792 (patch)
tree3a3e862951a85889c3c5762d6d30b5dd80868864 /OpenSim/Region/CoreModules/Scripting
parentMerge branch 'master' into careminster (diff)
parentimplementing rule tracking (diff)
downloadopensim-SC-899337b4a0584ce2371c3bfcc44387d0f090b792.zip
opensim-SC-899337b4a0584ce2371c3bfcc44387d0f090b792.tar.gz
opensim-SC-899337b4a0584ce2371c3bfcc44387d0f090b792.tar.bz2
opensim-SC-899337b4a0584ce2371c3bfcc44387d0f090b792.tar.xz
Merge branch 'master' into careminster
Conflicts: OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs169
-rw-r--r--OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs12
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs239
-rw-r--r--OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs60
4 files changed, 410 insertions, 70 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 18bd018..13b7498 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -49,6 +49,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
49 public const int DISP_EXPIRE = 1; 49 public const int DISP_EXPIRE = 1;
50 public const int DISP_TEMP = 2; 50 public const int DISP_TEMP = 2;
51 51
52 /// <summary>
53 /// If true then where possible dynamic textures are reused.
54 /// </summary>
55 public bool ReuseTextures { get; set; }
56
52 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 57 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
53 58
54 private Dictionary<string, IDynamicTextureRender> RenderPlugins = 59 private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -56,6 +61,15 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
56 61
57 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); 62 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
58 63
64 /// <summary>
65 /// Record dynamic textures that we can reuse for a given data and parameter combination rather than
66 /// regenerate.
67 /// </summary>
68 /// <remarks>
69 /// Key is string.Format("{0}{1}", data
70 /// </remarks>
71 private Cache m_reuseableDynamicTextures;
72
59 #region IDynamicTextureManager Members 73 #region IDynamicTextureManager Members
60 74
61 public void RegisterRender(string handleType, IDynamicTextureRender render) 75 public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -71,7 +85,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
71 /// </summary> 85 /// </summary>
72 /// <param name="id"></param> 86 /// <param name="id"></param>
73 /// <param name="data"></param> 87 /// <param name="data"></param>
74 public void ReturnData(UUID id, byte[] data) 88 /// <param name="isReuseable">True if the data generated can be reused for subsequent identical requests</param>
89 public void ReturnData(UUID id, byte[] data, bool isReuseable)
75 { 90 {
76 DynamicTextureUpdater updater = null; 91 DynamicTextureUpdater updater = null;
77 92
@@ -88,7 +103,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
88 if (RegisteredScenes.ContainsKey(updater.SimUUID)) 103 if (RegisteredScenes.ContainsKey(updater.SimUUID))
89 { 104 {
90 Scene scene = RegisteredScenes[updater.SimUUID]; 105 Scene scene = RegisteredScenes[updater.SimUUID];
91 updater.DataReceived(data, scene); 106 UUID newTextureID = updater.DataReceived(data, scene);
107
108 if (ReuseTextures && isReuseable && !updater.BlendWithOldTexture)
109 m_reuseableDynamicTextures.Store(
110 GenerateReusableTextureKey(updater.BodyData, updater.Params), newTextureID);
92 } 111 }
93 } 112 }
94 113
@@ -169,6 +188,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
169 { 188 {
170 if (RenderPlugins.ContainsKey(contentType)) 189 if (RenderPlugins.ContainsKey(contentType))
171 { 190 {
191 // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
192 // them.
193 if (ReuseTextures)
194 disp = disp & ~DISP_EXPIRE;
195
172 DynamicTextureUpdater updater = new DynamicTextureUpdater(); 196 DynamicTextureUpdater updater = new DynamicTextureUpdater();
173 updater.SimUUID = simID; 197 updater.SimUUID = simID;
174 updater.PrimID = primID; 198 updater.PrimID = primID;
@@ -183,21 +207,49 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
183 updater.Url = "Local image"; 207 updater.Url = "Local image";
184 updater.Disp = disp; 208 updater.Disp = disp;
185 209
186 lock (Updaters) 210 object reusableTextureUUID = null;
211
212 if (ReuseTextures)
213 reusableTextureUUID
214 = m_reuseableDynamicTextures.Get(GenerateReusableTextureKey(data, extraParams));
215
216 // We cannot reuse a dynamic texture if the data is going to be blended with something already there.
217 if (reusableTextureUUID == null || updater.BlendWithOldTexture)
187 { 218 {
188 if (!Updaters.ContainsKey(updater.UpdaterID)) 219 lock (Updaters)
189 { 220 {
190 Updaters.Add(updater.UpdaterID, updater); 221 if (!Updaters.ContainsKey(updater.UpdaterID))
222 {
223 Updaters.Add(updater.UpdaterID, updater);
224 }
225 }
226
227 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
228 }
229 else
230 {
231 // No need to add to updaters as the texture is always the same. Not that this functionality
232 // apppears to be implemented anyway.
233 if (RegisteredScenes.ContainsKey(updater.SimUUID))
234 {
235 SceneObjectPart part = RegisteredScenes[updater.SimUUID].GetSceneObjectPart(updater.PrimID);
236
237 if (part != null)
238 updater.UpdatePart(part, (UUID)reusableTextureUUID);
191 } 239 }
192 } 240 }
193 241
194 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
195 return updater.UpdaterID; 242 return updater.UpdaterID;
196 } 243 }
197 244
198 return UUID.Zero; 245 return UUID.Zero;
199 } 246 }
200 247
248 private string GenerateReusableTextureKey(string data, string extraParams)
249 {
250 return string.Format("{0}{1}", data, extraParams);
251 }
252
201 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, 253 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
202 out double xSize, out double ySize) 254 out double xSize, out double ySize)
203 { 255 {
@@ -224,6 +276,12 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
224 276
225 public void PostInitialise() 277 public void PostInitialise()
226 { 278 {
279// ReuseTextures = true;
280 if (ReuseTextures)
281 {
282 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
283 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
284 }
227 } 285 }
228 286
229 public void Close() 287 public void Close()
@@ -269,9 +327,60 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
269 } 327 }
270 328
271 /// <summary> 329 /// <summary>
330 /// Update the given part with the new texture.
331 /// </summary>
332 /// <returns>
333 /// The old texture UUID.
334 /// </returns>
335 public UUID UpdatePart(SceneObjectPart part, UUID textureID)
336 {
337 UUID oldID;
338
339 lock (part)
340 {
341 // mostly keep the values from before
342 Primitive.TextureEntry tmptex = part.Shape.Textures;
343
344 // FIXME: Need to return the appropriate ID if only a single face is replaced.
345 oldID = tmptex.DefaultTexture.TextureID;
346
347 if (Face == ALL_SIDES)
348 {
349 oldID = tmptex.DefaultTexture.TextureID;
350 tmptex.DefaultTexture.TextureID = textureID;
351 }
352 else
353 {
354 try
355 {
356 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
357 texface.TextureID = textureID;
358 tmptex.FaceTextures[Face] = texface;
359 }
360 catch (Exception)
361 {
362 tmptex.DefaultTexture.TextureID = textureID;
363 }
364 }
365
366 // I'm pretty sure we always want to force this to true
367 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
368 // tmptex.DefaultTexture.Fullbright = true;
369
370 part.UpdateTextureEntry(tmptex.GetBytes());
371 }
372
373 return oldID;
374 }
375
376 /// <summary>
272 /// Called once new texture data has been received for this updater. 377 /// Called once new texture data has been received for this updater.
273 /// </summary> 378 /// </summary>
274 public void DataReceived(byte[] data, Scene scene) 379 /// <param name="data"></param>
380 /// <param name="scene"></param>
381 /// <param name="isReuseable">True if the data given is reuseable.</param>
382 /// <returns>The asset UUID given to the incoming data.</returns>
383 public UUID DataReceived(byte[] data, Scene scene)
275 { 384 {
276 SceneObjectPart part = scene.GetSceneObjectPart(PrimID); 385 SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
277 386
@@ -281,7 +390,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
281 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); 390 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
282 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 391 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
283 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); 392 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
284 return; 393
394 return UUID.Zero;
285 } 395 }
286 396
287 byte[] assetData = null; 397 byte[] assetData = null;
@@ -323,52 +433,23 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
323 cacheLayerDecode = null; 433 cacheLayerDecode = null;
324 } 434 }
325 435
326 UUID oldID = UUID.Zero; 436 UUID oldID = UpdatePart(part, asset.FullID);
327
328 lock (part)
329 {
330 // mostly keep the values from before
331 Primitive.TextureEntry tmptex = part.Shape.Textures;
332
333 // remove the old asset from the cache
334 oldID = tmptex.DefaultTexture.TextureID;
335
336 if (Face == ALL_SIDES)
337 {
338 tmptex.DefaultTexture.TextureID = asset.FullID;
339 }
340 else
341 {
342 try
343 {
344 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
345 texface.TextureID = asset.FullID;
346 tmptex.FaceTextures[Face] = texface;
347 }
348 catch (Exception)
349 {
350 tmptex.DefaultTexture.TextureID = asset.FullID;
351 }
352 }
353
354 // I'm pretty sure we always want to force this to true
355 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
356 // tmptex.DefaultTexture.Fullbright = true;
357
358 part.UpdateTextureEntry(tmptex.GetBytes());
359 }
360 437
361 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) 438 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
362 { 439 {
363 if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); 440 if (oldAsset == null)
441 oldAsset = scene.AssetService.Get(oldID.ToString());
442
364 if (oldAsset != null) 443 if (oldAsset != null)
365 { 444 {
366 if (oldAsset.Temporary == true) 445 if (oldAsset.Temporary)
367 { 446 {
368 scene.AssetService.Delete(oldID.ToString()); 447 scene.AssetService.Delete(oldID.ToString());
369 } 448 }
370 } 449 }
371 } 450 }
451
452 return asset.FullID;
372 } 453 }
373 454
374 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) 455 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)
diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
index 6f83948..2b3a0f2 100644
--- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs
@@ -67,12 +67,18 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
67 return true; 67 return true;
68 } 68 }
69 69
70// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
71// {
72// // We don't support conversion of body data.
73// return false;
74// }
75
70 public byte[] ConvertUrl(string url, string extraParams) 76 public byte[] ConvertUrl(string url, string extraParams)
71 { 77 {
72 return null; 78 return null;
73 } 79 }
74 80
75 public byte[] ConvertStream(Stream data, string extraParams) 81 public byte[] ConvertData(string bodyData, string extraParams)
76 { 82 {
77 return null; 83 return null;
78 } 84 }
@@ -236,9 +242,11 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL
236 stream.Close(); 242 stream.Close();
237 } 243 }
238 } 244 }
245
239 m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}", 246 m_log.DebugFormat("[LOADIMAGEURLMODULE] Returning {0} bytes of image data for request {1}",
240 imageJ2000.Length, state.RequestID); 247 imageJ2000.Length, state.RequestID);
241 m_textureManager.ReturnData(state.RequestID, imageJ2000); 248
249 m_textureManager.ReturnData(state.RequestID, imageJ2000, false);
242 } 250 }
243 251
244 #region Nested type: RequestState 252 #region Nested type: RequestState
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
index 9787c8c..b50c0bd 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/Tests/VectorRenderModuleTests.cs
@@ -45,31 +45,250 @@ using OpenSim.Tests.Common.Mock;
45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests 45namespace OpenSim.Region.CoreModules.Scripting.VectorRender.Tests
46{ 46{
47 [TestFixture] 47 [TestFixture]
48 public class VectorRenderModuleTests 48 public class VectorRenderModuleTests : OpenSimTestCase
49 { 49 {
50 Scene m_scene;
51 DynamicTextureModule m_dtm;
52 VectorRenderModule m_vrm;
53
54 private void SetupScene(bool reuseTextures)
55 {
56 m_scene = new SceneHelpers().SetupScene();
57
58 m_dtm = new DynamicTextureModule();
59 m_dtm.ReuseTextures = reuseTextures;
60
61 m_vrm = new VectorRenderModule();
62
63 SceneHelpers.SetupSceneModules(m_scene, m_dtm, m_vrm);
64 }
65
50 [Test] 66 [Test]
51 public void TestDraw() 67 public void TestDraw()
52 { 68 {
53 TestHelpers.InMethod(); 69 TestHelpers.InMethod();
54 70
55 Scene scene = new SceneHelpers().SetupScene(); 71 SetupScene(false);
56 DynamicTextureModule dtm = new DynamicTextureModule(); 72 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
57 VectorRenderModule vrm = new VectorRenderModule();
58 SceneHelpers.SetupSceneModules(scene, dtm, vrm);
59
60 SceneObjectGroup so = SceneHelpers.AddSceneObject(scene);
61 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID; 73 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
62 74
63 dtm.AddDynamicTextureData( 75 m_dtm.AddDynamicTextureData(
64 scene.RegionInfo.RegionID, 76 m_scene.RegionInfo.RegionID,
65 so.UUID, 77 so.UUID,
66 vrm.GetContentType(), 78 m_vrm.GetContentType(),
67 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;", 79 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
68 "", 80 "",
69 0); 81 0);
70 82
83 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
84 }
85
86 [Test]
87 public void TestRepeatSameDraw()
88 {
89 TestHelpers.InMethod();
90
91 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
92
93 SetupScene(false);
94 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
95
96 m_dtm.AddDynamicTextureData(
97 m_scene.RegionInfo.RegionID,
98 so.UUID,
99 m_vrm.GetContentType(),
100 dtText,
101 "",
102 0);
103
104 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
105
106 m_dtm.AddDynamicTextureData(
107 m_scene.RegionInfo.RegionID,
108 so.UUID,
109 m_vrm.GetContentType(),
110 dtText,
111 "",
112 0);
113
114 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
115 }
116
117 [Test]
118 public void TestRepeatSameDrawDifferentExtraParams()
119 {
120 TestHelpers.InMethod();
121
122 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
123
124 SetupScene(false);
125 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
126
127 m_dtm.AddDynamicTextureData(
128 m_scene.RegionInfo.RegionID,
129 so.UUID,
130 m_vrm.GetContentType(),
131 dtText,
132 "",
133 0);
134
135 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
136
137 m_dtm.AddDynamicTextureData(
138 m_scene.RegionInfo.RegionID,
139 so.UUID,
140 m_vrm.GetContentType(),
141 dtText,
142 "alpha:250",
143 0);
144
145 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
146 }
147
148 [Test]
149 public void TestRepeatSameDrawContainingImage()
150 {
151 TestHelpers.InMethod();
152
153 string dtText
154 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
155
156 SetupScene(false);
157 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
158
159 m_dtm.AddDynamicTextureData(
160 m_scene.RegionInfo.RegionID,
161 so.UUID,
162 m_vrm.GetContentType(),
163 dtText,
164 "",
165 0);
166
167 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
168
169 m_dtm.AddDynamicTextureData(
170 m_scene.RegionInfo.RegionID,
171 so.UUID,
172 m_vrm.GetContentType(),
173 dtText,
174 "",
175 0);
176
177 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
178 }
179
180 [Test]
181 public void TestDrawReusingTexture()
182 {
183 TestHelpers.InMethod();
184
185 SetupScene(true);
186 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
187 UUID originalTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
188
189 m_dtm.AddDynamicTextureData(
190 m_scene.RegionInfo.RegionID,
191 so.UUID,
192 m_vrm.GetContentType(),
193 "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;",
194 "",
195 0);
71 196
72 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID)); 197 Assert.That(originalTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
73 } 198 }
199
200 [Test]
201 public void TestRepeatSameDrawReusingTexture()
202 {
203 TestHelpers.InMethod();
204
205 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
206
207 SetupScene(true);
208 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
209
210 m_dtm.AddDynamicTextureData(
211 m_scene.RegionInfo.RegionID,
212 so.UUID,
213 m_vrm.GetContentType(),
214 dtText,
215 "",
216 0);
217
218 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
219
220 m_dtm.AddDynamicTextureData(
221 m_scene.RegionInfo.RegionID,
222 so.UUID,
223 m_vrm.GetContentType(),
224 dtText,
225 "",
226 0);
227
228 Assert.That(firstDynamicTextureID, Is.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
229 }
230
231 [Test]
232 public void TestRepeatSameDrawDifferentExtraParamsReusingTexture()
233 {
234 TestHelpers.InMethod();
235
236 string dtText = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World;";
237
238 SetupScene(true);
239 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
240
241 m_dtm.AddDynamicTextureData(
242 m_scene.RegionInfo.RegionID,
243 so.UUID,
244 m_vrm.GetContentType(),
245 dtText,
246 "",
247 0);
248
249 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
250
251 m_dtm.AddDynamicTextureData(
252 m_scene.RegionInfo.RegionID,
253 so.UUID,
254 m_vrm.GetContentType(),
255 dtText,
256 "alpha:250",
257 0);
258
259 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
260 }
261
262 [Test]
263 public void TestRepeatSameDrawContainingImageReusingTexture()
264 {
265 TestHelpers.InMethod();
266
267 string dtText
268 = "PenColour BLACK; MoveTo 40,220; FontSize 32; Text Hello World; Image http://localhost/shouldnotexist.png";
269
270 SetupScene(true);
271 SceneObjectGroup so = SceneHelpers.AddSceneObject(m_scene);
272
273 m_dtm.AddDynamicTextureData(
274 m_scene.RegionInfo.RegionID,
275 so.UUID,
276 m_vrm.GetContentType(),
277 dtText,
278 "",
279 0);
280
281 UUID firstDynamicTextureID = so.RootPart.Shape.Textures.GetFace(0).TextureID;
282
283 m_dtm.AddDynamicTextureData(
284 m_scene.RegionInfo.RegionID,
285 so.UUID,
286 m_vrm.GetContentType(),
287 dtText,
288 "",
289 0);
290
291 Assert.That(firstDynamicTextureID, Is.Not.EqualTo(so.RootPart.Shape.Textures.GetFace(0).TextureID));
292 }
74 } 293 }
75} \ No newline at end of file 294} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
index 05eaaec..f687646 100644
--- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs
@@ -30,6 +30,7 @@ using System.Drawing;
30using System.Drawing.Imaging; 30using System.Drawing.Imaging;
31using System.Globalization; 31using System.Globalization;
32using System.IO; 32using System.IO;
33using System.Linq;
33using System.Net; 34using System.Net;
34using Nini.Config; 35using Nini.Config;
35using OpenMetaverse; 36using OpenMetaverse;
@@ -47,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
47 { 48 {
48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 49 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
49 50
50 private string m_name = "VectorRenderModule";
51 private Scene m_scene; 51 private Scene m_scene;
52 private IDynamicTextureManager m_textureManager; 52 private IDynamicTextureManager m_textureManager;
53 private Graphics m_graph; 53 private Graphics m_graph;
@@ -61,12 +61,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
61 61
62 public string GetContentType() 62 public string GetContentType()
63 { 63 {
64 return ("vector"); 64 return "vector";
65 } 65 }
66 66
67 public string GetName() 67 public string GetName()
68 { 68 {
69 return m_name; 69 return Name;
70 } 70 }
71 71
72 public bool SupportsAsynchronous() 72 public bool SupportsAsynchronous()
@@ -74,14 +74,26 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
74 return true; 74 return true;
75 } 75 }
76 76
77// public bool AlwaysIdenticalConversion(string bodyData, string extraParams)
78// {
79// string[] lines = GetLines(bodyData);
80// return lines.Any((str, r) => str.StartsWith("Image"));
81// }
82
77 public byte[] ConvertUrl(string url, string extraParams) 83 public byte[] ConvertUrl(string url, string extraParams)
78 { 84 {
79 return null; 85 return null;
80 } 86 }
81 87
82 public byte[] ConvertStream(Stream data, string extraParams) 88 public byte[] ConvertData(string bodyData, string extraParams)
83 { 89 {
84 return null; 90 bool reuseable;
91 return Draw(bodyData, extraParams, out reuseable);
92 }
93
94 private byte[] ConvertData(string bodyData, string extraParams, out bool reuseable)
95 {
96 return Draw(bodyData, extraParams, out reuseable);
85 } 97 }
86 98
87 public bool AsyncConvertUrl(UUID id, string url, string extraParams) 99 public bool AsyncConvertUrl(UUID id, string url, string extraParams)
@@ -91,7 +103,12 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
91 103
92 public bool AsyncConvertData(UUID id, string bodyData, string extraParams) 104 public bool AsyncConvertData(UUID id, string bodyData, string extraParams)
93 { 105 {
94 Draw(bodyData, id, extraParams); 106 // XXX: This isn't actually being done asynchronously!
107 bool reuseable;
108 byte[] data = ConvertData(bodyData, extraParams, out reuseable);
109
110 m_textureManager.ReturnData(id, data, reuseable);
111
95 return true; 112 return true;
96 } 113 }
97 114
@@ -152,7 +169,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
152 169
153 public string Name 170 public string Name
154 { 171 {
155 get { return m_name; } 172 get { return "VectorRenderModule"; }
156 } 173 }
157 174
158 public bool IsSharedModule 175 public bool IsSharedModule
@@ -162,7 +179,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
162 179
163 #endregion 180 #endregion
164 181
165 private void Draw(string data, UUID id, string extraParams) 182 private byte[] Draw(string data, string extraParams, out bool reuseable)
166 { 183 {
167 // 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 184 // 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
168 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255 185 // we will now support multiple comma seperated params in the form width:256,height:512,alpha:255
@@ -343,7 +360,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
343 } 360 }
344 } 361 }
345 362
346 GDIDraw(data, graph, altDataDelim); 363 GDIDraw(data, graph, altDataDelim, out reuseable);
347 } 364 }
348 365
349 byte[] imageJ2000 = new byte[0]; 366 byte[] imageJ2000 = new byte[0];
@@ -359,7 +376,7 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
359 e.Message, e.StackTrace); 376 e.Message, e.StackTrace);
360 } 377 }
361 378
362 m_textureManager.ReturnData(id, imageJ2000); 379 return imageJ2000;
363 } 380 }
364 finally 381 finally
365 { 382 {
@@ -434,8 +451,21 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
434 } 451 }
435*/ 452*/
436 453
437 private void GDIDraw(string data, Graphics graph, char dataDelim) 454 /// <summary>
455 /// Split input data into discrete command lines.
456 /// </summary>
457 /// <returns></returns>
458 /// <param name='data'></param>
459 /// <param name='dataDelim'></param>
460 private string[] GetLines(string data, char dataDelim)
438 { 461 {
462 char[] lineDelimiter = { dataDelim };
463 return data.Split(lineDelimiter);
464 }
465
466 private void GDIDraw(string data, Graphics graph, char dataDelim, out bool reuseable)
467 {
468 reuseable = true;
439 Point startPoint = new Point(0, 0); 469 Point startPoint = new Point(0, 0);
440 Point endPoint = new Point(0, 0); 470 Point endPoint = new Point(0, 0);
441 Pen drawPen = null; 471 Pen drawPen = null;
@@ -450,11 +480,9 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
450 myFont = new Font(fontName, fontSize); 480 myFont = new Font(fontName, fontSize);
451 myBrush = new SolidBrush(Color.Black); 481 myBrush = new SolidBrush(Color.Black);
452 482
453 char[] lineDelimiter = {dataDelim};
454 char[] partsDelimiter = {','}; 483 char[] partsDelimiter = {','};
455 string[] lines = data.Split(lineDelimiter);
456 484
457 foreach (string line in lines) 485 foreach (string line in GetLines(data, dataDelim))
458 { 486 {
459 string nextLine = line.Trim(); 487 string nextLine = line.Trim();
460 //replace with switch, or even better, do some proper parsing 488 //replace with switch, or even better, do some proper parsing
@@ -485,6 +513,10 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender
485 } 513 }
486 else if (nextLine.StartsWith("Image")) 514 else if (nextLine.StartsWith("Image"))
487 { 515 {
516 // We cannot reuse any generated texture involving fetching an image via HTTP since that image
517 // can change.
518 reuseable = false;
519
488 float x = 0; 520 float x = 0;
489 float y = 0; 521 float y = 0;
490 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y); 522 GetParams(partsDelimiter, ref nextLine, 5, ref x, ref y);