fix graphics resources disposing out of order

pull/14/head
cosmonaut 2021-01-26 21:06:15 -08:00
parent 7f6236cb49
commit d10f018f14
2 changed files with 44 additions and 4 deletions

View File

@ -12,6 +12,8 @@ namespace MoonWorks.Graphics
private readonly Queue<CommandBuffer> commandBufferPool; private readonly Queue<CommandBuffer> commandBufferPool;
private readonly List<WeakReference> resources = new List<WeakReference>();
public GraphicsDevice( public GraphicsDevice(
IntPtr deviceWindowHandle, IntPtr deviceWindowHandle,
Refresh.PresentMode presentMode, Refresh.PresentMode presentMode,
@ -78,16 +80,44 @@ namespace MoonWorks.Graphics
Refresh.Refresh_Wait(Handle); Refresh.Refresh_Wait(Handle);
} }
internal void AddResourceReference(WeakReference resourceReference)
{
lock (resources)
{
resources.Add(resourceReference);
}
}
internal void RemoveResourceReference(WeakReference resourceReference)
{
lock (resources)
{
resources.Remove(resourceReference);
}
}
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (!IsDisposed) if (!IsDisposed)
{ {
if (disposing) if (disposing)
{ {
// TODO: dispose managed state (managed objects) lock (resources)
{
foreach (var resource in resources)
{
var target = resource.Target;
if (target != null)
{
(target as IDisposable).Dispose();
}
}
resources.Clear();
}
Refresh.Refresh_DestroyDevice(Handle);
} }
Refresh.Refresh_DestroyDevice(Handle);
IsDisposed = true; IsDisposed = true;
} }
} }

View File

@ -1,6 +1,4 @@
using System; using System;
using System.Collections.Generic;
using System.Text;
namespace MoonWorks.Graphics namespace MoonWorks.Graphics
{ {
@ -12,9 +10,14 @@ namespace MoonWorks.Graphics
public bool IsDisposed { get; private set; } public bool IsDisposed { get; private set; }
protected abstract Action<IntPtr, IntPtr> QueueDestroyFunction { get; } protected abstract Action<IntPtr, IntPtr> QueueDestroyFunction { get; }
private WeakReference selfReference;
public GraphicsResource(GraphicsDevice device) public GraphicsResource(GraphicsDevice device)
{ {
Device = device; Device = device;
selfReference = new WeakReference(this);
Device.AddResourceReference(selfReference);
} }
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
@ -22,6 +25,13 @@ namespace MoonWorks.Graphics
if (!IsDisposed) if (!IsDisposed)
{ {
QueueDestroyFunction(Device.Handle, Handle); QueueDestroyFunction(Device.Handle, Handle);
if (selfReference != null)
{
Device.RemoveResourceReference(selfReference);
selfReference = null;
}
IsDisposed = true; IsDisposed = true;
} }
} }