** DANGER someone should stress test more ** release unused physics meshs, including unmanaged memory allocations (allocated by managed code)

avinationmerge
UbitUmarov 2012-08-06 09:06:46 +01:00
parent 307c45af2a
commit 36a1248b31
7 changed files with 174 additions and 55 deletions

View File

@ -37,6 +37,8 @@ namespace OpenSim.Region.Physics.Manager
IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod);
IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical);
IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical,bool convex); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical,bool convex);
void ReleaseMesh(IMesh mesh);
void ExpireReleaseMeshs();
} }
// Values for level of detail to be passed to the mesher. // Values for level of detail to be passed to the mesher.

View File

@ -79,5 +79,7 @@ namespace OpenSim.Region.Physics.Manager
return null; return null;
} }
public void ReleaseMesh(IMesh mesh) { }
public void ExpireReleaseMeshs() { }
} }
} }

View File

@ -763,5 +763,7 @@ namespace OpenSim.Region.Physics.Meshing
return mesh; return mesh;
} }
public void ReleaseMesh(IMesh imesh) { }
public void ExpireReleaseMeshs() { }
} }
} }

View File

@ -46,8 +46,8 @@ namespace OpenSim.Region.Physics.Meshing
IntPtr m_indicesPtr = IntPtr.Zero; IntPtr m_indicesPtr = IntPtr.Zero;
int m_indexCount = 0; int m_indexCount = 0;
public float[] m_normals; public float[] m_normals;
Vector3 _centroid; Vector3 m_centroid;
int _centroidDiv; int m_centroidDiv;
private class vertexcomp : IEqualityComparer<Vertex> private class vertexcomp : IEqualityComparer<Vertex>
{ {
@ -65,7 +65,6 @@ namespace OpenSim.Region.Physics.Meshing
int c = v.Z.GetHashCode(); int c = v.Z.GetHashCode();
return (a << 16) ^ (b << 8) ^ c; return (a << 16) ^ (b << 8) ^ c;
} }
} }
public Mesh() public Mesh()
@ -74,8 +73,18 @@ namespace OpenSim.Region.Physics.Meshing
m_vertices = new Dictionary<Vertex, int>(vcomp); m_vertices = new Dictionary<Vertex, int>(vcomp);
m_triangles = new List<Triangle>(); m_triangles = new List<Triangle>();
_centroid = Vector3.Zero; m_centroid = Vector3.Zero;
_centroidDiv = 0; m_centroidDiv = 0;
}
public int RefCount { get; set; }
public ulong Key { get; set; }
public void Scale(Vector3 scale)
{
} }
public Mesh Clone() public Mesh Clone()
@ -86,8 +95,8 @@ namespace OpenSim.Region.Physics.Meshing
{ {
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone())); result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
} }
result._centroid = _centroid; result.m_centroid = m_centroid;
result._centroidDiv = _centroidDiv; result.m_centroidDiv = m_centroidDiv;
return result; return result;
} }
@ -109,41 +118,41 @@ namespace OpenSim.Region.Physics.Meshing
if (m_vertices.Count == 0) if (m_vertices.Count == 0)
{ {
_centroidDiv = 0; m_centroidDiv = 0;
_centroid = Vector3.Zero; m_centroid = Vector3.Zero;
} }
if (!m_vertices.ContainsKey(triangle.v1)) if (!m_vertices.ContainsKey(triangle.v1))
{ {
m_vertices[triangle.v1] = m_vertices.Count; m_vertices[triangle.v1] = m_vertices.Count;
_centroid.X += triangle.v1.X; m_centroid.X += triangle.v1.X;
_centroid.Y += triangle.v1.Y; m_centroid.Y += triangle.v1.Y;
_centroid.Z += triangle.v1.Z; m_centroid.Z += triangle.v1.Z;
_centroidDiv++; m_centroidDiv++;
} }
if (!m_vertices.ContainsKey(triangle.v2)) if (!m_vertices.ContainsKey(triangle.v2))
{ {
m_vertices[triangle.v2] = m_vertices.Count; m_vertices[triangle.v2] = m_vertices.Count;
_centroid.X += triangle.v2.X; m_centroid.X += triangle.v2.X;
_centroid.Y += triangle.v2.Y; m_centroid.Y += triangle.v2.Y;
_centroid.Z += triangle.v2.Z; m_centroid.Z += triangle.v2.Z;
_centroidDiv++; m_centroidDiv++;
} }
if (!m_vertices.ContainsKey(triangle.v3)) if (!m_vertices.ContainsKey(triangle.v3))
{ {
m_vertices[triangle.v3] = m_vertices.Count; m_vertices[triangle.v3] = m_vertices.Count;
_centroid.X += triangle.v3.X; m_centroid.X += triangle.v3.X;
_centroid.Y += triangle.v3.Y; m_centroid.Y += triangle.v3.Y;
_centroid.Z += triangle.v3.Z; m_centroid.Z += triangle.v3.Z;
_centroidDiv++; m_centroidDiv++;
} }
m_triangles.Add(triangle); m_triangles.Add(triangle);
} }
public Vector3 GetCentroid() public Vector3 GetCentroid()
{ {
if (_centroidDiv > 0) if (m_centroidDiv > 0)
return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv); return new Vector3(m_centroid.X / m_centroidDiv, m_centroid.Y / m_centroidDiv, m_centroid.Z / m_centroidDiv);
else else
return Vector3.Zero; return Vector3.Zero;
} }

