Skip to content

Commit 78f455f

Browse files
committed
fix memory leak
1 parent 5860612 commit 78f455f

21 files changed

+492
-111
lines changed

EmbreeSharp.Test/TestBindings.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ private static unsafe void ErrorFunctionImpl(void* userPtr, RTCError code, byte*
1919
[TestMethod]
2020
public unsafe void SimpleIntersect()
2121
{
22-
using RTCDevice device = rtcNewDevice(null);
22+
RTCDevice device = rtcNewDevice(null);
2323
RTCErrorFunction errFunc = ErrorFunctionImpl;
2424
rtcSetDeviceErrorFunction(device, errFunc, null);
25-
using RTCScene scene = rtcNewScene(device);
26-
using RTCGeometry geo = rtcNewGeometry(device, RTCGeometryType.RTC_GEOMETRY_TYPE_TRIANGLE);
25+
RTCScene scene = rtcNewScene(device);
26+
RTCGeometry geo = rtcNewGeometry(device, RTCGeometryType.RTC_GEOMETRY_TYPE_TRIANGLE);
2727
float* vertices = (float*)rtcSetNewGeometryBuffer(geo, RTCBufferType.RTC_BUFFER_TYPE_VERTEX, 0, RTCFormat.RTC_FORMAT_FLOAT3, (nuint)sizeof(float) * 3, 4);
2828
uint* indices = (uint*)rtcSetNewGeometryBuffer(geo, RTCBufferType.RTC_BUFFER_TYPE_INDEX, 0, RTCFormat.RTC_FORMAT_UINT3, (nuint)sizeof(uint) * 3, 2);
2929
vertices[0] = -1f; vertices[1] = 0; vertices[2] = 1;
@@ -75,6 +75,9 @@ public unsafe void SimpleIntersect()
7575
rtcIntersect1(scene, (RTCRayHit*)Unsafe.AsPointer(ref rayhit));
7676
Assert.IsTrue(rayhit.hit.geomID == RTC_INVALID_GEOMETRY_ID);
7777
}
78+
rtcReleaseGeometry(geo);
79+
rtcReleaseScene(scene);
80+
rtcReleaseDevice(device);
7881
}
7982
}
8083
}

EmbreeSharp.Test/TestBuilder.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ public void Example()
117117
return true;
118118
});
119119
builder.Build();
120+
Assert.IsFalse(builder.Result.IsNull);
120121
ref Node res = ref builder.Result.Ref<Node>();
121122
Assert.AreEqual(minX, Math.Min(res.LeftBound.lower_x, res.RightBound.lower_x));
122123
Assert.AreEqual(minY, Math.Min(res.LeftBound.lower_y, res.RightBound.lower_y));
@@ -225,7 +226,8 @@ public void Generic()
225226
return true;
226227
});
227228
builder.Build();
228-
ref Node res = ref builder.Result;
229+
Assert.IsFalse(builder.Result.IsNull);
230+
ref Node res = ref builder.Result.Value;
229231
Assert.AreEqual(minX, Math.Min(res.LeftBound.lower_x, res.RightBound.lower_x));
230232
Assert.AreEqual(minY, Math.Min(res.LeftBound.lower_y, res.RightBound.lower_y));
231233
Assert.AreEqual(minZ, Math.Min(res.LeftBound.lower_z, res.RightBound.lower_z));

EmbreeSharp/EmbreeBuffer.cs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace EmbreeSharp
66
{
77
public class EmbreeBuffer : IDisposable
88
{
9-
private readonly RTCBuffer _buffer;
9+
private RTCBufferHandle _buffer;
1010
private readonly nuint _byteSize;
1111
private bool _disposedValue = false;
1212

@@ -18,7 +18,7 @@ public RTCBuffer NativeBuffer
1818
{
1919
ThrowUtility.ObjectDisposed();
2020
}
21-
return _buffer;
21+
return new RTCBuffer() { Ptr = _buffer.DangerousGetHandle() };
2222
}
2323
}
2424
public nuint ByteSize => _byteSize;
@@ -28,7 +28,7 @@ public EmbreeBuffer(EmbreeDevice device, nuint byteSize) : this(EmbreeNative.rtc
2828

2929
protected EmbreeBuffer(RTCBuffer rtcBuffer, nuint byteSize)
3030
{
31-
_buffer = rtcBuffer;
31+
_buffer = new RTCBufferHandle(rtcBuffer);
3232
_byteSize = byteSize;
3333
}
3434

@@ -42,6 +42,7 @@ protected virtual void Dispose(bool disposing)
4242
if (!_disposedValue)
4343
{
4444
_buffer.Dispose();
45+
_buffer = null!;
4546
_disposedValue = true;
4647
}
4748
}
@@ -60,7 +61,7 @@ public NativeMemoryView<byte> GetData()
6061
}
6162
unsafe
6263
{
63-
void* dst = EmbreeNative.rtcGetBufferData(_buffer);
64+
void* dst = EmbreeNative.rtcGetBufferData(NativeBuffer);
6465
return new NativeMemoryView<byte>(dst, _byteSize);
6566
}
6667
}
@@ -74,7 +75,7 @@ public NativeMemoryView<T> GetData<T>() where T : unmanaged
7475
var count = _byteSize / (nuint)Unsafe.SizeOf<T>();
7576
unsafe
7677
{
77-
void* dst = EmbreeNative.rtcGetBufferData(_buffer);
78+
void* dst = EmbreeNative.rtcGetBufferData(NativeBuffer);
7879
return new NativeMemoryView<T>(dst, count);
7980
}
8081
}

