Browse Source

Added Dispose for CompositionTarget

pull/8105/head
Nikita Tsukanov 4 years ago
parent
commit
dbbed2c70b
  1. 5
      src/Avalonia.Base/Rendering/Composition/CompositionObject.cs
  2. 27
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs
  3. 2
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs
  4. 4
      src/Avalonia.Base/Rendering/Composition/Server/ServerObject.cs

5
src/Avalonia.Base/Rendering/Composition/CompositionObject.cs

@ -25,7 +25,7 @@ namespace Avalonia.Rendering.Composition
public void Dispose() public void Dispose()
{ {
//Changes.Dispose = true; RegisterForSerialization();
IsDisposed = true; IsDisposed = true;
} }
@ -112,7 +112,8 @@ namespace Avalonia.Rendering.Composition
private protected virtual void SerializeChangesCore(BatchStreamWriter writer) private protected virtual void SerializeChangesCore(BatchStreamWriter writer)
{ {
if (Server is IDisposable)
writer.Write((byte)(IsDisposed ? 1 : 0));
} }
} }
} }

27
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs

@ -9,7 +9,7 @@ using Avalonia.Utilities;
namespace Avalonia.Rendering.Composition.Server namespace Avalonia.Rendering.Composition.Server
{ {
internal partial class ServerCompositionTarget internal partial class ServerCompositionTarget : IDisposable
{ {
private readonly ServerCompositor _compositor; private readonly ServerCompositor _compositor;
private readonly Func<IRenderTarget> _renderTargetFactory; private readonly Func<IRenderTarget> _renderTargetFactory;
@ -23,6 +23,7 @@ namespace Avalonia.Rendering.Composition.Server
private Size _layerSize; private Size _layerSize;
private IDrawingContextLayerImpl? _layer; private IDrawingContextLayerImpl? _layer;
private bool _redrawRequested; private bool _redrawRequested;
private bool _disposed;
public ReadbackIndices Readback { get; } = new(); public ReadbackIndices Readback { get; } = new();
@ -50,6 +51,12 @@ namespace Avalonia.Rendering.Composition.Server
public void Render() public void Render()
{ {
if (_disposed)
{
Compositor.RemoveCompositionTarget(this);
return;
}
if (Root == null) if (Root == null)
return; return;
_renderTarget ??= _renderTargetFactory(); _renderTarget ??= _renderTargetFactory();
@ -69,6 +76,12 @@ namespace Avalonia.Rendering.Composition.Server
_redrawRequested = false; _redrawRequested = false;
using (var targetContext = _renderTarget.CreateDrawingContext(null)) using (var targetContext = _renderTarget.CreateDrawingContext(null))
{ {
// This is a hack to safely dispose layer created by some other render target
// because we can only dispose layers with the corresponding GPU context being
// active on the current thread
while (Compositor.LayersToDispose.Count > 0)
Compositor.LayersToDispose.Dequeue().Dispose();
var layerSize = Size * Scaling; var layerSize = Size * Scaling;
if (layerSize != _layerSize || _layer == null) if (layerSize != _layerSize || _layer == null)
{ {
@ -130,5 +143,17 @@ namespace Avalonia.Rendering.Composition.Server
{ {
_redrawRequested = true; _redrawRequested = true;
} }
public void Dispose()
{
_disposed = true;
if (_layer != null)
{
Compositor.LayersToDispose.Enqueue(_layer);
_layer = null;
}
_renderTarget?.Dispose();
_renderTarget = null;
}
} }
} }

2
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Avalonia.Platform;
using Avalonia.Rendering.Composition.Animations; using Avalonia.Rendering.Composition.Animations;
using Avalonia.Rendering.Composition.Expressions; using Avalonia.Rendering.Composition.Expressions;
using Avalonia.Rendering.Composition.Transport; using Avalonia.Rendering.Composition.Transport;
@ -19,6 +20,7 @@ namespace Avalonia.Rendering.Composition.Server
private List<IAnimationInstance> _animationsToUpdate = new(); private List<IAnimationInstance> _animationsToUpdate = new();
private BatchStreamObjectPool<object?> _batchObjectPool; private BatchStreamObjectPool<object?> _batchObjectPool;
private BatchStreamMemoryPool _batchMemoryPool; private BatchStreamMemoryPool _batchMemoryPool;
public Queue<IDrawingContextLayerImpl> LayersToDispose { get; } = new();
public ServerCompositor(IRenderLoop renderLoop, BatchStreamObjectPool<object?> batchObjectPool, BatchStreamMemoryPool batchMemoryPool) public ServerCompositor(IRenderLoop renderLoop, BatchStreamObjectPool<object?> batchObjectPool, BatchStreamMemoryPool batchMemoryPool)
{ {

4
src/Avalonia.Base/Rendering/Composition/Server/ServerObject.cs

@ -107,7 +107,9 @@ namespace Avalonia.Rendering.Composition.Server
protected virtual void DeserializeChangesCore(BatchStreamReader reader, TimeSpan commitedAt) protected virtual void DeserializeChangesCore(BatchStreamReader reader, TimeSpan commitedAt)
{ {
if (this is IDisposable disp
&& reader.Read<byte>() == 1)
disp.Dispose();
} }
public void DeserializeChanges(BatchStreamReader reader, Batch batch) public void DeserializeChanges(BatchStreamReader reader, Batch batch)

Loading…
Cancel
Save