View File

@ -83,6 +83,7 @@ namespace OpenSim.Region.Physics.Meshing
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
private Dictionary<ulong, Mesh> m_uniqueReleasedMeshes = new Dictionary<ulong, Mesh>();
public Meshmerizer(IConfigSource config) public Meshmerizer(IConfigSource config)
{ {
@ -986,6 +987,8 @@ namespace OpenSim.Region.Physics.Meshing
return CreateMesh(primName, primShape, size, lod, false,false); return CreateMesh(primName, primShape, size, lod, false,false);
} }
private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f);
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
{ {
#if SPAM #if SPAM
@ -995,17 +998,60 @@ namespace OpenSim.Region.Physics.Meshing
Mesh mesh = null; Mesh mesh = null;
ulong key = 0; ulong key = 0;
// If this mesh has been created already, return it instead of creating another copy
// For large regions with 100k+ prims and hundreds of copies of each, this can save a GB or more of memory
key = primShape.GetMeshKey(size, lod, convex);
if (m_uniqueMeshes.TryGetValue(key, out mesh))
return mesh;
if (size.X < 0.01f) size.X = 0.01f; if (size.X < 0.01f) size.X = 0.01f;
if (size.Y < 0.01f) size.Y = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f;
if (size.Z < 0.01f) size.Z = 0.01f; if (size.Z < 0.01f) size.Z = 0.01f;
// try to find a identical mesh on meshs in use
key = primShape.GetMeshKey(size, lod, convex);
lock (m_uniqueMeshes)
{
m_uniqueMeshes.TryGetValue(key, out mesh);
if (mesh != null)
{
mesh.RefCount++;
return mesh;
}
}
// try to find a identical mesh on meshs recently released
lock (m_uniqueReleasedMeshes)
{
m_uniqueReleasedMeshes.TryGetValue(key, out mesh);
if (mesh != null)
{
m_uniqueReleasedMeshes.Remove(key);
lock (m_uniqueMeshes)
m_uniqueMeshes.Add(key, mesh);
mesh.RefCount = 1;
return mesh;
}
}
/*
Mesh UnitSizeMesh = null;
ulong unitsizekey = 0;
unitsizekey = primShape.GetMeshKey(m_MeshUnitSize, lod, convex);
lock(m_uniqueMeshes)
m_uniqueMeshes.TryGetValue(unitsizekey, out UnitSizeMesh);
if (UnitSizeMesh !=null)
{
UnitSizeMesh.RefCount++;
mesh = UnitSizeMesh.Clone();
mesh.Key = key;
mesh.Scale(size);
mesh.RefCount++;
lock(m_uniqueMeshes)
m_uniqueMeshes.Add(key, mesh);
return mesh;
}
*/
mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex); mesh = CreateMeshFromPrimMesher(primName, primShape, size, lod,convex);
// mesh.Key = unitsizekey;
if (mesh != null) if (mesh != null)
{ {
@ -1021,11 +1067,68 @@ namespace OpenSim.Region.Physics.Meshing
// trim the vertex and triangle lists to free up memory // trim the vertex and triangle lists to free up memory
mesh.TrimExcess(); mesh.TrimExcess();
mesh.Key = key;
mesh.RefCount++;
m_uniqueMeshes.Add(key, mesh); lock(m_uniqueMeshes)
m_uniqueMeshes.Add(key, mesh);
} }
return mesh; return mesh;
} }
public void ReleaseMesh(IMesh imesh)
{
if (imesh == null)
return;
Mesh mesh = (Mesh)imesh;
int curRefCount = mesh.RefCount;
curRefCount--;
if (curRefCount > 0)
{
mesh.RefCount = curRefCount;
return;
}
lock (m_uniqueMeshes)
{
mesh.RefCount = 0;
m_uniqueMeshes.Remove(mesh.Key);
lock (m_uniqueReleasedMeshes)
m_uniqueReleasedMeshes.Add(mesh.Key, mesh);
}
}
public void ExpireReleaseMeshs()
{
if (m_uniqueMeshes.Count == 0)
return;
List<Mesh> meshstodelete = new List<Mesh>();
int refcntr;
lock (m_uniqueReleasedMeshes)
{
foreach (Mesh m in m_uniqueReleasedMeshes.Values)
{
refcntr = m.RefCount;
refcntr--;
if (refcntr > -6)
m.RefCount = refcntr;
else
meshstodelete.Add(m);
}
foreach (Mesh m in meshstodelete)
{
m_uniqueReleasedMeshes.Remove(m.Key);
m.releaseSourceMeshData();
m.releasePinned();
}
}
}
} }
} }

View File

