diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index ae6c44bb6a..9b43a8059d 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -163,7 +163,7 @@ namespace OpenSim.Capabilities.Handlers if (texture == null) { - //m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); +// m_log.DebugFormat("[GETTEXTURE]: texture was not in the cache"); // Fetch locally or remotely. Misses return a 404 texture = m_assetService.Get(textureID.ToString()); @@ -197,7 +197,7 @@ namespace OpenSim.Capabilities.Handlers } else // it was on the cache { - //m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); +// m_log.DebugFormat("[GETTEXTURE]: texture was in the cache"); WriteTextureData(httpRequest, httpResponse, texture, format); return true; } @@ -219,12 +219,30 @@ namespace OpenSim.Capabilities.Handlers int start, end; if (TryParseRange(range, out start, out end)) { - // Before clamping start make sure we can satisfy it in order to avoid // sending back the last byte instead of an error status if (start >= texture.Data.Length) { - response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; + m_log.DebugFormat( + "[GETTEXTURE]: Client requested range for texture {0} starting at {1} but texture has end of {2}", + texture.ID, start, texture.Data.Length); + + // Stricly speaking, as per http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html, we should be sending back + // Requested Range Not Satisfiable (416) here. However, it appears that at least recent implementations + // of the Linden Lab viewer (3.2.1 and 3.3.4 and probably earlier), a viewer that has previously + // received a very small texture may attempt to fetch bytes from the server past the + // range of data that it received originally. Whether this happens appears to depend on whether + // the viewer's estimation of how large a request it needs to make for certain discard levels + // (http://wiki.secondlife.com/wiki/Image_System#Discard_Level_and_Mip_Mapping), chiefly discard + // level 2. If this estimate is greater than the total texture size, returning a RequestedRangeNotSatisfiable + // here will cause the viewer to treat the texture as bad and never display the full resolution + // However, if we return PartialContent (or OK) instead, the viewer will display that resolution. + +// response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; +// response.AddHeader("Content-Range", String.Format("bytes */{0}", texture.Data.Length)); +// response.StatusCode = (int)System.Net.HttpStatusCode.OK; + response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; + response.ContentType = texture.Metadata.ContentType; } else { @@ -232,12 +250,18 @@ namespace OpenSim.Capabilities.Handlers start = Utils.Clamp(start, 0, end); int len = end - start + 1; - //m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); +// m_log.Debug("Serving " + start + " to " + end + " of " + texture.Data.Length + " bytes for texture " + texture.ID); // Always return PartialContent, even if the range covered the entire data length // We were accidentally sending back 404 before in this situation // https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 supports sending 206 even if the // entire range is requested, and viewer 3.2.2 (and very probably earlier) seems fine with this. + // + // We also do not want to send back OK even if the whole range was satisfiable since this causes + // HTTP textures on at least Imprudence 1.4.0-beta2 to never display the final texture quality. +// if (end > maxEnd) +// response.StatusCode = (int)System.Net.HttpStatusCode.OK; +// else response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; response.ContentLength = len; diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 3eedf498c4..e09f1a9613 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -42,7 +42,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { 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; @@ -249,10 +249,18 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture } } +// m_log.DebugFormat( +// "[DYNAMIC TEXTURE MODULE]: Requesting generation of new dynamic texture for {0} in {1}", +// part.Name, part.ParentGroup.Scene.Name); + RenderPlugins[contentType].AsyncConvertData(updater.UpdaterID, data, extraParams); } else { +// m_log.DebugFormat( +// "[DYNAMIC TEXTURE MODULE]: Reusing cached texture {0} for {1} in {2}", +// objReusableTextureUUID, part.Name, part.ParentGroup.Scene.Name); + // No need to add to updaters as the texture is always the same. Not that this functionality // apppears to be implemented anyway. updater.UpdatePart(part, (UUID)objReusableTextureUUID); @@ -448,8 +456,10 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture IJ2KDecoder cacheLayerDecode = scene.RequestModuleInterface(); if (cacheLayerDecode != null) { - cacheLayerDecode.Decode(asset.FullID, asset.Data); - cacheLayerDecode = null; + if (!cacheLayerDecode.Decode(asset.FullID, asset.Data)) + m_log.WarnFormat( + "[DYNAMIC TEXTURE MODULE]: Decoding of dynamically generated asset {0} for {1} in {2} failed", + asset.ID, part.Name, part.ParentGroup.Scene.Name); } UUID oldID = UpdatePart(part, asset.FullID); diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 4268f2e98a..0e7051ee0d 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -46,6 +46,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender { public class VectorRenderModule : IRegionModule, IDynamicTextureRender { + // These fields exist for testing purposes, please do not remove. +// private static bool s_flipper; +// private static byte[] s_asset1Data; +// private static byte[] s_asset2Data; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; @@ -161,6 +166,13 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender { m_textureManager.RegisterRender(GetContentType(), this); } + + // This code exists for testing purposes, please do not remove. +// s_asset1Data = m_scene.AssetService.Get("00000000-0000-1111-9999-000000000001").Data; +// s_asset1Data = m_scene.AssetService.Get("9f4acf0d-1841-4e15-bdb8-3a12efc9dd8f").Data; + + // Terrain dirt - smallest bin/assets file (6004 bytes) +// s_asset2Data = m_scene.AssetService.Get("b8d3965a-ad78-bf43-699b-bff8eca6c975").Data; } public void Close() @@ -364,6 +376,14 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender } byte[] imageJ2000 = new byte[0]; + + // This code exists for testing purposes, please do not remove. +// if (s_flipper) +// imageJ2000 = s_asset1Data; +// else +// imageJ2000 = s_asset2Data; +// +// s_flipper = !s_flipper; try {