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:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user