Browse Source

Merge pull request #3713 from AvaloniaUI/x11-immediate-renderer-shim

Immediate rendering support for X11 platform via render loop
pull/3747/head
Steven Kirk 6 years ago
committed by GitHub
parent
commit
73884046d8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 107
      src/Avalonia.X11/X11ImmediateRendererProxy.cs
  2. 1
      src/Avalonia.X11/X11Platform.cs
  3. 20
      src/Avalonia.X11/X11Window.cs

107
src/Avalonia.X11/X11ImmediateRendererProxy.cs

@ -0,0 +1,107 @@
using System;
using System.Collections.Generic;
using Avalonia.Rendering;
using Avalonia.Threading;
using Avalonia.VisualTree;
namespace Avalonia.X11
{
public class X11ImmediateRendererProxy : IRenderer, IRenderLoopTask
{
private readonly IRenderLoop _loop;
private ImmediateRenderer _renderer;
private bool _invalidated;
private object _lock = new object();
public X11ImmediateRendererProxy(IVisual root, IRenderLoop loop)
{
_loop = loop;
_renderer = new ImmediateRenderer(root);
}
public void Dispose()
{
_renderer.Dispose();
}
public bool DrawFps
{
get => _renderer.DrawFps;
set => _renderer.DrawFps = value;
}
public bool DrawDirtyRects
{
get => _renderer.DrawDirtyRects;
set => _renderer.DrawDirtyRects = value;
}
public event EventHandler<SceneInvalidatedEventArgs> SceneInvalidated
{
add => _renderer.SceneInvalidated += value;
remove => _renderer.SceneInvalidated -= value;
}
public void AddDirty(IVisual visual)
{
lock (_lock)
_invalidated = true;
_renderer.AddDirty(visual);
}
public IEnumerable<IVisual> HitTest(Point p, IVisual root, Func<IVisual, bool> filter)
{
return _renderer.HitTest(p, root, filter);
}
public IVisual HitTestFirst(Point p, IVisual root, Func<IVisual, bool> filter)
{
return _renderer.HitTestFirst(p, root, filter);
}
public void RecalculateChildren(IVisual visual)
{
_renderer.RecalculateChildren(visual);
}
public void Resized(Size size)
{
_renderer.Resized(size);
}
public void Paint(Rect rect)
{
_invalidated = false;
_renderer.Paint(rect);
}
public void Start()
{
_loop.Add(this);
_renderer.Start();
}
public void Stop()
{
_loop.Remove(this);
_renderer.Stop();
}
public bool NeedsUpdate => false;
public void Update(TimeSpan time)
{
}
public void Render()
{
if (_invalidated)
{
lock (_lock)
_invalidated = false;
Dispatcher.UIThread.Post(() => Paint(new Rect(0, 0, 100000, 100000)));
}
}
}
}

1
src/Avalonia.X11/X11Platform.cs

@ -96,6 +96,7 @@ namespace Avalonia
public bool UseGpu { get; set; } = true;
public bool OverlayPopups { get; set; }
public bool UseDBusMenu { get; set; }
public bool UseDeferredRendering { get; set; } = true;
public List<string> GlxRendererBlacklist { get; set; } = new List<string>
{

20
src/Avalonia.X11/X11Window.cs

@ -27,7 +27,6 @@ namespace Avalonia.X11
private readonly IWindowImpl _popupParent;
private readonly bool _popup;
private readonly X11Info _x11;
private bool _invalidated;
private XConfigureEvent? _configure;
private PixelPoint? _configurePoint;
private bool _triggeredExpose;
@ -309,8 +308,13 @@ namespace Avalonia.X11
public Action Closed { get; set; }
public Action<PixelPoint> PositionChanged { get; set; }
public IRenderer CreateRenderer(IRenderRoot root) =>
new DeferredRenderer(root, AvaloniaLocator.Current.GetService<IRenderLoop>());
public IRenderer CreateRenderer(IRenderRoot root)
{
var loop = AvaloniaLocator.Current.GetService<IRenderLoop>();
return _platform.Options.UseDeferredRendering ?
new DeferredRenderer(root, loop) :
(IRenderer)new X11ImmediateRendererProxy(root, loop);
}
void OnEvent(XEvent ev)
{
@ -684,20 +688,12 @@ namespace Avalonia.X11
void DoPaint()
{
_invalidated = false;
Paint?.Invoke(new Rect());
}
public void Invalidate(Rect rect)
{
if(_invalidated)
return;
_invalidated = true;
Dispatcher.UIThread.InvokeAsync(() =>
{
if (_mapped)
DoPaint();
});
}
public IInputRoot InputRoot => _inputRoot;

Loading…
Cancel
Save