diff options
Diffstat (limited to 'OpenSim/Region/CoreModules')
-rw-r--r-- | OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs | 22 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 86 |
2 files changed, 69 insertions, 39 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs index 7dd9087..349d3ac 100644 --- a/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs +++ b/OpenSim/Region/CoreModules/Agent/TextureSender/J2KDecoderModule.cs | |||
@@ -103,6 +103,10 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
103 | // If it's cached, return the cached results | 103 | // If it's cached, return the cached results |
104 | if (m_decodedCache.TryGetValue(assetID, out result)) | 104 | if (m_decodedCache.TryGetValue(assetID, out result)) |
105 | { | 105 | { |
106 | // m_log.DebugFormat( | ||
107 | // "[J2KDecoderModule]: Returning existing cached {0} layers j2k decode for {1}", | ||
108 | // result.Length, assetID); | ||
109 | |||
106 | callback(assetID, result); | 110 | callback(assetID, result); |
107 | } | 111 | } |
108 | else | 112 | else |
@@ -133,14 +137,9 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
133 | } | 137 | } |
134 | } | 138 | } |
135 | 139 | ||
136 | /// <summary> | 140 | public bool Decode(UUID assetID, byte[] j2kData) |
137 | /// Provides a synchronous decode so that caller can be assured that this executes before the next line | ||
138 | /// </summary> | ||
139 | /// <param name="assetID"></param> | ||
140 | /// <param name="j2kData"></param> | ||
141 | public void Decode(UUID assetID, byte[] j2kData) | ||
142 | { | 141 | { |
143 | DoJ2KDecode(assetID, j2kData); | 142 | return DoJ2KDecode(assetID, j2kData); |
144 | } | 143 | } |
145 | 144 | ||
146 | #endregion IJ2KDecoder | 145 | #endregion IJ2KDecoder |
@@ -150,11 +149,13 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
150 | /// </summary> | 149 | /// </summary> |
151 | /// <param name="assetID">UUID of Asset</param> | 150 | /// <param name="assetID">UUID of Asset</param> |
152 | /// <param name="j2kData">JPEG2000 data</param> | 151 | /// <param name="j2kData">JPEG2000 data</param> |
153 | private void DoJ2KDecode(UUID assetID, byte[] j2kData) | 152 | private bool DoJ2KDecode(UUID assetID, byte[] j2kData) |
154 | { | 153 | { |
155 | // m_log.DebugFormat( | 154 | // m_log.DebugFormat( |
156 | // "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID); | 155 | // "[J2KDecoderModule]: Doing J2K decoding of {0} bytes for asset {1}", j2kData.Length, assetID); |
157 | 156 | ||
157 | bool decodedSuccessfully = true; | ||
158 | |||
158 | //int DecodeTime = 0; | 159 | //int DecodeTime = 0; |
159 | //DecodeTime = Environment.TickCount; | 160 | //DecodeTime = Environment.TickCount; |
160 | OpenJPEG.J2KLayerInfo[] layers; | 161 | OpenJPEG.J2KLayerInfo[] layers; |
@@ -192,6 +193,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
192 | catch (Exception ex) | 193 | catch (Exception ex) |
193 | { | 194 | { |
194 | m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message); | 195 | m_log.Warn("[J2KDecoderModule]: CSJ2K threw an exception decoding texture " + assetID + ": " + ex.Message); |
196 | decodedSuccessfully = false; | ||
195 | } | 197 | } |
196 | } | 198 | } |
197 | else | 199 | else |
@@ -200,6 +202,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
200 | if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components)) | 202 | if (!OpenJPEG.DecodeLayerBoundaries(j2kData, out layers, out components)) |
201 | { | 203 | { |
202 | m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID); | 204 | m_log.Warn("[J2KDecoderModule]: OpenJPEG failed to decode texture " + assetID); |
205 | decodedSuccessfully = false; | ||
203 | } | 206 | } |
204 | } | 207 | } |
205 | 208 | ||
@@ -208,6 +211,7 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
208 | m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults"); | 211 | m_log.Warn("[J2KDecoderModule]: Failed to decode layer data for texture " + assetID + ", guessing sane defaults"); |
209 | // Layer decoding completely failed. Guess at sane defaults for the layer boundaries | 212 | // Layer decoding completely failed. Guess at sane defaults for the layer boundaries |
210 | layers = CreateDefaultLayers(j2kData.Length); | 213 | layers = CreateDefaultLayers(j2kData.Length); |
214 | decodedSuccessfully = false; | ||
211 | } | 215 | } |
212 | 216 | ||
213 | // Cache Decoded layers | 217 | // Cache Decoded layers |
@@ -227,6 +231,8 @@ namespace OpenSim.Region.CoreModules.Agent.TextureSender | |||
227 | m_notifyList.Remove(assetID); | 231 | m_notifyList.Remove(assetID); |
228 | } | 232 | } |
229 | } | 233 | } |
234 | |||
235 | return decodedSuccessfully; | ||
230 | } | 236 | } |
231 | 237 | ||
232 | private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength) | 238 | private OpenJPEG.J2KLayerInfo[] CreateDefaultLayers(int j2kLength) |
diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index e8aee3e..d68d28c 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | |||
@@ -156,7 +156,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
156 | changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; | 156 | changed = sp.Appearance.SetTextureEntries(textureEntry) || changed; |
157 | 157 | ||
158 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); | 158 | // WriteBakedTexturesReport(sp, m_log.DebugFormat); |
159 | ValidateBakedTextureCache(sp, false); | 159 | if (!ValidateBakedTextureCache(sp)) |
160 | RequestRebake(sp, true); | ||
160 | 161 | ||
161 | // This appears to be set only in the final stage of the appearance | 162 | // This appears to be set only in the final stage of the appearance |
162 | // update transaction. In theory, we should be able to do an immediate | 163 | // update transaction. In theory, we should be able to do an immediate |
@@ -251,15 +252,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
251 | } | 252 | } |
252 | 253 | ||
253 | /// <summary> | 254 | /// <summary> |
254 | /// Check for the existence of the baked texture assets. | ||
255 | /// </summary> | ||
256 | /// <param name="sp"></param> | ||
257 | public bool ValidateBakedTextureCache(IScenePresence sp) | ||
258 | { | ||
259 | return ValidateBakedTextureCache(sp, true); | ||
260 | } | ||
261 | |||
262 | /// <summary> | ||
263 | /// Queue up a request to send appearance. | 255 | /// Queue up a request to send appearance. |
264 | /// </summary> | 256 | /// </summary> |
265 | /// <remarks> | 257 | /// <remarks> |
@@ -292,17 +284,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
292 | } | 284 | } |
293 | } | 285 | } |
294 | 286 | ||
295 | #endregion | 287 | public bool ValidateBakedTextureCache(IScenePresence sp) |
296 | |||
297 | #region AvatarFactoryModule private methods | ||
298 | |||
299 | /// <summary> | ||
300 | /// Check for the existence of the baked texture assets. Request a rebake | ||
301 | /// unless checkonly is true. | ||
302 | /// </summary> | ||
303 | /// <param name="client"></param> | ||
304 | /// <param name="checkonly"></param> | ||
305 | private bool ValidateBakedTextureCache(IScenePresence sp, bool checkonly) | ||
306 | { | 288 | { |
307 | bool defonly = true; // are we only using default textures | 289 | bool defonly = true; // are we only using default textures |
308 | 290 | ||
@@ -330,16 +312,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
330 | defonly = false; // found a non-default texture reference | 312 | defonly = false; // found a non-default texture reference |
331 | 313 | ||
332 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) | 314 | if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) |
333 | { | 315 | return false; |
334 | if (checkonly) | ||
335 | return false; | ||
336 | |||
337 | m_log.DebugFormat( | ||
338 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", | ||
339 | face.TextureID, idx, sp.Name); | ||
340 | |||
341 | sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID); | ||
342 | } | ||
343 | } | 316 | } |
344 | 317 | ||
345 | m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", sp.UUID); | 318 | m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0}", sp.UUID); |
@@ -348,6 +321,57 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory | |||
348 | return (defonly ? false : true); | 321 | return (defonly ? false : true); |
349 | } | 322 | } |
350 | 323 | ||
324 | public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) | ||
325 | { | ||
326 | int texturesRebaked = 0; | ||
327 | |||
328 | for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) | ||
329 | { | ||
330 | int idx = AvatarAppearance.BAKE_INDICES[i]; | ||
331 | Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; | ||
332 | |||
333 | // if there is no texture entry, skip it | ||
334 | if (face == null) | ||
335 | continue; | ||
336 | |||
337 | // m_log.DebugFormat( | ||
338 | // "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", | ||
339 | // face.TextureID, idx, client.Name, client.AgentId); | ||
340 | |||
341 | // if the texture is one of the "defaults" then skip it | ||
342 | // this should probably be more intelligent (skirt texture doesnt matter | ||
343 | // if the avatar isnt wearing a skirt) but if any of the main baked | ||
344 | // textures is default then the rest should be as well | ||
345 | if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) | ||
346 | continue; | ||
347 | |||
348 | if (missingTexturesOnly) | ||
349 | { | ||
350 | if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) | ||
351 | continue; | ||
352 | else | ||
353 | m_log.DebugFormat( | ||
354 | "[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.", | ||
355 | face.TextureID, idx, sp.Name); | ||
356 | } | ||
357 | else | ||
358 | { | ||
359 | m_log.DebugFormat( | ||
360 | "[AVFACTORY]: Requesting rebake of {0} ({1}) for {2}.", | ||
361 | face.TextureID, idx, sp.Name); | ||
362 | } | ||
363 | |||
364 | texturesRebaked++; | ||
365 | sp.ControllingClient.SendRebakeAvatarTextures(face.TextureID); | ||
366 | } | ||
367 | |||
368 | return texturesRebaked; | ||
369 | } | ||
370 | |||
371 | #endregion | ||
372 | |||
373 | #region AvatarFactoryModule private methods | ||
374 | |||
351 | private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp) | 375 | private Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(ScenePresence sp) |
352 | { | 376 | { |
353 | if (sp.IsChildAgent) | 377 | if (sp.IsChildAgent) |