EmbreeSharp/EmbreeBuilder.cs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ public abstract class EmbreeBuilder<T> : IDisposable where T : EmbreeBuilder<T>
2424
private bool _disposedValue;
2525

2626
private GCHandle _gcHandle;
27-
private readonly RTCBVH _bvh;
27+
private RTCBVHHandle _bvh;
2828

2929
protected RTCBuildQuality _buildQuality;
3030
protected RTCBuildFlags _buildFlags;
@@ -38,13 +38,14 @@ public abstract class EmbreeBuilder<T> : IDisposable where T : EmbreeBuilder<T>
3838
protected RTCBuildPrimitive[]? _prims;
3939

4040
public bool IsDisposed => _disposedValue;
41-
public RTCBVH NativeBVH => _bvh;
41+
public RTCBVH NativeBVH => new RTCBVH() { Ptr = _bvh.DangerousGetHandle() };
4242
internal GCHandle Gc => _gcHandle;
4343

4444
public EmbreeBuilder(EmbreeDevice device)
4545
{
4646
_gcHandle = GCHandle.Alloc(this, GCHandleType.Weak);
47-
_bvh = EmbreeNative.rtcNewBVH(device.NativeDevice);
47+
var bvh = EmbreeNative.rtcNewBVH(device.NativeDevice);
48+
_bvh = new RTCBVHHandle(bvh);
4849
_buildQuality = RTCBuildQuality.RTC_BUILD_QUALITY_MEDIUM;
4950
_buildFlags = RTCBuildFlags.RTC_BUILD_FLAG_NONE;
5051
_maxBranchingFactor = 2;
@@ -72,6 +73,7 @@ protected virtual void Dispose(bool disposing)
7273
_gcHandle.Free();
7374
_gcHandle = default;
7475
_bvh.Dispose();
76+
_bvh = null!;
7577
_disposedValue = true;
7678
}
7779
}
@@ -408,7 +410,7 @@ public unsafe RTCThreadLocalAllocation Build()
408410
maxLeafSize = _maxLeafSize,
409411
traversalCost = _traversalCost,
410412
intersectionCost = _intersectionCost,
411-
bvh = NativeBVH.DangerousGetHandle(),
413+
bvh = NativeBVH,
412414
primitives = primitives,
413415
primitiveCount = primitiveCount,
414416
primitiveArrayCapacity = primitiveArrayCapacity,
@@ -451,7 +453,7 @@ public class EmbreeBuilder<TNode, TLeaf> : EmbreeBuilder<EmbreeBuilder<TNode, TL
451453
private SplitPrimitiveFunction? _splitPrimitive;
452454
private ProgressMonitorFunction? _progressMonitor;
453455

454-
public ref TNode Result => ref _result.Value;
456+
public Ref<TNode> Result => _result;
455457

456458
public EmbreeBuilder(EmbreeDevice device) : base(device) { }
457459

@@ -611,7 +613,7 @@ private static unsafe bool ProgressMonitorImpl(void* ptr, double n)
611613
return builder._progressMonitor?.Invoke(n) ?? true;
612614
}
613615

614-
public unsafe ref TNode Build()
616+
public unsafe Ref<TNode> Build()
615617
{
616618
if (IsDisposed) { ThrowUtility.ObjectDisposed(); }
617619
if (_prims == null) { ThrowUtility.InvalidOperation("primitives cannot be null"); }
@@ -655,7 +657,7 @@ public unsafe ref TNode Build()
655657
maxLeafSize = _maxLeafSize,
656658
traversalCost = _traversalCost,
657659
intersectionCost = _intersectionCost,
658-
bvh = NativeBVH.DangerousGetHandle(),
660+
bvh = NativeBVH,
659661
primitives = primitives,
660662
primitiveCount = primitiveCount,
661663
primitiveArrayCapacity = primitiveArrayCapacity,
@@ -675,7 +677,7 @@ public unsafe ref TNode Build()
675677
GC.KeepAlive(nCreateLeaf);
676678
GC.KeepAlive(nSplitPrim);
677679
GC.KeepAlive(nProgMonitor);
678-
return ref _result.Value;
680+
return _result;
679681
}
680682
finally
681683
{

EmbreeSharp/EmbreeDevice.cs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace EmbreeSharp
1111
public class EmbreeDevice : IDisposable
1212
{
1313
private GCHandle _gcHandle;
14-
private readonly RTCDevice _device;
14+
private RTCDeviceHandle _device;
1515
private ErrorFunction? _errorFunc;
1616
private MemoryMonitorFunction? _memMonitor;
1717
private bool _disposedValue = false;
@@ -24,7 +24,7 @@ public RTCDevice NativeDevice
2424
{
2525
ThrowUtility.ObjectDisposed();
2626
}
27-
return _device;
27+
return new RTCDevice() { Ptr = _device.DangerousGetHandle() };
2828
}
2929
}
3030
public bool IsDisposed => _disposedValue;
@@ -34,7 +34,8 @@ public EmbreeDevice()
3434
_gcHandle = GCHandle.Alloc(this);
3535
unsafe
3636
{
37-
_device = EmbreeNative.rtcNewDevice(null);
37+
var device = EmbreeNative.rtcNewDevice(null);
38+
_device = new RTCDeviceHandle(device);
3839
}
3940
}
4041

