8 changed files with 265 additions and 19 deletions
@ -0,0 +1,56 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Avalonia.Win32.Interop; |
||||
|
using SharpDX; |
||||
|
using SharpDX.DXGI; |
||||
|
|
||||
|
namespace Avalonia.Direct2D1 |
||||
|
{ |
||||
|
class HwndRenderTarget : SwapChainRenderTarget |
||||
|
{ |
||||
|
private readonly IntPtr _hwnd; |
||||
|
|
||||
|
public HwndRenderTarget(IntPtr hwnd) |
||||
|
{ |
||||
|
_hwnd = hwnd; |
||||
|
} |
||||
|
|
||||
|
protected override SwapChain1 CreateSwapChain(Factory2 dxgiFactory, SwapChainDescription1 swapChainDesc) |
||||
|
{ |
||||
|
return new SwapChain1(dxgiFactory, Device, _hwnd, ref swapChainDesc); |
||||
|
} |
||||
|
|
||||
|
protected override Size2F GetWindowDpi() |
||||
|
{ |
||||
|
if (UnmanagedMethods.ShCoreAvailable) |
||||
|
{ |
||||
|
uint dpix, dpiy; |
||||
|
|
||||
|
var monitor = UnmanagedMethods.MonitorFromWindow( |
||||
|
_hwnd, |
||||
|
UnmanagedMethods.MONITOR.MONITOR_DEFAULTTONEAREST); |
||||
|
|
||||
|
if (UnmanagedMethods.GetDpiForMonitor( |
||||
|
monitor, |
||||
|
UnmanagedMethods.MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, |
||||
|
out dpix, |
||||
|
out dpiy) == 0) |
||||
|
{ |
||||
|
return new Size2F(dpix, dpiy); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return new Size2F(96, 96); |
||||
|
} |
||||
|
|
||||
|
protected override Size2 GetWindowSize() |
||||
|
{ |
||||
|
UnmanagedMethods.RECT rc; |
||||
|
UnmanagedMethods.GetClientRect(_hwnd, out rc); |
||||
|
return new Size2(rc.right - rc.left, rc.bottom - rc.top); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,134 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Avalonia.Media; |
||||
|
using Avalonia.Platform; |
||||
|
using Avalonia.Win32.Interop; |
||||
|
using SharpDX; |
||||
|
using SharpDX.Direct2D1; |
||||
|
using SharpDX.DXGI; |
||||
|
using AlphaMode = SharpDX.Direct2D1.AlphaMode; |
||||
|
using Device = SharpDX.Direct2D1.Device; |
||||
|
using Factory = SharpDX.Direct2D1.Factory; |
||||
|
using Factory2 = SharpDX.DXGI.Factory2; |
||||
|
|
||||
|
namespace Avalonia.Direct2D1 |
||||
|
{ |
||||
|
public abstract class SwapChainRenderTarget : IRenderTarget |
||||
|
{ |
||||
|
private Size2 _savedSize; |
||||
|
private Size2F _savedDpi; |
||||
|
private DeviceContext _deviceContext; |
||||
|
private SwapChain1 _swapChain; |
||||
|
|
||||
|
protected SwapChainRenderTarget() |
||||
|
{ |
||||
|
Device = AvaloniaLocator.Current.GetService<SharpDX.DXGI.Device>(); |
||||
|
Direct2DFactory = AvaloniaLocator.Current.GetService<Factory>(); |
||||
|
DirectWriteFactory = AvaloniaLocator.Current.GetService<SharpDX.DirectWrite.Factory>(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the Direct2D factory.
|
||||
|
/// </summary>
|
||||
|
public Factory Direct2DFactory |
||||
|
{ |
||||
|
get; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the DirectWrite factory.
|
||||
|
/// </summary>
|
||||
|
public SharpDX.DirectWrite.Factory DirectWriteFactory |
||||
|
{ |
||||
|
get; |
||||
|
} |
||||
|
|
||||
|
protected SharpDX.DXGI.Device Device { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Creates a drawing context for a rendering session.
|
||||
|
/// </summary>
|
||||
|
/// <returns>An <see cref="Avalonia.Media.DrawingContext"/>.</returns>
|
||||
|
public DrawingContext CreateDrawingContext() |
||||
|
{ |
||||
|
var size = GetWindowSize(); |
||||
|
var dpi = GetWindowDpi(); |
||||
|
|
||||
|
if (size != _savedSize || dpi != _savedDpi) |
||||
|
{ |
||||
|
_savedSize = size; |
||||
|
_savedDpi = dpi; |
||||
|
CreateSwapChain(); |
||||
|
} |
||||
|
|
||||
|
return new DrawingContext(new Media.DrawingContext(_deviceContext, DirectWriteFactory, _swapChain)); |
||||
|
} |
||||
|
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
_deviceContext.Dispose(); |
||||
|
_swapChain.Dispose(); |
||||
|
} |
||||
|
|
||||
|
private void CreateSwapChain() |
||||
|
{ |
||||
|
using (var d2dDevice = new Device(Device)) |
||||
|
using (var dxgiAdaptor = Device.Adapter) |
||||
|
using (var dxgiFactory = dxgiAdaptor.GetParent<Factory2>()) |
||||
|
{ |
||||
|
_deviceContext?.Dispose(); |
||||
|
_deviceContext = new DeviceContext(d2dDevice, DeviceContextOptions.None); |
||||
|
|
||||
|
var swapChainDesc = new SwapChainDescription1 |
||||
|
{ |
||||
|
Width = _savedSize.Width, |
||||
|
Height = _savedSize.Height, |
||||
|
Format = Format.B8G8R8A8_UNorm, |
||||
|
Stereo = false, |
||||
|
SampleDescription = new SampleDescription |
||||
|
{ |
||||
|
Count = 1, |
||||
|
Quality = 0, |
||||
|
}, |
||||
|
Usage = Usage.RenderTargetOutput, |
||||
|
BufferCount = 2, |
||||
|
Scaling = Scaling.None, |
||||
|
SwapEffect = SwapEffect.FlipSequential, |
||||
|
Flags = 0, |
||||
|
}; |
||||
|
|
||||
|
var dpi = Direct2DFactory.DesktopDpi; |
||||
|
|
||||
|
_swapChain?.Dispose(); |
||||
|
_swapChain = CreateSwapChain(dxgiFactory, swapChainDesc); |
||||
|
|
||||
|
using (var dxgiBackBuffer = _swapChain.GetBackBuffer<Surface>(0)) |
||||
|
using (var d2dBackBuffer = new Bitmap1( |
||||
|
_deviceContext, |
||||
|
dxgiBackBuffer, |
||||
|
new BitmapProperties1( |
||||
|
new PixelFormat |
||||
|
{ |
||||
|
AlphaMode = AlphaMode.Ignore, |
||||
|
Format = Format.B8G8R8A8_UNorm |
||||
|
}, |
||||
|
_savedDpi.Width, |
||||
|
_savedDpi.Height, |
||||
|
BitmapOptions.Target | BitmapOptions.CannotDraw))) |
||||
|
{ |
||||
|
_deviceContext.Target = d2dBackBuffer; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected abstract SwapChain1 CreateSwapChain(Factory2 dxgiFactory, SwapChainDescription1 swapChainDesc); |
||||
|
|
||||
|
protected abstract Size2F GetWindowDpi(); |
||||
|
|
||||
|
protected abstract Size2 GetWindowSize(); |
||||
|
} |
||||
|
} |
||||
@ -1,6 +1,7 @@ |
|||||
<?xml version="1.0" encoding="utf-8"?> |
<?xml version="1.0" encoding="utf-8"?> |
||||
<packages> |
<packages> |
||||
<package id="SharpDX" version="3.1.0" targetFramework="net45" /> |
<package id="SharpDX" version="3.1.1" targetFramework="net45" /> |
||||
<package id="SharpDX.Direct2D1" version="3.1.0" targetFramework="net45" /> |
<package id="SharpDX.Direct2D1" version="3.1.1" targetFramework="net45" /> |
||||
<package id="SharpDX.DXGI" version="3.1.0" targetFramework="net45" /> |
<package id="SharpDX.Direct3D11" version="3.1.1" targetFramework="net45" /> |
||||
|
<package id="SharpDX.DXGI" version="3.1.1" targetFramework="net45" /> |
||||
</packages> |
</packages> |
||||
Loading…
Reference in new issue