From c3f9c99fb32d15e57b24502b71c79fe028ed3007 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 7 Aug 2014 05:20:45 +0100 Subject: DANGER... changed bakedtextures caching. Assuming grid baking is cache only, reduced number of accesses to it. TESTING --- OpenSim/Framework/WearableCacheItem.cs | 2 +- .../Linden/Caps/UploadBakedTextureModule.cs | 124 +++++---- .../Region/ClientStack/Linden/UDP/LLClientView.cs | 110 ++++---- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 279 +++++++++++++++------ OpenSim/Region/Framework/Scenes/ScenePresence.cs | 2 +- 5 files changed, 299 insertions(+), 218 deletions(-) diff --git a/OpenSim/Framework/WearableCacheItem.cs b/OpenSim/Framework/WearableCacheItem.cs index 1aecf79..cde2862 100644 --- a/OpenSim/Framework/WearableCacheItem.cs +++ b/OpenSim/Framework/WearableCacheItem.cs @@ -46,7 +46,7 @@ namespace OpenSim.Framework int itemmax = 21; WearableCacheItem[] retitems = new WearableCacheItem[itemmax]; for (uint i=0;i AvatarWearable.MAX_WEARABLES) - { - maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; - m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); - } - - m_BakedTextureModule = m_scene.RequestModuleInterface(); - if (cacheItems.Length > 0) - { - m_log.Debug("[Cacheitems]: " + cacheItems.Length); - for (int iter = 0; iter < maxCacheitemsLoop; iter++) - { - m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + - cacheItems[iter].TextureID); - } - - ScenePresence p = null; - if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) +/* not in use. work done in AvatarFactoryModule ValidateBakedTextureCache() and UpdateBakedTextureCache() + private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems) { + // if cacheItems.Length > 0 viewer is giving us current textures information. + // baked ones should had been uploaded and in assets cache as local itens + + + if (cacheItems.Length == 0) + return; // no textures information, nothing to do + + ScenePresence p = null; + if (!m_scene.TryGetScenePresence(remoteClient.AgentId, out p)) + return; // what are we doing if there is no presence to cache for? + + if (p.IsDeleted) + return; // does this really work? + + int maxCacheitemsLoop = cacheItems.Length; + if (maxCacheitemsLoop > 20) + { + maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES; + m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES); + } + + m_BakedTextureModule = m_scene.RequestModuleInterface(); + + + // some nice debug + m_log.Debug("[Cacheitems]: " + cacheItems.Length); + for (int iter = 0; iter < maxCacheitemsLoop; iter++) + { + m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + + cacheItems[iter].TextureID); + } + + // p.Appearance.WearableCacheItems is in memory primary cashID to textures mapper WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems; + if (existingitems == null) { if (m_BakedTextureModule != null) @@ -161,38 +173,22 @@ namespace OpenSim.Region.ClientStack.Linden p.Appearance.WearableCacheItems = savedcache; p.Appearance.WearableCacheItemsDirty = false; } - } - /* - * The following Catch types DO NOT WORK with m_BakedTextureModule.Get - * it jumps to the General Packet Exception Handler if you don't catch Exception! - * - catch (System.Net.Sockets.SocketException) - { - cacheItems = null; - } - catch (WebException) - { - cacheItems = null; - } - catch (InvalidOperationException) - { - cacheItems = null; - } */ + catch (Exception) { - // The service logs a sufficient error message. + // The service logs a sufficient error message. } - + if (savedcache != null) existingitems = savedcache; } } + // Existing items null means it's a fully new appearance if (existingitems == null) { - for (int i = 0; i < maxCacheitemsLoop; i++) { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) @@ -205,7 +201,7 @@ namespace OpenSim.Region.ClientStack.Linden AppearanceManager.DEFAULT_AVATAR_TEXTURE; continue; } - cacheItems[i].TextureID =face.TextureID; + cacheItems[i].TextureID = face.TextureID; if (m_scene.AssetService != null) cacheItems[i].TextureAsset = m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString()); @@ -214,15 +210,10 @@ namespace OpenSim.Region.ClientStack.Linden { m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length); } - - } } else - - - { - // for each uploaded baked texture + { for (int i = 0; i < maxCacheitemsLoop; i++) { if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex) @@ -253,27 +244,24 @@ namespace OpenSim.Region.ClientStack.Linden } } } - p.Appearance.WearableCacheItems = cacheItems; - + if (m_BakedTextureModule != null) { m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems); p.Appearance.WearableCacheItemsDirty = true; - + } else p.Appearance.WearableCacheItemsDirty = false; - } - } - - for (int iter = 0; iter < maxCacheitemsLoop; iter++) - { - m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + - cacheItems[iter].TextureID); - } - } + for (int iter = 0; iter < maxCacheitemsLoop; iter++) + { + m_log.Debug("[CacheitemsLeaving] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" + + cacheItems[iter].TextureID); + } + } + */ public void PostInitialise() { } diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 08b6cb4..38a9af3 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3684,6 +3684,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP avp.Sender.IsTrial = false; avp.Sender.ID = agentID; avp.AppearanceData = new AvatarAppearancePacket.AppearanceDataBlock[0]; + + // this need be use in future + // avp.AppearanceData[0].AppearanceVersion = 0; + // avp.AppearanceData[0].CofVersion = 0; + //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); OutPacket(avp, ThrottleOutPacketType.Task); } @@ -12006,8 +12011,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP AgentCachedTextureResponsePacket cachedresp = (AgentCachedTextureResponsePacket)PacketPool.Instance.GetPacket(PacketType.AgentCachedTextureResponse); if (cachedtex.AgentData.SessionID != SessionId) - return false; - + return false; // TODO: don't create new blocks if recycling an old packet cachedresp.AgentData.AgentID = AgentId; @@ -12022,23 +12026,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP //WearableCacheItem[] items = fac.GetCachedItems(AgentId); IAssetService cache = m_scene.AssetService; - IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface(); //bakedTextureModule = null; int maxWearablesLoop = cachedtex.WearableData.Length; if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES) maxWearablesLoop = AvatarWearable.MAX_WEARABLES; -// if (bakedTextureModule != null && cache != null) + int cacheHits = 0; + if (cache != null) { // We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid WearableCacheItem[] cacheItems = null; + ScenePresence p = m_scene.GetScenePresence(AgentId); - if (p.Appearance != null) + + if (p!= null && p.Appearance != null) { - if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty) + /* we should only check bakedTextureModule at login or when appearance changes + if (p.Appearance.WearableCacheItems == null) // currently with a caching only bakemodule Appearance.Wearables.dirty as no use { + IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface(); if (bakedTextureModule != null) { m_log.Debug("[ HandleAgentTextureCached] bakedTextureModule"); @@ -12047,23 +12055,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP cacheItems = bakedTextureModule.Get(AgentId); p.Appearance.WearableCacheItems = cacheItems; p.Appearance.WearableCacheItemsDirty = false; - } - /* - * The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception! - * - catch (System.Net.Sockets.SocketException) - { - cacheItems = null; - } - catch (WebException) - { - cacheItems = null; + if (cacheItems != null) + { + foreach (WearableCacheItem item in cacheItems) + { + if (item.TextureAsset != null) + { + item.TextureAsset.Temporary = true; + item.TextureAsset.Local = true; + cache.Store(item.TextureAsset); + } + } + } } - catch (InvalidOperationException) - { - cacheItems = null; - } */ + catch (Exception) { cacheItems = null; @@ -12075,36 +12081,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP { cacheItems = p.Appearance.WearableCacheItems; } +*/ + cacheItems = p.Appearance.WearableCacheItems; } - if (cache != null && cacheItems != null) - { - foreach (WearableCacheItem item in cacheItems) - { - - if (cache.GetCached(item.TextureID.ToString()) == null) - { - item.TextureAsset.Temporary = true; - cache.Store(item.TextureAsset); - } - } - } - if (cacheItems != null) { - for (int i = 0; i < maxWearablesLoop; i++) { - WearableCacheItem item = - WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems); + int idx = cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex; + cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; cachedresp.WearableData[i].HostName = new byte[0]; - if (item != null && cachedtex.WearableData[i].ID == item.CacheId) + if (cachedtex.WearableData[i].ID == cacheItems[idx].CacheId) { - - cachedresp.WearableData[i].TextureID = item.TextureID; + cachedresp.WearableData[i].TextureID = cacheItems[idx].TextureID; + cacheHits++; } else { @@ -12124,36 +12117,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } } - else + else // no cache { - if (cache == null) + for (int i = 0; i < maxWearablesLoop; i++) { - for (int i = 0; i < maxWearablesLoop; i++) - { - cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - cachedresp.WearableData[i].TextureID = UUID.Zero; - //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); - cachedresp.WearableData[i].HostName = new byte[0]; - } - } - else - { - for (int i = 0; i < maxWearablesLoop; i++) - { - cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); - cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; - - if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null) - cachedresp.WearableData[i].TextureID = UUID.Zero; - //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); -// else -// cachedresp.WearableData[i].TextureID = UUID.Zero; - // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46"); - cachedresp.WearableData[i].HostName = new byte[0]; - } + cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); + cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex; + cachedresp.WearableData[i].TextureID = UUID.Zero; + cachedresp.WearableData[i].HostName = new byte[0]; } } + + m_log.DebugFormat("texture cached: hits {0}", cacheHits); + cachedresp.Header.Zerocoded = true; OutPacket(cachedresp, ThrottleOutPacketType.Task); diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 09cc998..b4aefce 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -188,27 +188,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // Process the visual params, this may change height as well if (visualParams != null) { - // string[] visualParamsStrings = new string[visualParams.Length]; - // for (int i = 0; i < visualParams.Length; i++) - // visualParamsStrings[i] = visualParams[i].ToString(); - // m_log.DebugFormat( - // "[AVFACTORY]: Setting visual params for {0} to {1}", - // client.Name, string.Join(", ", visualParamsStrings)); -/* - float oldHeight = sp.Appearance.AvatarHeight; - changed = sp.Appearance.SetVisualParams(visualParams); - - if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) - ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); - */ -// float oldoff = sp.Appearance.AvatarFeetOffset; -// Vector3 oldbox = sp.Appearance.AvatarBoxSize; changed = sp.Appearance.SetVisualParams(visualParams); -// float off = sp.Appearance.AvatarFeetOffset; -// Vector3 box = sp.Appearance.AvatarBoxSize; -// if(oldoff != off || oldbox != box) -// ((ScenePresence)sp).SetSize(box,off); - } // Process the baked texture array @@ -222,9 +202,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // WriteBakedTexturesReport(sp, m_log.DebugFormat); + // If bake textures are missing and this is not an NPC, request a rebake from client - if (!ValidateBakedTextureCache(sp) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) - RequestRebake(sp, true); + // rebake may messup caching, and should not be needed + + +// if (!UpdateBakedTextureCache(sp,cacheItems) && (((ScenePresence)sp).PresenceType != PresenceType.Npc)) +// RequestRebake(sp, true); + + UpdateBakedTextureCache(sp, cacheItems); // This appears to be set only in the final stage of the appearance // update transaction. In theory, we should be able to do an immediate @@ -377,13 +363,138 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } } + // called on textures update + public bool UpdateBakedTextureCache(IScenePresence sp, WearableCacheItem[] cacheItems) + { + bool defonly = true; // are we only using default textures + + // uploaded baked textures will be in assets local cache + IAssetService cache = m_scene.AssetService; + + int validDirtyBakes = 0; + int hits = 0; + + // our main cacheIDs mapper is p.Appearance.WearableCacheItems + WearableCacheItem[] wearableCache = sp.Appearance.WearableCacheItems; + + if (wearableCache == null) + { + wearableCache = WearableCacheItem.GetDefaultCacheItem(); + } + + // Process received baked textures + for (int i = 0; i < cacheItems.Length; i++) + { + int idx = (int)cacheItems[i].TextureIndex; + Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[idx]; + + // No face + if (face == null) + { + // for some reason viewer is cleaning this + sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); + sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; + continue; + } + else + { + if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) + { + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; + continue; + } + + defonly = false; // found a non-default texture reference + + if(sp.Appearance.Texture.FaceTextures[idx].TextureID == wearableCache[idx].TextureID) + { + if(wearableCache[idx].CacheId != cacheItems[i].CacheId) + { + wearableCache[idx].CacheId = cacheItems[i].CacheId; + validDirtyBakes++; + hits++; + //assuming this can only happen if asset is in cache + } + continue; + } + + + wearableCache[idx].TextureAsset = null; + if (cache != null) + wearableCache[idx].TextureAsset = cache.GetCached(face.TextureID.ToString()); + + if (wearableCache[idx].TextureAsset != null) + { + wearableCache[idx].CacheId = cacheItems[i].CacheId; + wearableCache[idx].TextureID = sp.Appearance.Texture.FaceTextures[idx].TextureID; + validDirtyBakes++; + hits++; + } + else + { + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; + continue; + } + } + } + + sp.Appearance.WearableCacheItems = wearableCache; + + // if we got a full set of baked textures save all in BakedTextureModule + + if (validDirtyBakes == cacheItems.Length) + { + IBakedTextureModule m_BakedTextureModule = m_scene.RequestModuleInterface(); + if (m_BakedTextureModule != null) + { + m_log.Debug("[UpdateBakedCache] uploading to bakedModule cache"); + + m_BakedTextureModule.Store(sp.UUID, wearableCache); + } + } + + // debug + for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) + { + int j = AvatarAppearance.BAKE_INDICES[iter]; + m_log.Debug("[UpdateBCache] {" + iter + "/" + + sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + + sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + + sp.Appearance.WearableCacheItems[j].TextureID); + } + + // If we only found default textures, then the appearance is not cached + return (defonly ? false : true); + } + + // called when we get a new root avatar public bool ValidateBakedTextureCache(IScenePresence sp) { bool defonly = true; // are we only using default textures - IImprovedAssetCache cache = m_scene.RequestModuleInterface(); + IAssetService cache = m_scene.AssetService; IBakedTextureModule bakedModule = m_scene.RequestModuleInterface(); WearableCacheItem[] wearableCache = null; + // debug + for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) + { + int j = AvatarAppearance.BAKE_INDICES[iter]; + Primitive.TextureEntryFace face = sp.Appearance.Texture.FaceTextures[iter]; + if(face != null) + m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - " + face.TextureID); + else + m_log.Debug("[ValidateBakedCache] {" + iter + "/" + j + " t - No texture"); + } + + + int hits = 0; // Cache wearable data for teleport. // Only makes sense if there's a bake module and a cache module if (bakedModule != null && cache != null) @@ -394,41 +505,35 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory } catch (Exception) { - + wearableCache = null; } + if (wearableCache != null) { for (int i = 0; i < wearableCache.Length; i++) { - cache.Cache(wearableCache[i].TextureAsset); - } - } - } - /* - IBakedTextureModule bakedModule = m_scene.RequestModuleInterface(); - if (invService.GetRootFolder(userID) != null) - { - WearableCacheItem[] wearableCache = null; - if (bakedModule != null) - { - try - { - wearableCache = bakedModule.Get(userID); - appearance.WearableCacheItems = wearableCache; - appearance.WearableCacheItemsDirty = false; - foreach (WearableCacheItem item in wearableCache) + + m_log.Debug("[ValidateBakedCache] got bakedModule cache"); + + if (wearableCache[i].TextureAsset != null) { - appearance.Texture.FaceTextures[item.TextureIndex].TextureID = item.TextureID; + wearableCache[i].TextureAsset.Temporary = true; + wearableCache[i].TextureAsset.Local = true; + cache.Store(wearableCache[i].TextureAsset); + } + else + { + wearableCache[i].TextureID = UUID.Zero; + wearableCache[i].CacheId = UUID.Zero; } - } - catch (Exception) - { - } } - */ + } + + if(wearableCache == null) + wearableCache = WearableCacheItem.GetDefaultCacheItem(); - // Process the texture entry + // Process the baked textures for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) { int idx = AvatarAppearance.BAKE_INDICES[i]; @@ -437,61 +542,73 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // No face, so lets check our baked service cache, teleport or login. if (face == null) { - if (wearableCache != null) + sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint)idx); + if (wearableCache[idx].TextureID != UUID.Zero) { - // If we find the an appearance item, set it as the textureentry and the face - WearableCacheItem searchitem = WearableCacheItem.SearchTextureIndex((uint) idx, wearableCache); - if (searchitem != null) - { - sp.Appearance.Texture.FaceTextures[idx] = sp.Appearance.Texture.CreateFace((uint) idx); - sp.Appearance.Texture.FaceTextures[idx].TextureID = searchitem.TextureID; - face = sp.Appearance.Texture.FaceTextures[idx]; - } - else - { - // if there is no texture entry and no baked cache, skip it - continue; - } + sp.Appearance.Texture.FaceTextures[idx].TextureID = wearableCache[idx].TextureID; + face = sp.Appearance.Texture.FaceTextures[idx]; + // let run to end of loop to check cache } else { - //No texture entry face and no cache. Skip this face. + sp.Appearance.Texture.FaceTextures[idx].TextureID = AppearanceManager.DEFAULT_AVATAR_TEXTURE; + face = sp.Appearance.Texture.FaceTextures[idx]; + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; continue; } } - - -// m_log.DebugFormat( -// "[AVFACTORY]: Looking for texture {0}, id {1} for {2} {3}", -// face.TextureID, idx, client.Name, client.AgentId); + - // if the texture is one of the "defaults" then skip it - // this should probably be more intelligent (skirt texture doesnt matter - // if the avatar isnt wearing a skirt) but if any of the main baked - // textures is default then the rest should be as well if (face.TextureID == UUID.Zero || face.TextureID == AppearanceManager.DEFAULT_AVATAR_TEXTURE) + { + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; continue; - + } + defonly = false; // found a non-default texture reference - if (cache != null) + if(wearableCache[idx].TextureID != sp.Appearance.Texture.FaceTextures[idx].TextureID) { - if (!cache.Check(face.TextureID.ToString())) - return false; + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + wearableCache[idx].TextureAsset = null; + continue; } - else + + wearableCache[idx].TextureAsset = null; + if (cache != null) { - if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) - return false; + wearableCache[idx].TextureAsset = m_scene.AssetService.Get(face.TextureID.ToString()); + if (wearableCache[idx].TextureAsset == null) + { + wearableCache[idx].CacheId = UUID.Zero; + wearableCache[idx].TextureID = UUID.Zero; + } + else + hits++; } } -// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); + sp.Appearance.WearableCacheItems = wearableCache; + + m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1} {2} {3}", sp.Name, sp.UUID, hits, defonly.ToString()); + // debug + for (int iter = 0; iter < AvatarAppearance.BAKE_INDICES.Length; iter++) + { + int j = AvatarAppearance.BAKE_INDICES[iter]; + m_log.Debug("[ValidateBakedCache] {" + iter + "/" + + sp.Appearance.WearableCacheItems[j].TextureIndex + "}: c-" + + sp.Appearance.WearableCacheItems[j].CacheId + ", t-" + + sp.Appearance.WearableCacheItems[j].TextureID); + } // If we only found default textures, then the appearance is not cached return (defonly ? false : true); } - public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) { int texturesRebaked = 0; diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index f41a828..965d7c2 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -3502,7 +3502,7 @@ namespace OpenSim.Region.Framework.Scenes // If we aren't using a cached appearance, then clear out the baked textures if (!cachedappearance) { - Appearance.ResetAppearance(); +// Appearance.ResetAppearance(); // save what ???? // maybe needed so the tryretry repair works? if (m_scene.AvatarFactory != null) -- cgit v1.1