First round of memory improvements!

* Disable TRACK_UTILIZATION by default
* Ignore Primitive.ScratchPad and always set it to Utils.EmptyBytes. This field is deprecated on the SL grid and there are better ways to extend the protocol for non-SL grids
* More graceful handling of corrupted wearables
* Free up memory after baking

git-svn-id: http://libopenmetaverse.googlecode.com/svn/libopenmetaverse/trunk@3297 52acb1d6-8a22-11de-b505-999d5b087335
This commit is contained in:
John Hurliman
2010-04-20 21:58:23 +00:00
parent 94f830b9d9
commit de2a49dddf
5 changed files with 148 additions and 125 deletions

View File

@@ -1465,7 +1465,7 @@ namespace OpenMetaverse
private bool CreateBakes()
{
bool success = true;
List<BakeType> pendingBakes = new List<BakeType>(0);
List<BakeType> pendingBakes = new List<BakeType>();
// Check each bake layer in the Textures array for missing bakes
for (int bakedIndex = 0; bakedIndex < BAKED_TEXTURE_COUNT; bakedIndex++)
@@ -1495,6 +1495,17 @@ namespace OpenMetaverse
);
}
// Free up all the textures we're holding on to
for (int i = 0; i < Textures.Length; i++)
{
Textures[i].Texture = null;
Textures[i].TextureID = UUID.Zero;
}
// We just allocated and freed a ridiculous amount of memory while
// baking. Signal to the GC to clean up
GC.Collect();
return success;
}

View File