@ -57,7 +57,6 @@ using OdeAPI;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Physics.Manager; using OpenSim.Region.Physics.Manager;
namespace OpenSim.Region.Physics.OdePlugin namespace OpenSim.Region.Physics.OdePlugin
{ {
public class OdePrim : PhysicsActor public class OdePrim : PhysicsActor
@ -538,24 +537,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
set set
{ {
/*
IMesh mesh = null;
if (_parent_scene.needsMeshing(value))
{
bool convex;
if (m_shapetype == 0)
convex = false;
else
convex = true;
mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, (int)LevelOfDetail.High, true, convex);
}
if (mesh != null)
{
lock (m_meshlock)
m_mesh = mesh;
}
*/
AddChange(changes.Shape, value); AddChange(changes.Shape, value);
} }
} }
@ -1357,7 +1338,6 @@ namespace OpenSim.Region.Physics.OdePlugin
IMesh mesh = null; IMesh mesh = null;
lock (m_meshlock) lock (m_meshlock)
{ {
if (m_mesh == null) if (m_mesh == null)
@ -1403,7 +1383,7 @@ namespace OpenSim.Region.Physics.OdePlugin
hasOOBoffsetFromMesh = true; hasOOBoffsetFromMesh = true;
mesh.releaseSourceMeshData(); mesh.releaseSourceMeshData();
m_mesh = null; m_mesh = mesh;
} }
IntPtr geo = IntPtr.Zero; IntPtr geo = IntPtr.Zero;
@ -1545,7 +1525,10 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomTriMeshDataDestroy(_triMeshData); d.GeomTriMeshDataDestroy(_triMeshData);
_triMeshData = IntPtr.Zero; _triMeshData = IntPtr.Zero;
} }
} }
// catch (System.AccessViolationException) // catch (System.AccessViolationException)
catch (Exception e) catch (Exception e)
{ {
@ -1559,6 +1542,13 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name); m_log.ErrorFormat("[PHYSICS]: PrimGeom destruction BAD {0}", Name);
} }
if (m_mesh != null)
{
_parent_scene.mesher.ReleaseMesh(m_mesh);
m_mesh = null;
}
Body = IntPtr.Zero; Body = IntPtr.Zero;
hasOOBoffsetFromMesh = false; hasOOBoffsetFromMesh = false;
} }

View File

@ -194,7 +194,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private float metersInSpace = 25.6f; private float metersInSpace = 25.6f;
private float m_timeDilation = 1.0f; private float m_timeDilation = 1.0f;
DateTime m_lastframe; private DateTime m_lastframe;
private DateTime m_lastMeshExpire;
public float gravityx = 0f; public float gravityx = 0f;
public float gravityy = 0f; public float gravityy = 0f;
@ -203,6 +204,8 @@ namespace OpenSim.Region.Physics.OdePlugin
private float waterlevel = 0f; private float waterlevel = 0f;
private int framecount = 0; private int framecount = 0;
private int m_meshExpireCntr;
// private IntPtr WaterGeom = IntPtr.Zero; // private IntPtr WaterGeom = IntPtr.Zero;
// private IntPtr WaterHeightmapData = IntPtr.Zero; // private IntPtr WaterHeightmapData = IntPtr.Zero;
// private GCHandle WaterMapHandler = new GCHandle(); // private GCHandle WaterMapHandler = new GCHandle();
@ -263,7 +266,6 @@ namespace OpenSim.Region.Physics.OdePlugin
const int maxContactsbeforedeath = 4000; const int maxContactsbeforedeath = 4000;
private volatile int m_global_contactcount = 0; private volatile int m_global_contactcount = 0;
private IntPtr contactgroup; private IntPtr contactgroup;
public ContactData[] m_materialContactsData = new ContactData[8]; public ContactData[] m_materialContactsData = new ContactData[8];
@ -594,6 +596,7 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
m_lastframe = DateTime.UtcNow; m_lastframe = DateTime.UtcNow;
m_lastMeshExpire = m_lastframe;
} }
internal void waitForSpaceUnlock(IntPtr space) internal void waitForSpaceUnlock(IntPtr space)
@ -1768,9 +1771,9 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
DateTime now = DateTime.UtcNow; DateTime now = DateTime.UtcNow;
TimeSpan SinceLastFrame = now - m_lastframe; TimeSpan timedif = now - m_lastframe;
m_lastframe = now; m_lastframe = now;
timeStep = (float)SinceLastFrame.TotalSeconds; timeStep = (float)timedif.TotalSeconds;
// acumulate time so we can reduce error // acumulate time so we can reduce error
step_time += timeStep; step_time += timeStep;
@ -1972,6 +1975,14 @@ namespace OpenSim.Region.Physics.OdePlugin
_badCharacter.Clear(); _badCharacter.Clear();
} }
} }
timedif = now - m_lastMeshExpire;
if (timedif.Seconds > 10)
{
mesher.ExpireReleaseMeshs();
m_lastMeshExpire = now;
}
/* /*
int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace); int nactivegeoms = d.SpaceGetNumGeoms(ActiveSpace);
int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace); int nstaticgeoms = d.SpaceGetNumGeoms(StaticSpace);