@@ -46,7 +47,8 @@ public unsafe EmbreeDevice(string config)
4647
Encoding.UTF8.GetBytes(config, configBytes);
4748
fixed (byte* ptr = configBytes)
4849
{
49-
_device = EmbreeNative.rtcNewDevice(ptr);
50+
var device = EmbreeNative.rtcNewDevice(ptr);
51+
_device = new RTCDeviceHandle(device);
5052
}
5153
}
5254

@@ -66,12 +68,13 @@ protected virtual void Dispose(bool disposing)
6668
}
6769
unsafe
6870
{
69-
EmbreeNative.rtcSetDeviceErrorFunction(_device, null, null);
70-
EmbreeNative.rtcSetDeviceMemoryMonitorFunction(_device, null, null);
71+
EmbreeNative.rtcSetDeviceErrorFunction(NativeDevice, null, null);
72+
EmbreeNative.rtcSetDeviceMemoryMonitorFunction(NativeDevice, null, null);
7173
}
7274
_gcHandle.Free();
7375
_gcHandle = default;
7476
_device.Dispose();
77+
_device = null!;
7578
_disposedValue = true;
7679
}
7780
}
@@ -88,7 +91,7 @@ public long GetProperty(RTCDeviceProperty prop)
8891
{
8992
ThrowUtility.ObjectDisposed();
9093
}
91-
var result = EmbreeNative.rtcGetDeviceProperty(_device, prop);
94+
var result = EmbreeNative.rtcGetDeviceProperty(NativeDevice, prop);
9295
return result.ToInt64();
9396
}
9497

@@ -98,7 +101,7 @@ public void SetProperty(RTCDeviceProperty prop, long value)
98101
{
99102
ThrowUtility.ObjectDisposed();
100103
}
101-
EmbreeNative.rtcSetDeviceProperty(_device, prop, new nint(value));
104+
EmbreeNative.rtcSetDeviceProperty(NativeDevice, prop, new nint(value));
102105
}
103106

104107
public RTCError GetError()
@@ -107,7 +110,7 @@ public RTCError GetError()
107110
{
108111
ThrowUtility.ObjectDisposed();
109112
}
110-
return EmbreeNative.rtcGetDeviceError(_device);
113+
return EmbreeNative.rtcGetDeviceError(NativeDevice);
111114
}
112115

113116
private static unsafe void ErrorFunctionImpl(void* userPtr, RTCError code, byte* str)
@@ -133,11 +136,11 @@ public unsafe void SetErrorFunction(ErrorFunction? func)
133136
_errorFunc = func;
134137
if (func == null)
135138
{
136-
EmbreeNative.rtcSetDeviceErrorFunction(_device, null, null);
139+
EmbreeNative.rtcSetDeviceErrorFunction(NativeDevice, null, null);
137140
}
138141
else
139142
{
140-
EmbreeNative.rtcSetDeviceErrorFunction(_device, ErrorFunctionImpl, GCHandle.ToIntPtr(_gcHandle).ToPointer());
143+
EmbreeNative.rtcSetDeviceErrorFunction(NativeDevice, ErrorFunctionImpl, GCHandle.ToIntPtr(_gcHandle).ToPointer());
141144
}
142145
}
143146

@@ -157,11 +160,11 @@ public unsafe void SetMemoryMonitorFunction(MemoryMonitorFunction? func)
157160
_memMonitor = func;
158161
if (func == null)
159162
{
160-
EmbreeNative.rtcSetDeviceMemoryMonitorFunction(_device, null, null);
163+
EmbreeNative.rtcSetDeviceMemoryMonitorFunction(NativeDevice, null, null);
161164
}
162165
else
163166
{
164-
EmbreeNative.rtcSetDeviceMemoryMonitorFunction(_device, MemoryMonitorFunctionImpl, GCHandle.ToIntPtr(_gcHandle).ToPointer());
167+
EmbreeNative.rtcSetDeviceMemoryMonitorFunction(NativeDevice, MemoryMonitorFunctionImpl, GCHandle.ToIntPtr(_gcHandle).ToPointer());
165168
}
166169
}
167170
}

0 commit comments

Comments
 (0)