This releases the texture assets from LLImageManager cache, and re-requests them later if the client asks for them again. Needs more testing in texture-rich sims.

prioritization
Diva Canto 2009-09-30 10:59:10 -07:00 committed by Melanie
parent 6779abf7f5
commit 4bf47fa592
2 changed files with 48 additions and 12 deletions

View File

@ -60,14 +60,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private sbyte m_discardLevel=-1; private sbyte m_discardLevel=-1;
private uint m_packetNumber; private uint m_packetNumber;
private bool m_decoderequested = false; private bool m_decoderequested = false;
private bool m_hasasset = false; public bool m_hasasset = false;
private bool m_asset_requested = false; private bool m_asset_requested = false;
private bool m_sentinfo = false; private bool m_sentinfo = false;
private uint m_stopPacket = 0; private uint m_stopPacket = 0;
private const int cImagePacketSize = 1000; private const int cImagePacketSize = 1000;
private const int cFirstPacketSize = 600; private const int cFirstPacketSize = 600;
private AssetBase m_asset = null; private AssetBase m_asset = null;
private int m_assetDataLength = 0;
private LLImageManager m_image; private LLImageManager m_image;
public J2KImage(LLImageManager image) public J2KImage(LLImageManager image)
{ {
m_image = image; m_image = image;
@ -99,7 +103,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return 0; return 0;
try try
{ {
return (ushort)(((m_asset.Data.Length - cFirstPacketSize + cImagePacketSize - 1) / cImagePacketSize) + 1); return (ushort)(((m_assetDataLength - cFirstPacketSize + cImagePacketSize - 1) / cImagePacketSize) + 1);
} }
catch (Exception) catch (Exception)
{ {
@ -110,6 +114,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
public void DropAsset()
{
m_log.WarnFormat("[LLIMAGE MANAGER]: Dropping texture asset {0}", m_requestedUUID);
m_asset = null;
m_hasasset = false;
m_asset_requested = false;
}
public void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers) public void J2KDecodedCallback(UUID AssetId, OpenJPEG.J2KLayerInfo[] layers)
{ {
m_image.m_outstandingtextures++; m_image.m_outstandingtextures++;
@ -127,8 +139,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
else else
{ {
m_asset = asset; m_asset = asset;
} }
m_assetDataLength = m_asset.Data.Length;
RunUpdate(); RunUpdate();
} }
@ -150,8 +165,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public int LastPacketSize() public int LastPacketSize()
{ {
if (m_packetNumber == 1) if (m_packetNumber == 1)
return m_asset.Data.Length; return m_assetDataLength;
int lastsize = (m_asset.Data.Length - cFirstPacketSize) % cImagePacketSize; int lastsize = (m_assetDataLength - cFirstPacketSize) % cImagePacketSize;
//If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary //If the last packet size is zero, it's really cImagePacketSize, it sits on the boundary
if (lastsize == 0) if (lastsize == 0)
{ {
@ -185,10 +200,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true; return true;
} }
// Do we have less then 1 packet's worth of data? // Do we have less then 1 packet's worth of data?
else if (m_asset.Data.Length <= cFirstPacketSize) else if (m_assetDataLength <= cFirstPacketSize)
{ {
// Send only 1 packet // Send only 1 packet
client.SendImageFirstPart(1, m_requestedUUID, (uint)m_asset.Data.Length, m_asset.Data, 2); client.SendImageFirstPart(1, m_requestedUUID, (uint)m_assetDataLength, m_asset.Data, 2);
m_stopPacket = 0; m_stopPacket = 0;
return true; return true;
} }
@ -198,7 +213,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
try try
{ {
Buffer.BlockCopy(m_asset.Data, 0, firstImageData, 0, (int)cFirstPacketSize); Buffer.BlockCopy(m_asset.Data, 0, firstImageData, 0, (int)cFirstPacketSize);
client.SendImageFirstPart(TexturePacketCount(), m_requestedUUID, (uint)m_asset.Data.Length, firstImageData, 2); client.SendImageFirstPart(TexturePacketCount(), m_requestedUUID, (uint)m_assetDataLength, firstImageData, 2);
} }
catch (Exception) catch (Exception)
{ {
@ -216,13 +231,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
try try
{ {
if ((CurrentBytePosition() + cImagePacketSize) > m_asset.Data.Length) if ((CurrentBytePosition() + cImagePacketSize) > m_assetDataLength)
{ {
imagePacketSize = LastPacketSize(); imagePacketSize = LastPacketSize();
complete=true; complete=true;
if ((CurrentBytePosition() + imagePacketSize) > m_asset.Data.Length) if ((CurrentBytePosition() + imagePacketSize) > m_assetDataLength)
{ {
imagePacketSize = m_asset.Data.Length - CurrentBytePosition(); imagePacketSize = m_assetDataLength - CurrentBytePosition();
complete = true; complete = true;
} }
} }

View File

@ -257,6 +257,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
J2KImage imagereq = m_imagestore[m_priorities.Values[x]]; J2KImage imagereq = m_imagestore[m_priorities.Values[x]];
if (imagereq.m_decoded == true && !imagereq.m_completedSendAtCurrentDiscardLevel) if (imagereq.m_decoded == true && !imagereq.m_completedSendAtCurrentDiscardLevel)
{ {
// we need to test this here now that we are dropping assets
if (!imagereq.m_hasasset)
{
m_log.WarnFormat("[LLIMAGE MANAGER]: Re-requesting the image asset {0}", imagereq.m_requestedUUID);
imagereq.RunUpdate();
continue;
}
numCollected++; numCollected++;
//SendPackets will send up to ten packets per cycle //SendPackets will send up to ten packets per cycle
if (imagereq.SendPackets(m_client, maxpack)) if (imagereq.SendPackets(m_client, maxpack))
@ -264,8 +272,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//Send complete //Send complete
if (!imagereq.m_completedSendAtCurrentDiscardLevel) if (!imagereq.m_completedSendAtCurrentDiscardLevel)
{ {
imagereq.m_completedSendAtCurrentDiscardLevel = true; // I think this field imagereq.m_completedSendAtCurrentDiscardLevel
// is completely redundant
//imagereq.m_completedSendAtCurrentDiscardLevel = true;
Interlocked.Decrement(ref m_outstandingtextures); Interlocked.Decrement(ref m_outstandingtextures);
// First and foremost, drop the reference to the asset
// so that the asset doesn't stay in memory forever.
// We'll Get it again from the asset service (usually cache)
// if/when the client requests it again.
// In order not to mess much with the current implementation
// of this management code, we drop only the asset reference
// but keep the image request itself.
imagereq.DropAsset();
//Re-assign priority to bottom //Re-assign priority to bottom
//Remove the old priority //Remove the old priority
m_priorities.Remove(imagereq.m_designatedPriorityKey); m_priorities.Remove(imagereq.m_designatedPriorityKey);