From 37889eb3fa8e172fb8c1b73a5c5443fc7bf4e5a3 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Mon, 5 Dec 2011 18:35:03 +0000 Subject: [PATCH 1/2] For the GetTexture capability, if a data range is requested that covers the whole asset length, return HTTP PartialContent instead of NotFound NotFound is obviously wrong, and this change stops viewer 3.2.2 (and v probably earlier) complaining in the log about missing textures that are actually present. We still return PartialContent even if the range requested is a superset of the data range as per httpd's behaviour https://issues.apache.org/bugzilla/show_bug.cgi?id=51878 Viewer 3.2.2 and very probably earlier appear happy with this. Whether fixing this NotFound bug has any practical effect apart from resolve viewer log messages is unknown. --- .../Handlers/GetTexture/GetTextureHandler.cs | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs index 245d9312d2..7ab30ceb27 100644 --- a/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs +++ b/OpenSim/Capabilities/Handlers/GetTexture/GetTextureHandler.cs @@ -111,6 +111,10 @@ namespace OpenSim.Capabilities.Handlers m_log.Warn("[GETTEXTURE]: Failed to parse a texture_id from GetTexture request: " + httpRequest.Url); } +// m_log.DebugFormat( +// "[GETTEXTURE]: For texture {0} sending back response {1}, data length {2}", +// textureID, httpResponse.StatusCode, httpResponse.ContentLength); + httpResponse.Send(); return null; } @@ -210,7 +214,7 @@ namespace OpenSim.Capabilities.Handlers private void WriteTextureData(OSHttpRequest request, OSHttpResponse response, AssetBase texture, string format) { string range = request.Headers.GetOne("Range"); - //m_log.DebugFormat("[GETTEXTURE]: Range {0}", range); + if (!String.IsNullOrEmpty(range)) // JP2's only { // Range request @@ -222,23 +226,27 @@ namespace OpenSim.Capabilities.Handlers if (start >= texture.Data.Length) { response.StatusCode = (int)System.Net.HttpStatusCode.RequestedRangeNotSatisfiable; - return; } + else + { + end = Utils.Clamp(end, 0, texture.Data.Length - 1); + start = Utils.Clamp(start, 0, end); + int len = end - start + 1; - end = Utils.Clamp(end, 0, texture.Data.Length - 1); - 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); - - if (len < texture.Data.Length) + // 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. response.StatusCode = (int)System.Net.HttpStatusCode.PartialContent; - response.ContentLength = len; - response.ContentType = texture.Metadata.ContentType; - response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); - - response.Body.Write(texture.Data, start, len); + response.ContentLength = len; + response.ContentType = texture.Metadata.ContentType; + response.AddHeader("Content-Range", String.Format("bytes {0}-{1}/{2}", start, end, texture.Data.Length)); + + response.Body.Write(texture.Data, start, len); + } } else { @@ -257,6 +265,10 @@ namespace OpenSim.Capabilities.Handlers response.ContentType = "image/" + format; response.Body.Write(texture.Data, 0, texture.Data.Length); } + +// m_log.DebugFormat( +// "[GETTEXTURE]: For texture {0} requested range {1} responded {2} with content length {3} (actual {4})", +// texture.FullID, range, response.StatusCode, response.ContentLength, texture.Data.Length); } private bool TryParseRange(string header, out int start, out int end) @@ -275,7 +287,6 @@ namespace OpenSim.Capabilities.Handlers return false; } - private byte[] ConvertTextureData(AssetBase texture, string format) { m_log.DebugFormat("[GETTEXTURE]: Converting texture {0} to {1}", texture.ID, format); From 66f4ce354f57646de32b376cba79dfc6ded17c14 Mon Sep 17 00:00:00 2001 From: Melanie Date: Mon, 5 Dec 2011 19:01:14 +0000 Subject: [PATCH 2/2] Fix CHANGED_TEXTURE and CHANGED_COLOR. --- .../DynamicTexture/DynamicTextureModule.cs | 4 +- .../Framework/Scenes/SceneObjectPart.cs | 82 ++++++++++--------- .../Scripting/Minimodule/SOPObjectMaterial.cs | 10 +-- .../Shared/Api/Implementation/LSL_Api.cs | 36 ++++---- 4 files changed, 67 insertions(+), 65 deletions(-) diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index f2c8b3dd54..18bd0186b8 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -355,7 +355,7 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture // I'm pretty sure noone whats to set fullbright true if it wasn't true before. // tmptex.DefaultTexture.Fullbright = true; - part.UpdateTexture(tmptex); + part.UpdateTextureEntry(tmptex.GetBytes()); } if (oldID != UUID.Zero && ((Disp & DISP_EXPIRE) != 0)) @@ -437,4 +437,4 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture #endregion } -} \ No newline at end of file +} diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index dcbcfa312b..c8b39a4085 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -3178,7 +3178,10 @@ namespace OpenSim.Region.Framework.Scenes /// public void SetFaceColor(Vector3 color, int face) { - Primitive.TextureEntry tex = Shape.Textures; + // The only way to get a deep copy/ If we don't do this, we can + // mever detect color changes further down. + Byte[] buf = Shape.Textures.GetBytes(); + Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); Color4 texcolor; if (face >= 0 && face < GetNumberOfSides()) { @@ -3187,8 +3190,7 @@ namespace OpenSim.Region.Framework.Scenes texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); tex.FaceTextures[face].RGBA = texcolor; - UpdateTexture(tex); - TriggerScriptChangedEvent(Changed.COLOR); + UpdateTextureEntry(tex.GetBytes()); return; } else if (face == ALL_SIDES) @@ -3209,8 +3211,7 @@ namespace OpenSim.Region.Framework.Scenes texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); tex.DefaultTexture.RGBA = texcolor; } - UpdateTexture(tex); - TriggerScriptChangedEvent(Changed.COLOR); + UpdateTextureEntry(tex.GetBytes()); return; } } @@ -4537,49 +4538,50 @@ namespace OpenSim.Region.Framework.Scenes } } - /// - /// Update the textures on the part. - /// - /// - /// Added to handle bug in libsecondlife's TextureEntry.ToBytes() - /// not handling RGBA properly. Cycles through, and "fixes" the color - /// info - /// - /// - public void UpdateTexture(Primitive.TextureEntry tex) - { - //Color4 tmpcolor; - //for (uint i = 0; i < 32; i++) - //{ - // if (tex.FaceTextures[i] != null) - // { - // tmpcolor = tex.GetFace((uint) i).RGBA; - // tmpcolor.A = tmpcolor.A*255; - // tmpcolor.R = tmpcolor.R*255; - // tmpcolor.G = tmpcolor.G*255; - // tmpcolor.B = tmpcolor.B*255; - // tex.FaceTextures[i].RGBA = tmpcolor; - // } - //} - //tmpcolor = tex.DefaultTexture.RGBA; - //tmpcolor.A = tmpcolor.A*255; - //tmpcolor.R = tmpcolor.R*255; - //tmpcolor.G = tmpcolor.G*255; - //tmpcolor.B = tmpcolor.B*255; - //tex.DefaultTexture.RGBA = tmpcolor; - UpdateTextureEntry(tex.GetBytes()); - } - /// /// Update the texture entry for this part. /// /// public void UpdateTextureEntry(byte[] textureEntry) { - m_shape.TextureEntry = textureEntry; - TriggerScriptChangedEvent(Changed.TEXTURE); + Primitive.TextureEntry newTex = new Primitive.TextureEntry(textureEntry, 0, textureEntry.Length); + Primitive.TextureEntry oldTex = Shape.Textures; + Changed changeFlags = 0; + + for (int i = 0 ; i < GetNumberOfSides(); i++) + { + Primitive.TextureEntryFace newFace = newTex.DefaultTexture; + Primitive.TextureEntryFace oldFace = oldTex.DefaultTexture; + + if (oldTex.FaceTextures[i] != null) + oldFace = oldTex.FaceTextures[i]; + if (newTex.FaceTextures[i] != null) + newFace = newTex.FaceTextures[i]; + + Color4 oldRGBA = oldFace.RGBA; + Color4 newRGBA = newFace.RGBA; + + if (oldRGBA.R != newRGBA.R || + oldRGBA.G != newRGBA.G || + oldRGBA.B != newRGBA.B || + oldRGBA.A != newRGBA.A) + changeFlags |= Changed.COLOR; + + if (oldFace.TextureID != newFace.TextureID) + changeFlags |= Changed.TEXTURE; + + // Max change, skip the rest of testing + if (changeFlags == (Changed.TEXTURE | Changed.COLOR)) + break; + } + + m_shape.TextureEntry = textureEntry; + if (changeFlags != 0) + TriggerScriptChangedEvent(changeFlags); + UpdateFlag = UpdateRequired.FULL; ParentGroup.HasGroupChanged = true; + //This is madness.. //ParentGroup.ScheduleGroupForFullUpdate(); //This is sparta diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectMaterial.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectMaterial.cs index 0cba6afb6c..cea738cddb 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectMaterial.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SOPObjectMaterial.cs @@ -55,7 +55,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); texface.RGBA = new Color4(value.R,value.G,value.B,value.A); tex.FaceTextures[m_face] = texface; - m_parent.UpdateTexture(tex); + m_parent.UpdateTextureEntry(tex.GetBytes()); } } @@ -72,7 +72,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); texface.TextureID = value; tex.FaceTextures[m_face] = texface; - m_parent.UpdateTexture(tex); + m_parent.UpdateTextureEntry(tex.GetBytes()); } } @@ -97,7 +97,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); texface.Fullbright = value; tex.FaceTextures[m_face] = texface; - m_parent.UpdateTexture(tex); + m_parent.UpdateTextureEntry(tex.GetBytes()); } } @@ -110,7 +110,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); texface.Glow = (float) value; tex.FaceTextures[m_face] = texface; - m_parent.UpdateTexture(tex); + m_parent.UpdateTextureEntry(tex.GetBytes()); } } @@ -123,7 +123,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule Primitive.TextureEntryFace texface = tex.CreateFace((uint)m_face); texface.Shiny = value ? Shininess.High : Shininess.None; tex.FaceTextures[m_face] = texface; - m_parent.UpdateTexture(tex); + m_parent.UpdateTextureEntry(tex.GetBytes()); } } diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6c418df6ad..6d067b02cd 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -1424,7 +1424,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { tex.CreateFace((uint) face); tex.FaceTextures[face].TexMapType = textype; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } else if (face == ScriptBaseClass.ALL_SIDES) @@ -1437,7 +1437,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } tex.DefaultTexture.TexMapType = textype; } - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } } @@ -1449,7 +1449,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { tex.CreateFace((uint) face); tex.FaceTextures[face].Glow = glow; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } else if (face == ScriptBaseClass.ALL_SIDES) @@ -1462,7 +1462,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } tex.DefaultTexture.Glow = glow; } - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } } @@ -1497,7 +1497,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api tex.CreateFace((uint) face); tex.FaceTextures[face].Shiny = sval; tex.FaceTextures[face].Bump = bump; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } else if (face == ScriptBaseClass.ALL_SIDES) @@ -1512,7 +1512,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api tex.DefaultTexture.Shiny = sval; tex.DefaultTexture.Bump = bump; } - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } } @@ -1524,7 +1524,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api { tex.CreateFace((uint) face); tex.FaceTextures[face].Fullbright = bright; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } else if (face == ScriptBaseClass.ALL_SIDES) @@ -1537,7 +1537,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } tex.DefaultTexture.Fullbright = bright; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } } @@ -1593,7 +1593,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api texcolor = tex.CreateFace((uint)face).RGBA; texcolor.A = Util.Clip((float)alpha, 0.0f, 1.0f); tex.FaceTextures[face].RGBA = texcolor; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } else if (face == ScriptBaseClass.ALL_SIDES) @@ -1617,7 +1617,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api tex.DefaultTexture.RGBA = texcolor; } - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } } @@ -1774,7 +1774,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); texface.TextureID = textureID; tex.FaceTextures[face] = texface; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } else if (face == ScriptBaseClass.ALL_SIDES) @@ -1787,7 +1787,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } tex.DefaultTexture.TextureID = textureID; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } } @@ -1809,7 +1809,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api texface.RepeatU = (float)u; texface.RepeatV = (float)v; tex.FaceTextures[face] = texface; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } if (face == ScriptBaseClass.ALL_SIDES) @@ -1824,7 +1824,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } tex.DefaultTexture.RepeatU = (float)u; tex.DefaultTexture.RepeatV = (float)v; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } } @@ -1845,7 +1845,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api texface.OffsetU = (float)u; texface.OffsetV = (float)v; tex.FaceTextures[face] = texface; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } if (face == ScriptBaseClass.ALL_SIDES) @@ -1860,7 +1860,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } tex.DefaultTexture.OffsetU = (float)u; tex.DefaultTexture.OffsetV = (float)v; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } } @@ -1880,7 +1880,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api Primitive.TextureEntryFace texface = tex.CreateFace((uint)face); texface.Rotation = (float)rotation; tex.FaceTextures[face] = texface; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } if (face == ScriptBaseClass.ALL_SIDES) @@ -1893,7 +1893,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } } tex.DefaultTexture.Rotation = (float)rotation; - part.UpdateTexture(tex); + part.UpdateTextureEntry(tex.GetBytes()); return; } }