csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.4 KiB
136 lines
4.4 KiB
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 PixelFormat = SharpDX.Direct2D1.PixelFormat;
|
|
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()
|
|
{
|
|
DxgiDevice = AvaloniaLocator.Current.GetService<SharpDX.DXGI.Device>();
|
|
D2DDevice = AvaloniaLocator.Current.GetService<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 DxgiDevice { get; }
|
|
|
|
public Device D2DDevice { 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.DrawingContextImpl(_deviceContext, DirectWriteFactory, _swapChain));
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_deviceContext?.Dispose();
|
|
_swapChain?.Dispose();
|
|
}
|
|
|
|
private void CreateSwapChain()
|
|
{
|
|
using (var dxgiAdaptor = DxgiDevice.Adapter)
|
|
using (var dxgiFactory = dxgiAdaptor.GetParent<Factory2>())
|
|
{
|
|
_deviceContext?.Dispose();
|
|
_deviceContext = new DeviceContext(D2DDevice, DeviceContextOptions.None) {DotsPerInch = _savedDpi};
|
|
|
|
|
|
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,
|
|
};
|
|
|
|
_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();
|
|
}
|
|
}
|
|
|