diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/Direct2DImageSurface.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/Direct2DImageSurface.cs index 303e0850aa..57efe700dd 100644 --- a/src/Windows/Avalonia.Win32.Interop/Wpf/Direct2DImageSurface.cs +++ b/src/Windows/Avalonia.Win32.Interop/Wpf/Direct2DImageSurface.cs @@ -24,17 +24,18 @@ using Usage = SharpDX.Direct3D9.Usage; namespace Avalonia.Win32.Interop.Wpf { - class Direct2DImageSurface : IExternalDirect2DRenderTargetSurface + class Direct2DImageSurface : IExternalDirect2DRenderTargetSurface, IDisposable { - class Pair: IDisposable + class SwapBuffer: IDisposable { + + private readonly SharpDX.Direct3D11.Resource _resource; + private readonly SharpDX.Direct3D11.Resource _stagingResource; public SharpDX.Direct3D9.Surface Texture { get; } - public SharpDX.Direct3D11.Resource D3D11Resource { get; } - public SharpDX.Direct3D11.Resource StagingResource { get; } public RenderTarget Target { get;} public Size Size { get; } - public Pair(Size size, Vector dpi) + public SwapBuffer(Size size, Vector dpi) { int width = (int) size.Width; int height = (int) size.Height; @@ -53,7 +54,7 @@ namespace Avalonia.Win32.Interop.Wpf using (var surface = texture.QueryInterface()) using (var resource = texture.QueryInterface()) { - D3D11Resource = texture.QueryInterface(); + _resource = texture.QueryInterface(); var handle = resource.SharedHandle; using (var texture9 = new Texture(s_d3DDevice, texture.Description.Width, texture.Description.Height, 1, @@ -80,7 +81,7 @@ namespace Avalonia.Win32.Interop.Wpf SampleDescription = new SampleDescription(1, 0), CpuAccessFlags = CpuAccessFlags.Read })) - StagingResource = texture.QueryInterface(); + _stagingResource = texture.QueryInterface(); Size = size; } @@ -88,24 +89,22 @@ namespace Avalonia.Win32.Interop.Wpf { Texture?.Dispose(); Target?.Dispose(); - D3D11Resource?.Dispose(); - StagingResource?.Dispose(); + _resource?.Dispose(); + _stagingResource?.Dispose(); } public void Flush() { - - s_dxDevice.ImmediateContext.CopySubresourceRegion(D3D11Resource, 0, - new ResourceRegion(0, 0, 0, 1, 1, 1), StagingResource, 0, 0, 0, 0); - s_dxDevice.ImmediateContext.MapSubresource(StagingResource, 0, MapMode.Read, MapFlags.None); - s_dxDevice.ImmediateContext.UnmapSubresource(StagingResource, 0); - + s_dxDevice.ImmediateContext.CopySubresourceRegion(_resource, 0, + new ResourceRegion(0, 0, 0, 1, 1, 1), _stagingResource, 0, 0, 0, 0); + s_dxDevice.ImmediateContext.MapSubresource(_stagingResource, 0, MapMode.Read, MapFlags.None); + s_dxDevice.ImmediateContext.UnmapSubresource(_stagingResource, 0); } } private D3DImage _image; - private Pair _backBuffer; - private Pair _frontBuffer; + private SwapBuffer _backBuffer; + private SwapBuffer _frontBuffer; private readonly WpfTopLevelImpl _impl; private static Device s_dxDevice; private static Direct3DEx s_d3DContext; @@ -149,11 +148,9 @@ namespace Avalonia.Win32.Interop.Wpf return _backBuffer.Target; if (_image == null) - _image = new DX11Image(); + _image = new D3DImage(); _impl.ImageSource = _image; - - RemoveAndDispose(ref _backBuffer); if (size == default(Size)) { @@ -163,7 +160,7 @@ namespace Avalonia.Win32.Interop.Wpf _image.Unlock(); return null; } - _backBuffer = new Pair(size, dpi); + _backBuffer = new SwapBuffer(size, dpi); return _backBuffer.Target; } @@ -174,11 +171,6 @@ namespace Avalonia.Win32.Interop.Wpf d = default(T); } - void DoSwap() - { - - } - void Swap() { var oldFront = _frontBuffer; @@ -193,6 +185,8 @@ namespace Avalonia.Win32.Interop.Wpf public void DestroyRenderTarget() { + RemoveAndDispose(ref _backBuffer); + RemoveAndDispose(ref _frontBuffer); //? } @@ -202,5 +196,10 @@ namespace Avalonia.Win32.Interop.Wpf } public void AfterDrawing() => Swap(); + public void Dispose() + { + RemoveAndDispose(ref _frontBuffer); + RemoveAndDispose(ref _backBuffer); + } } } diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfAvaloniaHost.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfAvaloniaHost.cs index e36b53199a..0a15bc26d2 100644 --- a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfAvaloniaHost.cs +++ b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfAvaloniaHost.cs @@ -21,15 +21,31 @@ namespace Avalonia.Win32.Interop.Wpf { private WpfTopLevelImpl _impl; private readonly SynchronizationContext _sync; + private bool _hasChildren; public WpfAvaloniaHost() { _sync = SynchronizationContext.Current; _impl = new WpfTopLevelImpl(); _impl.ControlRoot.Prepare(); _impl.Visibility = Visibility.Visible; - AddLogicalChild(_impl); - AddVisualChild(_impl); SnapsToDevicePixels = true; + PresentationSource.AddSourceChangedHandler(this, OnSourceChanged); + } + + private void OnSourceChanged(object sender, SourceChangedEventArgs e) + { + if (e.NewSource != null && !_hasChildren) + { + AddLogicalChild(_impl); + AddVisualChild(_impl); + _hasChildren = true; + } + else + { + RemoveVisualChild(_impl); + RemoveLogicalChild(_impl); + _hasChildren = false; + } } public object Content diff --git a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs index b5715d43d5..fbed2f621c 100644 --- a/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs +++ b/src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs @@ -88,7 +88,12 @@ namespace Avalonia.Win32.Interop.Wpf _ttl.ScalingChanged?.Invoke(_ttl.Scaling); } - public void Dispose() => _ttl.Closed?.Invoke(); + public void Dispose() + { + _ttl.Closed?.Invoke(); + foreach(var d in _surfaces.OfType()) + d.Dispose(); + } Size ITopLevelImpl.ClientSize => _finalSize; IMouseDevice ITopLevelImpl.MouseDevice => _mouse;