Browse Source

macOS support?

pull/8105/head
Nikita Tsukanov 4 years ago
parent
commit
95b18fdf16
  1. 16
      src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
  2. 6
      src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs
  3. 11
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs
  4. 20
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  5. 5
      src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs
  6. 13
      src/Avalonia.Native/WindowImplBase.cs

16
src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs

@ -17,7 +17,6 @@ public class CompositingRenderer : RendererBase, IRendererWithCompositor
{
private readonly IRenderRoot _root;
private readonly Compositor _compositor;
private readonly IDeferredRendererLock? _rendererLock;
CompositionDrawingContext _recorder = new();
DrawingContext _recordingContext;
private HashSet<Visual> _dirty = new();
@ -26,14 +25,17 @@ public class CompositingRenderer : RendererBase, IRendererWithCompositor
private bool _queuedUpdate;
private Action _update;
/// <summary>
/// Forces the renderer to only draw frames on the render thread. Makes Paint to wait until frame is rendered
/// </summary>
public bool RenderOnlyOnRenderThread { get; set; } = true;
public CompositingRenderer(IRenderRoot root,
Compositor compositor,
IDeferredRendererLock? rendererLock = null)
Compositor compositor)
{
_root = root;
_compositor = compositor;
_recordingContext = new DrawingContext(_recorder);
_rendererLock = rendererLock ?? new ManagedDeferredRendererLock();
_target = compositor.CreateCompositionTarget(root.CreateRenderTarget);
_target.Root = ((Visual)root!.VisualRoot!).AttachToCompositor(compositor);
_update = Update;
@ -228,10 +230,12 @@ public class CompositingRenderer : RendererBase, IRendererWithCompositor
public void Paint(Rect rect)
{
// We render only on the render thread for now
Update();
_target.RequestRedraw();
Compositor.RequestCommitAsync().Wait();
if(RenderOnlyOnRenderThread)
Compositor.RequestCommitAsync().Wait();
else
_target.ImmediateUIThreadRender();
}
public void Start() => _target.IsEnabled = true;

6
src/Avalonia.Base/Rendering/Composition/CompositionTarget.cs

@ -109,5 +109,11 @@ namespace Avalonia.Rendering.Composition
}
public void RequestRedraw() => RegisterForSerialization();
internal void ImmediateUIThreadRender()
{
Compositor.RequestCommitAsync();
Compositor.Server.Render();
}
}
}

11
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs

@ -20,6 +20,7 @@ namespace Avalonia.Rendering.Composition.Server
private List<IAnimationInstance> _animationsToUpdate = new();
private BatchStreamObjectPool<object?> _batchObjectPool;
private BatchStreamMemoryPool _batchMemoryPool;
private object _lock = new object();
public IPlatformGpuContext? GpuContext { get; }
public ServerCompositor(IRenderLoop renderLoop, IPlatformGpu? platformGpu,
@ -88,7 +89,15 @@ namespace Avalonia.Rendering.Composition.Server
{
}
void IRenderLoopTask.Render()
public void Render()
{
lock (_lock)
{
RenderCore();
}
}
private void RenderCore()
{
ApplyPendingBatches();

20
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -8,6 +8,8 @@ using Avalonia.Native.Interop;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
using JetBrains.Annotations;
namespace Avalonia.Native
{
@ -21,6 +23,7 @@ namespace Avalonia.Native
static extern IntPtr CreateAvaloniaNative();
internal static readonly KeyboardDevice KeyboardDevice = new KeyboardDevice();
[CanBeNull] internal static Compositor Compositor { get; private set; }
public Size DoubleClickSize => new Size(4, 4);
@ -101,6 +104,7 @@ namespace Avalonia.Native
_factory.MacOptions.SetShowInDock(macOpts.ShowInDock ? 1 : 0);
}
var renderLoop = new RenderLoop();
AvaloniaLocator.CurrentMutable
.Bind<IPlatformThreadingInterface>()
.ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface()))
@ -110,7 +114,7 @@ namespace Avalonia.Native
.Bind<IPlatformSettings>().ToConstant(this)
.Bind<IWindowingPlatform>().ToConstant(this)
.Bind<IClipboard>().ToConstant(new ClipboardImpl(_factory.CreateClipboard()))
.Bind<IRenderLoop>().ToConstant(new RenderLoop())
.Bind<IRenderLoop>().ToConstant(renderLoop)
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs()))
.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Meta, wholeWordTextActionModifiers: KeyModifiers.Alt))
@ -124,19 +128,27 @@ namespace Avalonia.Native
hotkeys.MoveCursorToTheStartOfLineWithSelection.Add(new KeyGesture(Key.Left, hotkeys.CommandModifiers | hotkeys.SelectionModifiers));
hotkeys.MoveCursorToTheEndOfLine.Add(new KeyGesture(Key.Right, hotkeys.CommandModifiers));
hotkeys.MoveCursorToTheEndOfLineWithSelection.Add(new KeyGesture(Key.Right, hotkeys.CommandModifiers | hotkeys.SelectionModifiers));
if (_options.UseGpu)
{
try
{
AvaloniaLocator.CurrentMutable.Bind<IPlatformOpenGlInterface>()
.ToConstant(_platformGl = new AvaloniaNativePlatformOpenGlInterface(_factory.ObtainGlDisplay()));
_platformGl = new AvaloniaNativePlatformOpenGlInterface(_factory.ObtainGlDisplay());
AvaloniaLocator.CurrentMutable
.Bind<IPlatformOpenGlInterface>().ToConstant(_platformGl)
.Bind<IPlatformGpu>().ToConstant(_platformGl);
}
catch (Exception)
{
// ignored
}
}
if (_options.UseDeferredRendering && _options.UseCompositor)
{
Compositor = new Compositor(renderLoop, _platformGl);
}
}
public ITrayIconImpl CreateTrayIcon()

5
src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs

@ -39,6 +39,11 @@ namespace Avalonia
/// Immediate re-renders the whole scene when some element is changed on the scene. Deferred re-renders only changed elements.
/// </remarks>
public bool UseDeferredRendering { get; set; } = true;
/// <summary>
/// Enables new compositing rendering with UWP-like API
/// </summary>
public bool UseCompositor { get; set; }
/// <summary>
/// Determines whether to use GPU for rendering in your project. The default value is true.

13
src/Avalonia.Native/WindowImplBase.cs

@ -12,6 +12,7 @@ using Avalonia.Native.Interop;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
using Avalonia.Threading;
namespace Avalonia.Native
@ -363,13 +364,15 @@ namespace Avalonia.Native
public IRenderer CreateRenderer(IRenderRoot root)
{
var customRendererFactory = AvaloniaLocator.Current.GetService<IRendererFactory>();
var loop = AvaloniaLocator.Current.GetService<IRenderLoop>();
if (customRendererFactory != null)
return customRendererFactory.Create(root, loop);
if (_deferredRendering)
{
var loop = AvaloniaLocator.Current.GetService<IRenderLoop>();
var customRendererFactory = AvaloniaLocator.Current.GetService<IRendererFactory>();
if (customRendererFactory != null)
return customRendererFactory.Create(root, loop);
if (AvaloniaNativePlatform.Compositor != null)
return new CompositingRenderer(root, AvaloniaNativePlatform.Compositor);
return new DeferredRenderer(root, loop);
}

Loading…
Cancel
Save