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()
{
//Changes.Dispose = true;
RegisterForSerialization();
IsDisposed = true;
}
@ -112,7 +112,8 @@ namespace Avalonia.Rendering.Composition
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
{
internal partial class ServerCompositionTarget
internal partial class ServerCompositionTarget : IDisposable
{
private readonly ServerCompositor _compositor;
private readonly Func<IRenderTarget> _renderTargetFactory;
@ -23,6 +23,7 @@ namespace Avalonia.Rendering.Composition.Server
private Size _layerSize;
private IDrawingContextLayerImpl? _layer;
private bool _redrawRequested;
private bool _disposed;
public ReadbackIndices Readback { get; } = new();
@ -50,6 +51,12 @@ namespace Avalonia.Rendering.Composition.Server
public void Render()
{
if (_disposed)
{
Compositor.RemoveCompositionTarget(this);
return;
}
if (Root == null)
return;
_renderTarget ??= _renderTargetFactory();
@ -69,6 +76,12 @@ namespace Avalonia.Rendering.Composition.Server
_redrawRequested = false;
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;
if (layerSize != _layerSize || _layer == null)
{
@ -130,5 +143,17 @@ namespace Avalonia.Rendering.Composition.Server
{
_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.Collections.Generic;
using System.Diagnostics;
using Avalonia.Platform;
using Avalonia.Rendering.Composition.Animations;
using Avalonia.Rendering.Composition.Expressions;
using Avalonia.Rendering.Composition.Transport;
@ -19,6 +20,7 @@ namespace Avalonia.Rendering.Composition.Server
private List<IAnimationInstance> _animationsToUpdate = new();
private BatchStreamObjectPool<object?> _batchObjectPool;
private BatchStreamMemoryPool _batchMemoryPool;
public Queue<IDrawingContextLayerImpl> LayersToDispose { get; } = new();
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)
{
if (this is IDisposable disp
&& reader.Read<byte>() == 1)
disp.Dispose();
}
public void DeserializeChanges(BatchStreamReader reader, Batch batch)

Loading…
Cancel
Save