aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Scripting/DynamicTexture
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Scripting/DynamicTexture')
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs61
-rw-r--r--OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs315
2 files changed, 306 insertions, 70 deletions
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs
new file mode 100644
index 0000000..fce9490
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTexture.cs
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Drawing;
30using OpenSim.Region.Framework.Interfaces;
31
32namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
33{
34 public class DynamicTexture : IDynamicTexture
35 {
36 public string InputCommands { get; private set; }
37 public Uri InputUri { get; private set; }
38 public string InputParams { get; private set; }
39 public byte[] Data { get; private set; }
40 public Size Size { get; private set; }
41 public bool IsReuseable { get; private set; }
42
43 public DynamicTexture(string inputCommands, string inputParams, byte[] data, Size size, bool isReuseable)
44 {
45 InputCommands = inputCommands;
46 InputParams = inputParams;
47 Data = data;
48 Size = size;
49 IsReuseable = isReuseable;
50 }
51
52 public DynamicTexture(Uri inputUri, string inputParams, byte[] data, Size size, bool isReuseable)
53 {
54 InputUri = inputUri;
55 InputParams = inputParams;
56 Data = data;
57 Size = size;
58 IsReuseable = isReuseable;
59 }
60 }
61} \ No newline at end of file
diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
index 18bd018..9d77b19 100644
--- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
+++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs
@@ -37,18 +37,36 @@ using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes; 37using OpenSim.Region.Framework.Scenes;
38using log4net; 38using log4net;
39using System.Reflection; 39using System.Reflection;
40using Mono.Addins;
40 41
41namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture 42namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
42{ 43{
43 public class DynamicTextureModule : IRegionModule, IDynamicTextureManager 44 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "DynamicTextureModule")]
45 public class DynamicTextureModule : ISharedRegionModule, IDynamicTextureManager
44 { 46 {
45 //private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 47// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
46 48
47 private const int ALL_SIDES = -1; 49 private const int ALL_SIDES = -1;
48 50
49 public const int DISP_EXPIRE = 1; 51 public const int DISP_EXPIRE = 1;
50 public const int DISP_TEMP = 2; 52 public const int DISP_TEMP = 2;
51 53
54 /// <summary>
55 /// If true then where possible dynamic textures are reused.
56 /// </summary>
57 public bool ReuseTextures { get; set; }
58
59 /// <summary>
60 /// If false, then textures which have a low data size are not reused when ReuseTextures = true.
61 /// </summary>
62 /// <remarks>
63 /// LL viewers 3.3.4 and before appear to not fully render textures pulled from the viewer cache if those
64 /// textures have a relatively high pixel surface but a small data size. Typically, this appears to happen
65 /// if the data size is smaller than the viewer's discard level 2 size estimate. So if this is setting is
66 /// false, textures smaller than the calculation in IsSizeReuseable are always regenerated rather than reused
67 /// to work around this problem.</remarks>
68 public bool ReuseLowDataTextures { get; set; }
69
52 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>(); 70 private Dictionary<UUID, Scene> RegisteredScenes = new Dictionary<UUID, Scene>();
53 71
54 private Dictionary<string, IDynamicTextureRender> RenderPlugins = 72 private Dictionary<string, IDynamicTextureRender> RenderPlugins =
@@ -56,6 +74,25 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
56 74
57 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>(); 75 private Dictionary<UUID, DynamicTextureUpdater> Updaters = new Dictionary<UUID, DynamicTextureUpdater>();
58 76
77 /// <summary>
78 /// Record dynamic textures that we can reuse for a given data and parameter combination rather than
79 /// regenerate.
80 /// </summary>
81 /// <remarks>
82 /// Key is string.Format("{0}{1}", data
83 /// </remarks>
84 private Cache m_reuseableDynamicTextures;
85
86 /// <summary>
87 /// This constructor is only here because of the Unit Tests...
88 /// Don't use it.
89 /// </summary>
90 public DynamicTextureModule()
91 {
92 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
93 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
94 }
95
59 #region IDynamicTextureManager Members 96 #region IDynamicTextureManager Members
60 97
61 public void RegisterRender(string handleType, IDynamicTextureRender render) 98 public void RegisterRender(string handleType, IDynamicTextureRender render)
@@ -69,17 +106,17 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
69 /// <summary> 106 /// <summary>
70 /// Called by code which actually renders the dynamic texture to supply texture data. 107 /// Called by code which actually renders the dynamic texture to supply texture data.
71 /// </summary> 108 /// </summary>
72 /// <param name="id"></param> 109 /// <param name="updaterId"></param>
73 /// <param name="data"></param> 110 /// <param name="texture"></param>
74 public void ReturnData(UUID id, byte[] data) 111 public void ReturnData(UUID updaterId, IDynamicTexture texture)
75 { 112 {
76 DynamicTextureUpdater updater = null; 113 DynamicTextureUpdater updater = null;
77 114
78 lock (Updaters) 115 lock (Updaters)
79 { 116 {
80 if (Updaters.ContainsKey(id)) 117 if (Updaters.ContainsKey(updaterId))
81 { 118 {
82 updater = Updaters[id]; 119 updater = Updaters[updaterId];
83 } 120 }
84 } 121 }
85 122
@@ -88,7 +125,16 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
88 if (RegisteredScenes.ContainsKey(updater.SimUUID)) 125 if (RegisteredScenes.ContainsKey(updater.SimUUID))
89 { 126 {
90 Scene scene = RegisteredScenes[updater.SimUUID]; 127 Scene scene = RegisteredScenes[updater.SimUUID];
91 updater.DataReceived(data, scene); 128 UUID newTextureID = updater.DataReceived(texture.Data, scene);
129
130 if (ReuseTextures
131 && !updater.BlendWithOldTexture
132 && texture.IsReuseable
133 && (ReuseLowDataTextures || IsDataSizeReuseable(texture)))
134 {
135 m_reuseableDynamicTextures.Store(
136 GenerateReusableTextureKey(texture.InputCommands, texture.InputParams), newTextureID);
137 }
92 } 138 }
93 } 139 }
94 140
@@ -104,6 +150,27 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
104 } 150 }
105 } 151 }
106 152
153 /// <summary>
154 /// Determines whether the texture is reuseable based on its data size.
155 /// </summary>
156 /// <remarks>
157 /// This is a workaround for a viewer bug where very small data size textures relative to their pixel size
158 /// are not redisplayed properly when pulled from cache. The calculation here is based on the typical discard
159 /// level of 2, a 'rate' of 0.125 and 4 components (which makes for a factor of 0.5).
160 /// </remarks>
161 /// <returns></returns>
162 private bool IsDataSizeReuseable(IDynamicTexture texture)
163 {
164// Console.WriteLine("{0} {1}", texture.Size.Width, texture.Size.Height);
165 int discardLevel2DataThreshold = (int)Math.Ceiling((texture.Size.Width >> 2) * (texture.Size.Height >> 2) * 0.5);
166
167// m_log.DebugFormat(
168// "[DYNAMIC TEXTURE MODULE]: Discard level 2 threshold {0}, texture data length {1}",
169// discardLevel2DataThreshold, texture.Data.Length);
170
171 return discardLevel2DataThreshold < texture.Data.Length;
172 }
173
107 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url, 174 public UUID AddDynamicTextureURL(UUID simID, UUID primID, string contentType, string url,
108 string extraParams, int updateTimer) 175 string extraParams, int updateTimer)
109 { 176 {
@@ -167,22 +234,61 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
167 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data, 234 public UUID AddDynamicTextureData(UUID simID, UUID primID, string contentType, string data,
168 string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face) 235 string extraParams, int updateTimer, bool SetBlending, int disp, byte AlphaValue, int face)
169 { 236 {
170 if (RenderPlugins.ContainsKey(contentType)) 237 if (!RenderPlugins.ContainsKey(contentType))
238 return UUID.Zero;
239
240 Scene scene;
241 RegisteredScenes.TryGetValue(simID, out scene);
242
243 if (scene == null)
244 return UUID.Zero;
245
246 SceneObjectPart part = scene.GetSceneObjectPart(primID);
247
248 if (part == null)
249 return UUID.Zero;
250
251 // If we want to reuse dynamic textures then we have to ignore any request from the caller to expire
252 // them.
253 if (ReuseTextures)
254 disp = disp & ~DISP_EXPIRE;
255
256 DynamicTextureUpdater updater = new DynamicTextureUpdater();
257 updater.SimUUID = simID;
258 updater.PrimID = primID;
259 updater.ContentType = contentType;
260 updater.BodyData = data;
261 updater.UpdateTimer = updateTimer;
262 updater.UpdaterID = UUID.Random();
263 updater.Params = extraParams;
264 updater.BlendWithOldTexture = SetBlending;
265 updater.FrontAlpha = AlphaValue;
266 updater.Face = face;
267 updater.Url = "Local image";
268 updater.Disp = disp;
269
270 object objReusableTextureUUID = null;
271
272 if (ReuseTextures && !updater.BlendWithOldTexture)
171 { 273 {
172 DynamicTextureUpdater updater = new DynamicTextureUpdater(); 274 string reuseableTextureKey = GenerateReusableTextureKey(data, extraParams);
173 updater.SimUUID = simID; 275 objReusableTextureUUID = m_reuseableDynamicTextures.Get(reuseableTextureKey);
174 updater.PrimID = primID;
175 updater.ContentType = contentType;
176 updater.BodyData = data;
177 updater.UpdateTimer = updateTimer;
178 updater.UpdaterID = UUID.Random();
179 updater.Params = extraParams;
180 updater.BlendWithOldTexture = SetBlending;
181 updater.FrontAlpha = AlphaValue;
182 updater.Face = face;
183 updater.Url = "Local image";
184 updater.Disp = disp;
185 276
277 if (objReusableTextureUUID != null)
278 {
279 // If something else has removed this temporary asset from the cache, detect and invalidate
280 // our cached uuid.
281 if (scene.AssetService.GetMetadata(objReusableTextureUUID.ToString()) == null)
282 {
283 m_reuseableDynamicTextures.Invalidate(reuseableTextureKey);
284 objReusableTextureUUID = null;
285 }
286 }
287 }
288
289 // We cannot reuse a dynamic texture if the data is going to be blended with something already there.
290 if (objReusableTextureUUID == null)
291 {
186 lock (Updaters) 292 lock (Updaters)
187 { 293 {
188 if (!Updaters.ContainsKey(updater.UpdaterID)) 294 if (!Updaters.ContainsKey(updater.UpdaterID))
@@ -191,11 +297,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
191 } 297 }
192 } 298 }
193 299
300// m_log.DebugFormat(
301// "[DYNAMIC TEXTURE MODULE]: Requesting generation of new dynamic texture for {0} in {1}",
302// part.Name, part.ParentGroup.Scene.Name);
303
194 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); 304 RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams);
195 return updater.UpdaterID;
196 } 305 }
197 306 else
198 return UUID.Zero; 307 {
308// m_log.DebugFormat(
309// "[DYNAMIC TEXTURE MODULE]: Reusing cached texture {0} for {1} in {2}",
310// objReusableTextureUUID, part.Name, part.ParentGroup.Scene.Name);
311
312 // No need to add to updaters as the texture is always the same. Not that this functionality
313 // apppears to be implemented anyway.
314 updater.UpdatePart(part, (UUID)objReusableTextureUUID);
315 }
316
317 return updater.UpdaterID;
318 }
319
320 private string GenerateReusableTextureKey(string data, string extraParams)
321 {
322 return string.Format("{0}{1}", data, extraParams);
199 } 323 }
200 324
201 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize, 325 public void GetDrawStringSize(string contentType, string text, string fontName, int fontSize,
@@ -211,9 +335,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
211 335
212 #endregion 336 #endregion
213 337
214 #region IRegionModule Members 338 #region ISharedRegionModule Members
215 339
216 public void Initialise(Scene scene, IConfigSource config) 340 public void Initialise(IConfigSource config)
341 {
342 IConfig texturesConfig = config.Configs["Textures"];
343 if (texturesConfig != null)
344 {
345 ReuseTextures = texturesConfig.GetBoolean("ReuseDynamicTextures", false);
346 ReuseLowDataTextures = texturesConfig.GetBoolean("ReuseDynamicLowDataTextures", false);
347
348 if (ReuseTextures)
349 {
350 m_reuseableDynamicTextures = new Cache(CacheMedium.Memory, CacheStrategy.Conservative);
351 m_reuseableDynamicTextures.DefaultTTL = new TimeSpan(24, 0, 0);
352 }
353 }
354 }
355
356 public void PostInitialise()
357 {
358 }
359
360 public void AddRegion(Scene scene)
217 { 361 {
218 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID)) 362 if (!RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
219 { 363 {
@@ -222,8 +366,14 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
222 } 366 }
223 } 367 }
224 368
225 public void PostInitialise() 369 public void RegionLoaded(Scene scene)
370 {
371 }
372
373 public void RemoveRegion(Scene scene)
226 { 374 {
375 if (RegisteredScenes.ContainsKey(scene.RegionInfo.RegionID))
376 RegisteredScenes.Remove(scene.RegionInfo.RegionID);
227 } 377 }
228 378
229 public void Close() 379 public void Close()
@@ -235,9 +385,9 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
235 get { return "DynamicTextureModule"; } 385 get { return "DynamicTextureModule"; }
236 } 386 }
237 387
238 public bool IsSharedModule 388 public Type ReplaceableInterface
239 { 389 {
240 get { return true; } 390 get { return null; }
241 } 391 }
242 392
243 #endregion 393 #endregion
@@ -269,9 +419,60 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
269 } 419 }
270 420
271 /// <summary> 421 /// <summary>
422 /// Update the given part with the new texture.
423 /// </summary>
424 /// <returns>
425 /// The old texture UUID.
426 /// </returns>
427 public UUID UpdatePart(SceneObjectPart part, UUID textureID)
428 {
429 UUID oldID;
430
431 lock (part)
432 {
433 // mostly keep the values from before
434 Primitive.TextureEntry tmptex = part.Shape.Textures;
435
436 // FIXME: Need to return the appropriate ID if only a single face is replaced.
437 oldID = tmptex.DefaultTexture.TextureID;
438
439 if (Face == ALL_SIDES)
440 {
441 oldID = tmptex.DefaultTexture.TextureID;
442 tmptex.DefaultTexture.TextureID = textureID;
443 }
444 else
445 {
446 try
447 {
448 Primitive.TextureEntryFace texface = tmptex.CreateFace((uint)Face);
449 texface.TextureID = textureID;
450 tmptex.FaceTextures[Face] = texface;
451 }
452 catch (Exception)
453 {
454 tmptex.DefaultTexture.TextureID = textureID;
455 }
456 }
457
458 // I'm pretty sure we always want to force this to true
459 // I'm pretty sure noone whats to set fullbright true if it wasn't true before.
460 // tmptex.DefaultTexture.Fullbright = true;
461
462 part.UpdateTextureEntry(tmptex.GetBytes());
463 }
464
465 return oldID;
466 }
467
468 /// <summary>
272 /// Called once new texture data has been received for this updater. 469 /// Called once new texture data has been received for this updater.
273 /// </summary> 470 /// </summary>
274 public void DataReceived(byte[] data, Scene scene) 471 /// <param name="data"></param>
472 /// <param name="scene"></param>
473 /// <param name="isReuseable">True if the data given is reuseable.</param>
474 /// <returns>The asset UUID given to the incoming data.</returns>
475 public UUID DataReceived(byte[] data, Scene scene)
275 { 476 {
276 SceneObjectPart part = scene.GetSceneObjectPart(PrimID); 477 SceneObjectPart part = scene.GetSceneObjectPart(PrimID);
277 478
@@ -281,7 +482,8 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
281 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url); 482 String.Format("DynamicTextureModule: Error preparing image using URL {0}", Url);
282 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say, 483 scene.SimChat(Utils.StringToBytes(msg), ChatTypeEnum.Say,
283 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false); 484 0, part.ParentGroup.RootPart.AbsolutePosition, part.Name, part.UUID, false);
284 return; 485
486 return UUID.Zero;
285 } 487 }
286 488
287 byte[] assetData = null; 489 byte[] assetData = null;
@@ -319,56 +521,29 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture
319 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>(); 521 IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface<IJ2KDecoder>();
320 if (cacheLayerDecode != null) 522 if (cacheLayerDecode != null)
321 { 523 {
322 cacheLayerDecode.Decode(asset.FullID, asset.Data); 524 if (!cacheLayerDecode.Decode(asset.FullID, asset.Data))
323 cacheLayerDecode = null; 525 m_log.WarnFormat(
526 "[DYNAMIC TEXTURE MODULE]: Decoding of dynamically generated asset {0} for {1} in {2} failed",
527 asset.ID, part.Name, part.ParentGroup.Scene.Name);
324 } 528 }
325 529
326 UUID oldID = UUID.Zero; 530 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 531
361 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) 532 if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0))
362 { 533 {
363 if (oldAsset == null) oldAsset = scene.AssetService.Get(oldID.ToString()); 534 if (oldAsset == null)
535 oldAsset = scene.AssetService.Get(oldID.ToString());
536
364 if (oldAsset != null) 537 if (oldAsset != null)
365 { 538 {
366 if (oldAsset.Temporary == true) 539 if (oldAsset.Temporary)
367 { 540 {
368 scene.AssetService.Delete(oldID.ToString()); 541 scene.AssetService.Delete(oldID.ToString());
369 } 542 }
370 } 543 }
371 } 544 }
545
546 return asset.FullID;
372 } 547 }
373 548
374 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha) 549 private byte[] BlendTextures(byte[] frontImage, byte[] backImage, bool setNewAlpha, byte newAlpha)