forked from AvaloniaUI/Avalonia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Metal.cs
119 lines (95 loc) · 2.8 KB
/
Metal.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
using System;
using Avalonia.Metal;
using Avalonia.Native.Interop;
using Avalonia.Platform;
using Avalonia.Threading;
using Avalonia.Utilities;
namespace Avalonia.Native;
class MetalPlatformGraphics : IPlatformGraphics
{
private readonly IAvnMetalDisplay _display;
public MetalPlatformGraphics(IAvaloniaNativeFactory factory)
{
_display = factory.ObtainMetalDisplay();
}
public bool UsesSharedContext => false;
public IPlatformGraphicsContext CreateContext() => new MetalDevice(_display.CreateDevice());
public IPlatformGraphicsContext GetSharedContext() => throw new NotSupportedException();
}
class MetalDevice : IMetalDevice
{
public IAvnMetalDevice Native { get; private set; }
private DisposableLock _syncRoot = new();
public MetalDevice(IAvnMetalDevice native)
{
Native = native;
}
public void Dispose()
{
Native?.Dispose();
Native = null;
}
public object TryGetFeature(Type featureType) => null;
public bool IsLost => false;
public IDisposable EnsureCurrent() => _syncRoot.Lock();
public IntPtr Device => Native.Device;
public IntPtr CommandQueue => Native.Queue;
}
class MetalPlatformSurface : IMetalPlatformSurface
{
private readonly IAvnWindowBase _window;
public MetalPlatformSurface(IAvnWindowBase window)
{
_window = window;
}
public IMetalPlatformSurfaceRenderTarget CreateMetalRenderTarget(IMetalDevice device)
{
if (!Dispatcher.UIThread.CheckAccess())
throw new RenderTargetNotReadyException();
var dev = (MetalDevice)device;
var target = _window.CreateMetalRenderTarget(dev.Native);
return new MetalRenderTarget(target);
}
}
internal class MetalRenderTarget : IMetalPlatformSurfaceRenderTarget
{
private IAvnMetalRenderTarget _native;
public MetalRenderTarget(IAvnMetalRenderTarget native)
{
_native = native;
}
public void Dispose()
{
_native?.Dispose();
_native = null;
}
public IMetalPlatformSurfaceRenderingSession BeginRendering()
{
var session = _native.BeginDrawing();
return new MetalDrawingSession(session);
}
}
internal class MetalDrawingSession : IMetalPlatformSurfaceRenderingSession
{
private IAvnMetalRenderingSession _session;
public MetalDrawingSession(IAvnMetalRenderingSession session)
{
_session = session;
}
public void Dispose()
{
_session?.Dispose();
_session = null;
}
public IntPtr Texture => _session.Texture;
public PixelSize Size
{
get
{
var size = _session.PixelSize;
return new(size.Width, size.Height);
}
}
public double Scaling => _session.Scaling;
public bool IsYFlipped => false;
}