Browse Source

Merge pull request #2321 from MarchingCube/feature/fix-drawoperations-leak

Fix draw operations leak in DeferredRenderer
pull/2324/head
Steven Kirk 8 years ago
committed by GitHub
parent
commit
304c90fc29
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 37
      src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs

37
src/Avalonia.Visuals/Rendering/SceneGraph/VisualNode.cs

@ -322,36 +322,51 @@ namespace Avalonia.Rendering.SceneGraph
} }
} }
/// <summary>
/// Ensures that this node draw operations have been created and are mutable (in case we are using cloned operations).
/// </summary>
private void EnsureDrawOperationsCreated() private void EnsureDrawOperationsCreated()
{ {
if (_drawOperations == null) if (_drawOperations == null)
{ {
_drawOperations = new List<IRef<IDrawOperation>>(); _drawOperations = new List<IRef<IDrawOperation>>();
_drawOperationsRefCounter = RefCountable.Create(Disposable.Create(DisposeDrawOperations)); _drawOperationsRefCounter = RefCountable.Create(CreateDisposeDrawOperations(_drawOperations));
_drawOperationsCloned = false; _drawOperationsCloned = false;
} }
else if (_drawOperationsCloned) else if (_drawOperationsCloned)
{ {
_drawOperations = new List<IRef<IDrawOperation>>(_drawOperations.Select(op => op.Clone())); _drawOperations = new List<IRef<IDrawOperation>>(_drawOperations.Select(op => op.Clone()));
_drawOperationsRefCounter.Dispose(); _drawOperationsRefCounter.Dispose();
_drawOperationsRefCounter = RefCountable.Create(Disposable.Create(DisposeDrawOperations)); _drawOperationsRefCounter = RefCountable.Create(CreateDisposeDrawOperations(_drawOperations));
_drawOperationsCloned = false; _drawOperationsCloned = false;
} }
} }
public bool Disposed { get; } /// <summary>
/// Creates disposable that will dispose all items in passed draw operations after being disposed.
public void Dispose() /// It is crucial that we don't capture current <see cref="VisualNode"/> instance
/// as draw operations can be cloned and may persist across subsequent scenes.
/// </summary>
/// <param name="drawOperations">Draw operations that need to be disposed.</param>
/// <returns>Disposable for given draw operations.</returns>
private static IDisposable CreateDisposeDrawOperations(List<IRef<IDrawOperation>> drawOperations)
{ {
_drawOperationsRefCounter?.Dispose(); return Disposable.Create(() =>
{
foreach (var operation in drawOperations)
{
operation.Dispose();
}
});
} }
private void DisposeDrawOperations() public bool Disposed { get; private set; }
public void Dispose()
{ {
foreach (var operation in DrawOperations) _drawOperationsRefCounter?.Dispose();
{
operation.Dispose(); Disposed = true;
}
} }
} }
} }

Loading…
Cancel
Save