@@ -86,130 +86,140 @@ namespace OpenMetaverse.Assets
{
int version = -1;
Permissions = new Permissions();
string data = Utils.BytesToString(AssetData);
data = data.Replace("\r", String.Empty);
string[] lines = data.Split('\n');
for (int stri = 0; stri < lines.Length; stri++)
try
{
if (stri == 0)
{
string versionstring = lines[stri];
version = Int32.Parse(versionstring.Split(' ')[2]);
if (version != 22 && version != 18)
return false;
}
else if (stri == 1)
{
Name = lines[stri];
}
else if (stri == 2)
{
Description = lines[stri];
}
else
{
string line = lines[stri].Trim();
string[] fields = line.Split('\t');
string data = Utils.BytesToString(AssetData);
if (fields.Length == 1)
data = data.Replace("\r", String.Empty);
string[] lines = data.Split('\n');
for (int stri = 0; stri < lines.Length; stri++)
{
if (stri == 0)
{
fields = line.Split(' ');
if (fields[0] == "parameters")
{
int count = Int32.Parse(fields[1]) + stri;
for (; stri < count; )
{
stri++;
line = lines[stri].Trim();
fields = line.Split(' ');
int id = Int32.Parse(fields[0]);
if (fields[1] == ",")
fields[1] = "0";
else
fields[1] = fields[1].Replace(',', '.');
float weight = float.Parse(fields[1], System.Globalization.NumberStyles.Float,
Utils.EnUsCulture.NumberFormat);
Params[id] = weight;
}
}
else if (fields[0] == "textures")
{
int count = Int32.Parse(fields[1]) + stri;
for (; stri < count; )
{
stri++;
line = lines[stri].Trim();
fields = line.Split(' ');
AvatarTextureIndex id = (AvatarTextureIndex)Int32.Parse(fields[0]);
UUID texture = new UUID(fields[1]);
Textures[id] = texture;
}
}
else if (fields[0] == "type")
{
WearableType = (WearableType)Int32.Parse(fields[1]);
}
string versionstring = lines[stri];
version = Int32.Parse(versionstring.Split(' ')[2]);
if (version != 22 && version != 18)
return false;
}
else if (fields.Length == 2)
else if (stri == 1)
{
switch (fields[0])
Name = lines[stri];
}
else if (stri == 2)
{
Description = lines[stri];
}
else
{
string line = lines[stri].Trim();
string[] fields = line.Split('\t');
if (fields.Length == 1)
{
case "creator_mask":
// Deprecated, apply this as the base mask
Permissions.BaseMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "base_mask":
Permissions.BaseMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "owner_mask":
Permissions.OwnerMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "group_mask":
Permissions.GroupMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "everyone_mask":
Permissions.EveryoneMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "next_owner_mask":
Permissions.NextOwnerMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "creator_id":
Creator = new UUID(fields[1]);
break;
case "owner_id":
Owner = new UUID(fields[1]);
break;
case "last_owner_id":
LastOwner = new UUID(fields[1]);
break;
case "group_id":
Group = new UUID(fields[1]);
break;
case "group_owned":
GroupOwned = (Int32.Parse(fields[1]) != 0);
break;
case "sale_type":
ForSale = Utils.StringToSaleType(fields[1]);
break;
case "sale_price":
SalePrice = Int32.Parse(fields[1]);
break;
case "sale_info":
// Container for sale_type and sale_price, ignore
break;
default:
return false;
fields = line.Split(' ');
if (fields[0] == "parameters")
{
int count = Int32.Parse(fields[1]) + stri;
for (; stri < count; )
{
stri++;
line = lines[stri].Trim();
fields = line.Split(' ');
int id = Int32.Parse(fields[0]);
if (fields[1] == ",")
fields[1] = "0";
else
fields[1] = fields[1].Replace(',', '.');
float weight = float.Parse(fields[1], System.Globalization.NumberStyles.Float,
Utils.EnUsCulture.NumberFormat);
Params[id] = weight;
}
}
else if (fields[0] == "textures")
{
int count = Int32.Parse(fields[1]) + stri;
for (; stri < count; )
{
stri++;
line = lines[stri].Trim();
fields = line.Split(' ');
AvatarTextureIndex id = (AvatarTextureIndex)Int32.Parse(fields[0]);
UUID texture = new UUID(fields[1]);
Textures[id] = texture;
}
}
else if (fields[0] == "type")
{
WearableType = (WearableType)Int32.Parse(fields[1]);
}
}
else if (fields.Length == 2)
{
switch (fields[0])
{
case "creator_mask":
// Deprecated, apply this as the base mask
Permissions.BaseMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "base_mask":
Permissions.BaseMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "owner_mask":
Permissions.OwnerMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "group_mask":
Permissions.GroupMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "everyone_mask":
Permissions.EveryoneMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "next_owner_mask":
Permissions.NextOwnerMask = (PermissionMask)UInt32.Parse(fields[1], System.Globalization.NumberStyles.HexNumber);
break;
case "creator_id":
Creator = new UUID(fields[1]);
break;
case "owner_id":
Owner = new UUID(fields[1]);
break;
case "last_owner_id":
LastOwner = new UUID(fields[1]);
break;
case "group_id":
Group = new UUID(fields[1]);
break;
case "group_owned":
GroupOwned = (Int32.Parse(fields[1]) != 0);
break;
case "sale_type":
ForSale = Utils.StringToSaleType(fields[1]);
break;
case "sale_price":
SalePrice = Int32.Parse(fields[1]);
break;
case "sale_info":
// Container for sale_type and sale_price, ignore
break;
default:
return false;
}
}
}
}
}
catch (Exception ex)
{
Logger.Log("Failed decoding wearable asset " + this.AssetID + ": " + ex.Message,
Helpers.LogLevel.Warning);
return false;
}
return true;
}

View File

@@ -1970,14 +1970,15 @@ namespace OpenMetaverse
prim.TreeSpecies = (Tree)block.Data[0];
else
Logger.Log("Got a foliage update with an invalid TreeSpecies field", Helpers.LogLevel.Warning);
prim.ScratchPad = Utils.EmptyBytes;
break;
default:
prim.ScratchPad = new byte[block.Data.Length];
if (block.Data.Length > 0)
Buffer.BlockCopy(block.Data, 0, prim.ScratchPad, 0, prim.ScratchPad.Length);
// prim.ScratchPad = Utils.EmptyBytes;
// break;
//default:
// prim.ScratchPad = new byte[block.Data.Length];
// if (block.Data.Length > 0)
// Buffer.BlockCopy(block.Data, 0, prim.ScratchPad, 0, prim.ScratchPad.Length);
break;
}
prim.ScratchPad = Utils.EmptyBytes;
// Packed parameters
prim.CollisionPlane = objectupdate.CollisionPlane;
@@ -2336,7 +2337,7 @@ namespace OpenMetaverse
if ((flags & CompressedFlags.Tree) != 0)
{
prim.TreeSpecies = (Tree)block.Data[i++];
prim.ScratchPad = Utils.EmptyBytes;
//prim.ScratchPad = Utils.EmptyBytes;
}
// Scratch pad
else if ((flags & CompressedFlags.ScratchPad) != 0)
@@ -2344,10 +2345,11 @@ namespace OpenMetaverse
prim.TreeSpecies = (Tree)0;
int size = block.Data[i++];
prim.ScratchPad = new byte[size];
Buffer.BlockCopy(block.Data, i, prim.ScratchPad, 0, size);
//prim.ScratchPad = new byte[size];
//Buffer.BlockCopy(block.Data, i, prim.ScratchPad, 0, size);
i += size;
}
prim.ScratchPad = Utils.EmptyBytes;
// Floating text
if ((flags & CompressedFlags.HasText) != 0)

View File

@@ -769,7 +769,7 @@ namespace OpenMetaverse
Buffer.BlockCopy(prim.ScratchPad, 0, ScratchPad, 0, ScratchPad.Length);
}
else
ScratchPad = null;
ScratchPad = Utils.EmptyBytes;
Position = prim.Position;
Scale = prim.Scale;
Rotation = prim.Rotation;

View File

@@ -234,7 +234,7 @@ namespace OpenMetaverse
/// If true, utilization statistics will be tracked. There is a minor penalty
/// in CPU time for enabling this option.
/// </summary>
public bool TRACK_UTILIZATION = true;
public bool TRACK_UTILIZATION = false;
#endregion
#region Parcel Tracking