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.
122 lines
3.8 KiB
122 lines
3.8 KiB
using Avalonia.Direct2D1.Media;
|
|
using Avalonia.Direct2D1.Media.Imaging;
|
|
using Avalonia.Platform;
|
|
using Avalonia.Rendering;
|
|
using SharpDX;
|
|
using SharpDX.Direct2D1;
|
|
using SharpDX.DXGI;
|
|
|
|
namespace Avalonia.Direct2D1
|
|
{
|
|
public abstract class SwapChainRenderTarget : IRenderTarget, ILayerFactory
|
|
{
|
|
private Size2 _savedSize;
|
|
private Size2F _savedDpi;
|
|
private DeviceContext _deviceContext;
|
|
private SwapChain1 _swapChain;
|
|
|
|
/// <summary>
|
|
/// Creates a drawing context for a rendering session.
|
|
/// </summary>
|
|
/// <returns>An <see cref="Avalonia.Platform.IDrawingContextImpl"/>.</returns>
|
|
public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
|
|
{
|
|
var size = GetWindowSize();
|
|
var dpi = GetWindowDpi();
|
|
|
|
if (size != _savedSize || dpi != _savedDpi)
|
|
{
|
|
_savedSize = size;
|
|
_savedDpi = dpi;
|
|
|
|
Resize();
|
|
}
|
|
|
|
return new DrawingContextImpl(visualBrushRenderer, this, _deviceContext, _swapChain);
|
|
}
|
|
|
|
public IRenderTargetBitmapImpl CreateLayer(Size size)
|
|
{
|
|
if (_deviceContext == null)
|
|
{
|
|
CreateDeviceContext();
|
|
}
|
|
|
|
return D2DRenderTargetBitmapImpl.CreateCompatible(_deviceContext, size);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_deviceContext?.Dispose();
|
|
|
|
_swapChain?.Dispose();
|
|
}
|
|
|
|
private void Resize()
|
|
{
|
|
_deviceContext?.Dispose();
|
|
_deviceContext = null;
|
|
|
|
_swapChain?.ResizeBuffers(0, 0, 0, Format.Unknown, SwapChainFlags.None);
|
|
|
|
CreateDeviceContext();
|
|
}
|
|
|
|
private void CreateSwapChain()
|
|
{
|
|
var swapChainDescription = new SwapChainDescription1
|
|
{
|
|
Width = _savedSize.Width,
|
|
Height = _savedSize.Height,
|
|
Format = Format.B8G8R8A8_UNorm,
|
|
SampleDescription = new SampleDescription
|
|
{
|
|
Count = 1,
|
|
Quality = 0,
|
|
},
|
|
Usage = Usage.RenderTargetOutput,
|
|
BufferCount = 1,
|
|
SwapEffect = SwapEffect.Discard,
|
|
};
|
|
|
|
using (var dxgiAdapter = Direct2D1Platform.DxgiDevice.Adapter)
|
|
using (var dxgiFactory = dxgiAdapter.GetParent<SharpDX.DXGI.Factory2>())
|
|
{
|
|
_swapChain = CreateSwapChain(dxgiFactory, swapChainDescription);
|
|
}
|
|
}
|
|
|
|
private void CreateDeviceContext()
|
|
{
|
|
_deviceContext = new DeviceContext(Direct2D1Platform.Direct2D1Device, DeviceContextOptions.None) { DotsPerInch = _savedDpi };
|
|
|
|
if (_swapChain == null)
|
|
{
|
|
CreateSwapChain();
|
|
}
|
|
|
|
using (var dxgiBackBuffer = _swapChain.GetBackBuffer<Surface>(0))
|
|
using (var d2dBackBuffer = new Bitmap1(
|
|
_deviceContext,
|
|
dxgiBackBuffer,
|
|
new BitmapProperties1(
|
|
new SharpDX.Direct2D1.PixelFormat
|
|
{
|
|
AlphaMode = SharpDX.Direct2D1.AlphaMode.Premultiplied,
|
|
Format = Format.B8G8R8A8_UNorm
|
|
},
|
|
_savedSize.Width,
|
|
_savedSize.Height,
|
|
BitmapOptions.Target | BitmapOptions.CannotDraw)))
|
|
{
|
|
_deviceContext.Target = d2dBackBuffer;
|
|
}
|
|
}
|
|
|
|
protected abstract SwapChain1 CreateSwapChain(SharpDX.DXGI.Factory2 dxgiFactory, SwapChainDescription1 swapChainDesc);
|
|
|
|
protected abstract Size2F GetWindowDpi();
|
|
|
|
protected abstract Size2 GetWindowSize();
|
|
}
|
|
}
|
|
|