From bdc13455011c9de2877813138a49d83fc52d3142 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 2 Oct 2009 13:08:15 -0700 Subject: * Removed even more unnecessary state variables from J2KImage * Fixed the incorrect "out of memory?" exception messages and replaced them with useful information * Cleaned up J2KImage and LLImageManager to conform to coding conventions --- OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs | 278 +++++++++------------ .../Region/ClientStack/LindenUDP/LLImageManager.cs | 46 ++-- 2 files changed, 142 insertions(+), 182 deletions(-) (limited to 'OpenSim/Region/ClientStack') diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs index 5f549b5..0e3630c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs @@ -47,69 +47,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - public uint m_lastSequence; - public float m_requestedPriority; - public uint m_requestedPacketNumber; - public sbyte m_requestedDiscardLevel; - public UUID m_requestedUUID; - public IJ2KDecoder m_j2kDecodeModule; - public IAssetService m_assetCache; - public OpenJPEG.J2KLayerInfo[] m_layers; - public bool m_decoded; - public bool m_hasasset; - public C5.IPriorityQueueHandle m_priorityQueueHandle; - - private uint m_packetNumber; - private bool m_decoderequested; - private bool m_asset_requested; - private bool m_sentinfo; + public uint LastSequence; + public float Priority; + public uint StartPacket; + public sbyte DiscardLevel; + public UUID TextureID; + public IJ2KDecoder J2KDecoder; + public IAssetService AssetService; + public OpenJPEG.J2KLayerInfo[] Layers; + public bool IsDecoded; + public bool HasAsset; + public C5.IPriorityQueueHandle PriorityQueueHandle; + + private uint m_currentPacket; + private bool m_decodeRequested; + private bool m_assetRequested; + private bool m_sentInfo; private uint m_stopPacket; - private AssetBase m_asset; - private int m_assetDataLength; + private byte[] m_asset; private LLImageManager m_imageManager; - #region Properties - - public uint m_pPacketNumber - { - get { return m_packetNumber; } - } - public uint m_pStopPacketNumber - { - get { return m_stopPacket; } - } - - public byte[] Data - { - get - { - if (m_asset != null) - return m_asset.Data; - else - return null; - } - } - - public ushort TexturePacketCount() - { - if (!m_decoded) - return 0; - - try - { - return (ushort)(((m_assetDataLength - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1); - } - catch (Exception) - { - // If the asset is missing/destroyed/truncated, we will land - // here - // - return 0; - } - } - - #endregion Properties - public J2KImage(LLImageManager imageManager) { m_imageManager = imageManager; @@ -117,33 +74,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP public bool SendPackets(LLClientView client, int maxpack) { - if (m_packetNumber <= m_stopPacket) + if (m_currentPacket <= m_stopPacket) { bool SendMore = true; - if (!m_sentinfo || (m_packetNumber == 0)) + if (!m_sentInfo || (m_currentPacket == 0)) { if (SendFirstPacket(client)) { SendMore = false; } - m_sentinfo = true; - m_packetNumber++; + m_sentInfo = true; + m_currentPacket++; } - // bool ignoreStop = false; - if (m_packetNumber < 2) + if (m_currentPacket < 2) { - m_packetNumber = 2; + m_currentPacket = 2; } int count = 0; - while (SendMore && count < maxpack && m_packetNumber <= m_stopPacket) + while (SendMore && count < maxpack && m_currentPacket <= m_stopPacket) { count++; SendMore = SendPacket(client); - m_packetNumber++; + m_currentPacket++; } - if (m_packetNumber > m_stopPacket) + if (m_currentPacket > m_stopPacket) return true; } @@ -156,68 +112,68 @@ namespace OpenSim.Region.ClientStack.LindenUDP //and assign the real discardLevel and packetNumber //assuming of course that the connected client might be bonkers - if (!m_hasasset) + if (!HasAsset) { - if (!m_asset_requested) + if (!m_assetRequested) { - m_asset_requested = true; - m_assetCache.Get(m_requestedUUID.ToString(), this, AssetReceived); + m_assetRequested = true; + AssetService.Get(TextureID.ToString(), this, AssetReceived); } } else { - if (!m_decoded) + if (!IsDecoded) { //We need to decode the requested image first - if (!m_decoderequested) + if (!m_decodeRequested) { //Request decode - m_decoderequested = true; + m_decodeRequested = true; // Do we have a jpeg decoder? - if (m_j2kDecodeModule != null) + if (J2KDecoder != null) { - if (Data == null) + if (m_asset == null) { - J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); + J2KDecodedCallback(TextureID, new OpenJPEG.J2KLayerInfo[0]); } else { // Send it off to the jpeg decoder - m_j2kDecodeModule.BeginDecode(m_requestedUUID, Data, J2KDecodedCallback); + J2KDecoder.BeginDecode(TextureID, m_asset, J2KDecodedCallback); } } else { - J2KDecodedCallback(m_requestedUUID, new OpenJPEG.J2KLayerInfo[0]); + J2KDecodedCallback(TextureID, new OpenJPEG.J2KLayerInfo[0]); } } } else { // Check for missing image asset data - if (m_asset == null || m_asset.Data == null) + if (m_asset == null) { - // FIXME: - m_packetNumber = m_stopPacket; + m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing asset data (no missing image texture?). Canceling texture transfer"); + m_currentPacket = m_stopPacket; return; } - if (m_requestedDiscardLevel >= 0 || m_stopPacket == 0) + if (DiscardLevel >= 0 || m_stopPacket == 0) { - int maxDiscardLevel = Math.Max(0, m_layers.Length - 1); + int maxDiscardLevel = Math.Max(0, Layers.Length - 1); // Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel - if (m_requestedDiscardLevel < 0 && m_stopPacket == 0) - m_requestedDiscardLevel = (sbyte)maxDiscardLevel; + if (DiscardLevel < 0 && m_stopPacket == 0) + DiscardLevel = (sbyte)maxDiscardLevel; // Clamp at the highest discard level - m_requestedDiscardLevel = (sbyte)Math.Min(m_requestedDiscardLevel, maxDiscardLevel); + DiscardLevel = (sbyte)Math.Min(DiscardLevel, maxDiscardLevel); //Calculate the m_stopPacket - if (m_layers.Length > 0) + if (Layers.Length > 0) { - m_stopPacket = (uint)GetPacketForBytePosition(m_layers[(m_layers.Length - 1) - m_requestedDiscardLevel].End); + m_stopPacket = (uint)GetPacketForBytePosition(Layers[(Layers.Length - 1) - DiscardLevel].End); //I don't know why, but the viewer seems to expect the final packet if the file //is just one packet bigger. if (TexturePacketCount() == m_stopPacket + 1) @@ -230,7 +186,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_stopPacket = TexturePacketCount(); } - m_packetNumber = m_requestedPacketNumber; + m_currentPacket = StartPacket; } if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0) @@ -242,20 +198,52 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + private bool SendFirstPacket(LLClientView client) + { + if (m_asset == null) + { + m_log.Warn("[J2KIMAGE]: Sending ImageNotInDatabase for texture " + TextureID); + client.SendImageNotFound(TextureID); + return true; + } + else if (m_asset.Length <= FIRST_PACKET_SIZE) + { + // We have less then one packet's worth of data + client.SendImageFirstPart(1, TextureID, (uint)m_asset.Length, m_asset, 2); + m_stopPacket = 0; + return true; + } + else + { + // This is going to be a multi-packet texture download + byte[] firstImageData = new byte[FIRST_PACKET_SIZE]; + + try { Buffer.BlockCopy(m_asset, 0, firstImageData, 0, FIRST_PACKET_SIZE); } + catch (Exception) + { + m_log.ErrorFormat("[J2KIMAGE]: Texture block copy for the first packet failed. textureid={0}, assetlength={1}", TextureID, m_asset.Length); + return true; + } + + client.SendImageFirstPart(TexturePacketCount(), TextureID, (uint)m_asset.Length, firstImageData, (byte)ImageCodec.J2C); + } + return false; + } + private bool SendPacket(LLClientView client) { bool complete = false; - int imagePacketSize = ((int)m_packetNumber == (TexturePacketCount())) ? LastPacketSize() : IMAGE_PACKET_SIZE; + int imagePacketSize = ((int)m_currentPacket == (TexturePacketCount())) ? LastPacketSize() : IMAGE_PACKET_SIZE; try { - if ((CurrentBytePosition() + IMAGE_PACKET_SIZE) > m_assetDataLength) + if ((CurrentBytePosition() + IMAGE_PACKET_SIZE) > m_asset.Length) { imagePacketSize = LastPacketSize(); complete = true; - if ((CurrentBytePosition() + imagePacketSize) > m_assetDataLength) + if ((CurrentBytePosition() + imagePacketSize) > m_asset.Length) { - imagePacketSize = m_assetDataLength - CurrentBytePosition(); + imagePacketSize = m_asset.Length - CurrentBytePosition(); complete = true; } } @@ -266,27 +254,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (imagePacketSize > 0) { byte[] imageData = new byte[imagePacketSize]; - try - { - Buffer.BlockCopy(m_asset.Data, CurrentBytePosition(), imageData, 0, imagePacketSize); - } + int currentPosition = CurrentBytePosition(); + + try { Buffer.BlockCopy(m_asset, currentPosition, imageData, 0, imagePacketSize); } catch (Exception e) { - m_log.Error("Error copying texture block. Out of memory? imagePacketSize was " + imagePacketSize.ToString() + " on packet " + m_packetNumber.ToString() + " out of " + m_stopPacket.ToString() + ". Exception: " + e.ToString()); + m_log.ErrorFormat("[J2KIMAGE]: Texture block copy for the first packet failed. textureid={0}, assetlength={1}, currentposition={2}, imagepacketsize={3}, exception={4}", + TextureID, m_asset.Length, currentPosition, imagePacketSize, e.Message); return false; } //Send the packet - client.SendImageNextPart((ushort)(m_packetNumber - 1), m_requestedUUID, imageData); - } - if (complete) - { - return false; - } - else - { - return true; + client.SendImageNextPart((ushort)(m_currentPacket - 1), TextureID, imageData); } + + return !complete; } catch (Exception) { @@ -294,6 +276,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + private ushort TexturePacketCount() + { + if (!IsDecoded) + return 0; + + if (m_asset == null) + return 0; + + if (m_asset.Length <= FIRST_PACKET_SIZE) + return 1; + + return (ushort)(((m_asset.Length - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1); + } + private int GetPacketForBytePosition(int bytePosition) { return ((bytePosition - FIRST_PACKET_SIZE + IMAGE_PACKET_SIZE - 1) / IMAGE_PACKET_SIZE) + 1; @@ -301,9 +297,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int LastPacketSize() { - if (m_packetNumber == 1) - return m_assetDataLength; - int lastsize = (m_assetDataLength - FIRST_PACKET_SIZE) % IMAGE_PACKET_SIZE; + if (m_currentPacket == 1) + return m_asset.Length; + int lastsize = (m_asset.Length - FIRST_PACKET_SIZE) % IMAGE_PACKET_SIZE; //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary if (lastsize == 0) { @@ -314,12 +310,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP private int CurrentBytePosition() { - if (m_packetNumber == 0) + if (m_currentPacket == 0) return 0; - if (m_packetNumber == 1) + if (m_currentPacket == 1) return FIRST_PACKET_SIZE; - int result = FIRST_PACKET_SIZE + ((int)m_packetNumber - 2) * IMAGE_PACKET_SIZE; + int result = FIRST_PACKET_SIZE + ((int)m_currentPacket - 2) * IMAGE_PACKET_SIZE; if (result < 0) { result = FIRST_PACKET_SIZE; @@ -327,68 +323,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP return result; } - private bool SendFirstPacket(LLClientView client) - { - // this means we don't have - if (Data == null) - { - client.SendImageNotFound(m_requestedUUID); - m_log.WarnFormat("[TEXTURE]: Got null Data element on a asset {0}.. and the missing image Data property is also null", m_requestedUUID); - return true; - } - // Do we have less then 1 packet's worth of data? - else if (m_assetDataLength <= FIRST_PACKET_SIZE) - { - // Send only 1 packet - client.SendImageFirstPart(1, m_requestedUUID, (uint)m_assetDataLength, m_asset.Data, 2); - m_stopPacket = 0; - return true; - } - else - { - byte[] firstImageData = new byte[FIRST_PACKET_SIZE]; - try - { - Buffer.BlockCopy(m_asset.Data, 0, firstImageData, 0, (int)FIRST_PACKET_SIZE); - client.SendImageFirstPart(TexturePacketCount(), m_requestedUUID, (uint)m_assetDataLength, firstImageData, 2); - } - catch (Exception) - { - m_log.Error("Texture block copy failed. Possibly out of memory?"); - return true; - } - } - return false; - } - private void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) { - m_layers = layers; - m_decoded = true; + Layers = layers; + IsDecoded = true; RunUpdate(); } private void AssetDataCallback(UUID AssetID, AssetBase asset) { - m_hasasset = true; + HasAsset = true; if (asset == null || asset.Data == null) { if (m_imageManager.MissingImage != null) { - m_asset = m_imageManager.MissingImage; - m_assetDataLength = m_asset.Data.Length; + m_asset = m_imageManager.MissingImage.Data; } else { m_asset = null; - m_decoded = true; + IsDecoded = true; } } else { - m_asset = asset; - m_assetDataLength = m_asset.Data.Length; + m_asset = asset.Data; } RunUpdate(); diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index a484fdf..d641b6c 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs @@ -45,7 +45,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { public int Compare(J2KImage x, J2KImage y) { - return x.m_requestedPriority.CompareTo(y.m_requestedPriority); + return x.Priority.CompareTo(y.Priority); } } @@ -94,7 +94,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // Do a linear search for this texture download lock (m_priorityQueue) - m_priorityQueue.Find(delegate(J2KImage img) { return img.m_requestedUUID == newRequest.RequestedAssetID; }, out imgrequest); + m_priorityQueue.Find(delegate(J2KImage img) { return img.TextureID == newRequest.RequestedAssetID; }, out imgrequest); if (imgrequest != null) { @@ -105,7 +105,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP try { lock (m_priorityQueue) - m_priorityQueue.Delete(imgrequest.m_priorityQueueHandle); + m_priorityQueue.Delete(imgrequest.PriorityQueueHandle); } catch (Exception) { } } @@ -116,29 +116,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP //Check the packet sequence to make sure this isn't older than //one we've already received - if (newRequest.requestSequence > imgrequest.m_lastSequence) + if (newRequest.requestSequence > imgrequest.LastSequence) { //Update the sequence number of the last RequestImage packet - imgrequest.m_lastSequence = newRequest.requestSequence; + imgrequest.LastSequence = newRequest.requestSequence; //Update the requested discard level - imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; + imgrequest.DiscardLevel = newRequest.DiscardLevel; //Update the requested packet number - imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; + imgrequest.StartPacket = newRequest.PacketNumber; //Update the requested priority - imgrequest.m_requestedPriority = newRequest.Priority; + imgrequest.Priority = newRequest.Priority; try { lock (m_priorityQueue) - m_priorityQueue.Replace(imgrequest.m_priorityQueueHandle, imgrequest); + m_priorityQueue.Replace(imgrequest.PriorityQueueHandle, imgrequest); } catch (Exception) { - imgrequest.m_priorityQueueHandle = null; + imgrequest.PriorityQueueHandle = null; lock (m_priorityQueue) - m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest); + m_priorityQueue.Add(ref imgrequest.PriorityQueueHandle, imgrequest); } //Run an update @@ -161,29 +161,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP imgrequest = new J2KImage(this); //Assign our decoder module - imgrequest.m_j2kDecodeModule = m_j2kDecodeModule; + imgrequest.J2KDecoder = m_j2kDecodeModule; //Assign our asset cache module - imgrequest.m_assetCache = m_assetCache; + imgrequest.AssetService = m_assetCache; //Assign the requested discard level - imgrequest.m_requestedDiscardLevel = newRequest.DiscardLevel; + imgrequest.DiscardLevel = newRequest.DiscardLevel; //Assign the requested packet number - imgrequest.m_requestedPacketNumber = newRequest.PacketNumber; + imgrequest.StartPacket = newRequest.PacketNumber; //Assign the requested priority - imgrequest.m_requestedPriority = newRequest.Priority; + imgrequest.Priority = newRequest.Priority; //Assign the asset uuid - imgrequest.m_requestedUUID = newRequest.RequestedAssetID; + imgrequest.TextureID = newRequest.RequestedAssetID; //Assign the requested priority - imgrequest.m_requestedPriority = newRequest.Priority; + imgrequest.Priority = newRequest.Priority; //Add this download to the priority queue lock (m_priorityQueue) - m_priorityQueue.Add(ref imgrequest.m_priorityQueueHandle, imgrequest); + m_priorityQueue.Add(ref imgrequest.PriorityQueueHandle, imgrequest); //Run an update imgrequest.RunUpdate(); @@ -249,12 +249,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP lock (m_priorityQueue) imagereq = m_priorityQueue.FindMax(); - if (imagereq.m_decoded == true) + if (imagereq.IsDecoded == true) { // we need to test this here now that we are dropping assets - if (!imagereq.m_hasasset) + if (!imagereq.HasAsset) { - m_log.WarnFormat("[LLIMAGE MANAGER]: Re-requesting the image asset {0}", imagereq.m_requestedUUID); + m_log.WarnFormat("[LLIMAGE MANAGER]: Re-requesting the image asset {0}", imagereq.TextureID); imagereq.RunUpdate(); continue; } @@ -268,7 +268,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP try { lock (m_priorityQueue) - m_priorityQueue.Delete(imagereq.m_priorityQueueHandle); + m_priorityQueue.Delete(imagereq.PriorityQueueHandle); } catch (Exception) { } } -- cgit v1.1 From 332d3eb1bb4aecf67d56e64686db3e3851b848ea Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 2 Oct 2009 16:53:35 -0700 Subject: * Removed code that is no longer used with Melanie's queue callback optimization * Moved all priority queue access to helper functions to improve reliability and readability * New version of CSJ2K.dll (from libomv source tree) that fixes a JPEG2000 comment decoding bug --- .../Region/ClientStack/LindenUDP/LLImageManager.cs | 214 +++++++++------------ 1 file changed, 88 insertions(+), 126 deletions(-) (limited to 'OpenSim/Region/ClientStack') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index d641b6c..facfb9d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs @@ -50,43 +50,38 @@ namespace OpenSim.Region.ClientStack.LindenUDP } private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private bool m_shuttingdown = false; - private long m_lastloopprocessed = 0; - private AssetBase m_missingImage = null; - + private bool m_shuttingdown; + private long m_lastloopprocessed; + private AssetBase m_missingImage; private LLClientView m_client; //Client we're assigned to private IAssetService m_assetCache; //Asset Cache private IJ2KDecoder m_j2kDecodeModule; //Our J2K module private C5.IntervalHeap m_priorityQueue = new C5.IntervalHeap(10, new J2KImageComparer()); + private object m_syncRoot = new object(); + + public LLClientView Client { get { return m_client; } } + public AssetBase MissingImage { get { return m_missingImage; } } public LLImageManager(LLClientView client, IAssetService pAssetCache, IJ2KDecoder pJ2kDecodeModule) { m_client = client; m_assetCache = pAssetCache; + if (pAssetCache != null) m_missingImage = pAssetCache.Get("5748decc-f629-461c-9a36-a35a221fe21f"); - else - m_log.Error("[ClientView] - couldn't set missing image asset, falling back to missing image packet. This is known to crash the client"); + + if (m_missingImage == null) + m_log.Error("[ClientView] - Couldn't set missing image asset, falling back to missing image packet. This is known to crash the client"); m_j2kDecodeModule = pJ2kDecodeModule; } - public LLClientView Client - { - get { return m_client; } - } - - public AssetBase MissingImage - { - get { return m_missingImage; } - } - + /// + /// Handles an incoming texture request or update to an existing texture request + /// + /// public void EnqueueReq(TextureRequestArgs newRequest) { - //newRequest is the properties of our new texture fetch request. - //Basically, here is where we queue up "new" requests.. - // .. or modify existing requests to suit. - //Make sure we're not shutting down.. if (!m_shuttingdown) { @@ -125,21 +120,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP imgrequest.DiscardLevel = newRequest.DiscardLevel; //Update the requested packet number - imgrequest.StartPacket = newRequest.PacketNumber; + imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber); //Update the requested priority imgrequest.Priority = newRequest.Priority; - try - { - lock (m_priorityQueue) - m_priorityQueue.Replace(imgrequest.PriorityQueueHandle, imgrequest); - } - catch (Exception) - { - imgrequest.PriorityQueueHandle = null; - lock (m_priorityQueue) - m_priorityQueue.Add(ref imgrequest.PriorityQueueHandle, imgrequest); - } + UpdateImageInQueue(imgrequest); //Run an update imgrequest.RunUpdate(); @@ -159,31 +144,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP // newRequest.RequestedAssetID, newRequest.DiscardLevel, newRequest.PacketNumber, newRequest.Priority); imgrequest = new J2KImage(this); - - //Assign our decoder module imgrequest.J2KDecoder = m_j2kDecodeModule; - - //Assign our asset cache module imgrequest.AssetService = m_assetCache; - - //Assign the requested discard level imgrequest.DiscardLevel = newRequest.DiscardLevel; - - //Assign the requested packet number - imgrequest.StartPacket = newRequest.PacketNumber; - - //Assign the requested priority + imgrequest.StartPacket = Math.Max(1, newRequest.PacketNumber); imgrequest.Priority = newRequest.Priority; - - //Assign the asset uuid imgrequest.TextureID = newRequest.RequestedAssetID; - - //Assign the requested priority imgrequest.Priority = newRequest.Priority; //Add this download to the priority queue - lock (m_priorityQueue) - m_priorityQueue.Add(ref imgrequest.PriorityQueueHandle, imgrequest); + AddImageToQueue(imgrequest); //Run an update imgrequest.RunUpdate(); @@ -194,105 +164,97 @@ namespace OpenSim.Region.ClientStack.LindenUDP public bool ProcessImageQueue(int count, int maxpack) { - lock (this) + J2KImage imagereq; + int numCollected = 0; + + lock (m_syncRoot) { - //count is the number of textures we want to process in one go. - //As part of this class re-write, that number will probably rise - //since we're processing in a more efficient manner. + m_lastloopprocessed = DateTime.Now.Ticks; - // this can happen during Close() - if (m_client == null) + // This can happen during Close() + if (m_client == null || m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null) return false; - - int numCollected = 0; - - //Calculate our threshold - int threshold; - if (m_lastloopprocessed == 0) - { - if (m_client.PacketHandler == null || m_client.PacketHandler.PacketQueue == null || m_client.PacketHandler.PacketQueue.TextureThrottle == null) - return false; - //This is decent for a semi fast machine, but we'll calculate it more accurately based on time below - threshold = m_client.PacketHandler.PacketQueue.TextureThrottle.Current / 6300; - m_lastloopprocessed = DateTime.Now.Ticks; - } - else + + while ((imagereq = GetHighestPriorityImage()) != null) { - double throttleseconds = ((double)DateTime.Now.Ticks - (double)m_lastloopprocessed) / (double)TimeSpan.TicksPerSecond; - throttleseconds = throttleseconds * m_client.PacketHandler.PacketQueue.TextureThrottle.Current; - - //Average of 1000 bytes per packet - throttleseconds = throttleseconds / 1000; - - //Safe-zone multiplier of 2.0 - threshold = (int)(throttleseconds * 2.0); - m_lastloopprocessed = DateTime.Now.Ticks; - - } - - if (m_client.PacketHandler == null) - return false; - - if (m_client.PacketHandler.PacketQueue == null) - return false; - - if (threshold < 10) - threshold = 10; - - //Uncomment this to see what the texture stack is doing - //m_log.Debug("Queue: " + m_client.PacketHandler.PacketQueue.getQueueCount(ThrottleOutPacketType.Texture).ToString() + " Threshold: " + threshold.ToString() + " outstanding: " + m_outstandingtextures.ToString()); - if (true) //m_client.PacketHandler.PacketQueue.GetQueueCount(ThrottleOutPacketType.Texture) < threshold) - { - while (m_priorityQueue.Count > 0) + if (imagereq.IsDecoded == true) { - J2KImage imagereq = null; - lock (m_priorityQueue) - imagereq = m_priorityQueue.FindMax(); + ++numCollected; - if (imagereq.IsDecoded == true) + if (imagereq.SendPackets(m_client, maxpack)) { - // we need to test this here now that we are dropping assets - if (!imagereq.HasAsset) - { - m_log.WarnFormat("[LLIMAGE MANAGER]: Re-requesting the image asset {0}", imagereq.TextureID); - imagereq.RunUpdate(); - continue; - } - - ++numCollected; - - //SendPackets will send up to ten packets per cycle - if (imagereq.SendPackets(m_client, maxpack)) - { - // Send complete. Destroy any knowledge of this transfer - try - { - lock (m_priorityQueue) - m_priorityQueue.Delete(imagereq.PriorityQueueHandle); - } - catch (Exception) { } - } + // Send complete. Destroy any knowledge of this transfer + RemoveImageFromQueue(imagereq); } - - if (numCollected == count) - break; } - } - return m_priorityQueue.Count > 0; + if (numCollected == count) + break; + } } + + return m_priorityQueue.Count > 0; } //Faux destructor public void Close() { - m_shuttingdown = true; m_j2kDecodeModule = null; m_assetCache = null; m_client = null; } + #region Priority Queue Helpers + + J2KImage GetHighestPriorityImage() + { + J2KImage image = null; + + if (m_priorityQueue.Count > 0) + { + try + { + lock (m_priorityQueue) + image = m_priorityQueue.FindMax(); + } + catch (Exception) { } + } + + return image; + } + + void AddImageToQueue(J2KImage image) + { + image.PriorityQueueHandle = null; + + lock (m_priorityQueue) + m_priorityQueue.Add(ref image.PriorityQueueHandle, image); + } + + void RemoveImageFromQueue(J2KImage image) + { + try + { + lock (m_priorityQueue) + m_priorityQueue.Delete(image.PriorityQueueHandle); + } + catch (Exception) { } + } + + void UpdateImageInQueue(J2KImage image) + { + lock (m_priorityQueue) + { + try { m_priorityQueue.Replace(image.PriorityQueueHandle, image); } + catch (Exception) + { + image.PriorityQueueHandle = null; + m_priorityQueue.Add(ref image.PriorityQueueHandle, image); + } + } + } + #endregion Priority Queue Helpers } } -- cgit v1.1 From 387e9f7a7faeb412054383080afc3507a1522746 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Fri, 2 Oct 2009 18:31:08 -0700 Subject: * Creates Util.UTF8 and switches some references of Encoding.UTF8 to Util.UTF8 (not all references were switched since not all OpenSim libraries reference OpenSim.Framework) * Shrinks the largest in-memory object, the LLRAW.HeightmapLookupValue struct (only used for exporting to LLRAW terrain files), to the minimum possible size. This seems to have the odd side effect of cutting the size of the two double[256,256] terrain objects in half. Possibly an alignment optimization? --- OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/ClientStack') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 43d29fd..3f90004 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -4748,7 +4748,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP { Hashtable mp = (Hashtable)simMapProfiles[iii]; mbReply.Data[iii] = new MapBlockReplyPacket.DataBlock(); - mbReply.Data[iii].Name = System.Text.Encoding.UTF8.GetBytes((string)mp["name"]); + mbReply.Data[iii].Name = Util.UTF8.GetBytes((string)mp["name"]); mbReply.Data[iii].Access = System.Convert.ToByte(mp["access"]); mbReply.Data[iii].Agents = System.Convert.ToByte(mp["agents"]); mbReply.Data[iii].MapImageID = new UUID((string)mp["map-image-id"]); @@ -7338,7 +7338,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP } #endregion - string mapName = Encoding.UTF8.GetString(map.NameData.Name, 0, + string mapName = Util.UTF8.GetString(map.NameData.Name, 0, map.NameData.Name.Length - 1); handlerMapNameRequest = OnMapNameRequest; if (handlerMapNameRequest != null) -- cgit v1.1 From 366bfe17ae46ddfe7b942b5851a1625072b4852b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 4 Oct 2009 07:41:10 -0700 Subject: Trying to avoid the null pointer exception in J2KImage, RunUpdate. --- OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/ClientStack') diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs index 0e3630c..713d43a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs @@ -158,9 +158,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_currentPacket = m_stopPacket; return; } - + if (DiscardLevel >= 0 || m_stopPacket == 0) { + // This shouldn't happen, but if it does, we really can't proceed + if (Layers == null) + { + m_log.Warn("[J2KIMAGE]: RunUpdate() called with missing Layers. Canceling texture transfer"); + m_currentPacket = m_stopPacket; + return; + } + int maxDiscardLevel = Math.Max(0, Layers.Length - 1); // Treat initial texture downloads with a DiscardLevel of -1 a request for the highest DiscardLevel -- cgit v1.1 From d93e0a05037495dcdabdffcc9b9f78747271da39 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 4 Oct 2009 10:30:21 -0700 Subject: Guarding a line that is sometimes throwing a null pointer exception. --- OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/ClientStack') diff --git a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs index 713d43a..19ad0b4 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/J2KImage.cs @@ -197,11 +197,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_currentPacket = StartPacket; } - if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0) - { - //m_log.Debug("No textures queued, sending one packet to kickstart it"); - SendPacket(m_imageManager.Client); - } + if ((m_imageManager != null) && (m_imageManager.Client != null) && (m_imageManager.Client.PacketHandler != null)) + if (m_imageManager.Client.PacketHandler.GetQueueCount(ThrottleOutPacketType.Texture) == 0) + { + //m_log.Debug("No textures queued, sending one packet to kickstart it"); + SendPacket(m_imageManager.Client); + } } } } -- cgit v1.1 From 5b19d5a7b763a5ff5a7380f00c08fc30f4707588 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 4 Oct 2009 14:05:58 -0700 Subject: Reduced locking. --- OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/ClientStack') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs index facfb9d..2120d33 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs @@ -167,8 +167,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP J2KImage imagereq; int numCollected = 0; - lock (m_syncRoot) - { + //lock (m_syncRoot) + //{ m_lastloopprocessed = DateTime.Now.Ticks; // This can happen during Close() @@ -191,7 +191,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (numCollected == count) break; } - } + //} return m_priorityQueue.Count > 0; } @@ -211,16 +211,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP { J2KImage image = null; - if (m_priorityQueue.Count > 0) + lock (m_priorityQueue) { - try + + if (m_priorityQueue.Count > 0) { - lock (m_priorityQueue) + try + { image = m_priorityQueue.FindMax(); + } + catch (Exception) { } } - catch (Exception) { } } - return image; } -- cgit v1.1