Browse Source

Merge remote-tracking branch 'origin/master' into feature/ImePreeditText

feature/ImePreeditText
Dan Walmsley 4 years ago
parent
commit
1bfaa6f29c
  1. 22
      src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
  2. 33
      src/Avalonia.Base/Rendering/DirtyVisuals.cs
  3. 3
      src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs
  4. 9
      src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs
  5. 5
      src/iOS/Avalonia.iOS/AvaloniaView.cs
  6. 7
      src/iOS/Avalonia.iOS/Platform.cs

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

@ -29,6 +29,7 @@ public class CompositingRenderer : IRendererWithCompositor
private bool _queuedUpdate;
private Action _update;
private Action _invalidateScene;
private bool _updating;
internal CompositionTarget CompositionTarget;
@ -77,6 +78,8 @@ public class CompositingRenderer : IRendererWithCompositor
/// <inheritdoc/>
public void AddDirty(IVisual visual)
{
if (_updating)
throw new InvalidOperationException("Visual was invalidated during the render pass");
_dirty.Add((Visual)visual);
QueueUpdate();
}
@ -107,6 +110,8 @@ public class CompositingRenderer : IRendererWithCompositor
/// <inheritdoc/>
public void RecalculateChildren(IVisual visual)
{
if (_updating)
throw new InvalidOperationException("Visual was invalidated during the render pass");
_recalculateChildren.Add((Visual)visual);
QueueUpdate();
}
@ -191,7 +196,7 @@ public class CompositingRenderer : IRendererWithCompositor
private void InvalidateScene() =>
SceneInvalidated?.Invoke(this, new SceneInvalidatedEventArgs(_root, new Rect(_root.ClientSize)));
private void Update()
private void UpdateCore()
{
_queuedUpdate = false;
foreach (var visual in _dirty)
@ -240,6 +245,21 @@ public class CompositingRenderer : IRendererWithCompositor
CompositionTarget.Scaling = _root.RenderScaling;
Compositor.InvokeOnNextCommit(_invalidateScene);
}
private void Update()
{
if(_updating)
return;
_updating = true;
try
{
UpdateCore();
}
finally
{
_updating = false;
}
}
public void Resized(Size size)
{

33
src/Avalonia.Base/Rendering/DirtyVisuals.cs

@ -17,8 +17,7 @@ namespace Avalonia.Rendering
{
private SortedDictionary<int, List<IVisual>> _inner = new SortedDictionary<int, List<IVisual>>();
private Dictionary<IVisual, int> _index = new Dictionary<IVisual, int>();
private List<IVisual> _deferredChanges = new List<IVisual>();
private int _deferring;
private int _enumerating;
/// <summary>
/// Gets the number of dirty visuals.
@ -31,10 +30,9 @@ namespace Avalonia.Rendering
/// <param name="visual">The dirty visual.</param>
public void Add(IVisual visual)
{
if (_deferring > 0)
if (_enumerating > 0)
{
_deferredChanges.Add(visual);
return;
throw new InvalidOperationException("Visual was invalidated during a render pass");
}
var distance = visual.CalculateDistanceFromAncestor(visual.VisualRoot);
@ -65,7 +63,7 @@ namespace Avalonia.Rendering
/// </summary>
public void Clear()
{
if (_deferring > 0)
if (_enumerating > 0)
{
throw new InvalidOperationException("Cannot clear while enumerating");
}
@ -80,7 +78,7 @@ namespace Avalonia.Rendering
/// <returns>A collection of visuals.</returns>
public IEnumerator<IVisual> GetEnumerator()
{
BeginDefer();
_enumerating++;
try
{
foreach (var i in _inner)
@ -93,27 +91,10 @@ namespace Avalonia.Rendering
}
finally
{
EndDefer();
_enumerating--;
}
}
private void BeginDefer()
{
++_deferring;
}
private void EndDefer()
{
if (--_deferring > 0) return;
foreach (var visual in _deferredChanges)
{
Add(visual);
}
_deferredChanges.Clear();
}
/// <summary>
/// Gets the dirty visuals, in ascending order of distance to their root.
/// </summary>

3
src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs

@ -7,6 +7,7 @@ using Avalonia.LinuxFramebuffer.Input;
using Avalonia.LinuxFramebuffer.Output;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
namespace Avalonia.LinuxFramebuffer
{
@ -32,7 +33,7 @@ namespace Avalonia.LinuxFramebuffer
{
var factory = AvaloniaLocator.Current.GetService<IRendererFactory>();
var renderLoop = AvaloniaLocator.Current.GetService<IRenderLoop>();
return factory?.Create(root, renderLoop) ?? new DeferredRenderer(root, renderLoop);
return factory?.Create(root, renderLoop) ?? new CompositingRenderer(root, LinuxFramebufferPlatform.Compositor);
}
public void Dispose()

9
src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs

@ -15,6 +15,7 @@ using Avalonia.LinuxFramebuffer.Output;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
using Avalonia.Threading;
using JetBrains.Annotations;
@ -26,6 +27,10 @@ namespace Avalonia.LinuxFramebuffer
private static readonly Stopwatch St = Stopwatch.StartNew();
internal static uint Timestamp => (uint)St.ElapsedTicks;
public static InternalPlatformThreadingInterface Threading;
internal static Compositor Compositor { get; private set; }
LinuxFramebufferPlatform(IOutputBackend backend)
{
_fb = backend;
@ -48,6 +53,10 @@ namespace Avalonia.LinuxFramebuffer
.Bind<IKeyboardDevice>().ToConstant(new KeyboardDevice())
.Bind<IPlatformSettings>().ToSingleton<PlatformSettings>()
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>();
Compositor = new Compositor(
AvaloniaLocator.Current.GetRequiredService<IRenderLoop>(),
AvaloniaLocator.Current.GetService<IPlatformOpenGlInterface>());
}

5
src/iOS/Avalonia.iOS/AvaloniaView.cs

@ -10,6 +10,7 @@ using Avalonia.iOS.Storage;
using Avalonia.Platform;
using Avalonia.Platform.Storage;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
using CoreAnimation;
using Foundation;
using ObjCRuntime;
@ -65,8 +66,8 @@ namespace Avalonia.iOS
// No-op
}
public IRenderer CreateRenderer(IRenderRoot root) => new DeferredRenderer(root,
AvaloniaLocator.Current.GetService<IRenderLoop>());
public IRenderer CreateRenderer(IRenderRoot root) => new CompositingRenderer(root, Platform.Compositor);
public void Invalidate(Rect rect)
{

7
src/iOS/Avalonia.iOS/Platform.cs

@ -6,6 +6,7 @@ using Avalonia.Input.Platform;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
namespace Avalonia
{
@ -26,6 +27,8 @@ namespace Avalonia.iOS
{
public static EaglFeature GlFeature;
public static DisplayLinkTimer Timer;
internal static Compositor Compositor { get; private set; }
class PlatformSettings : IPlatformSettings
{
/// <inheritdoc cref="IPlatformSettings.TouchDoubleClickSize"/>
@ -57,6 +60,10 @@ namespace Avalonia.iOS
.Bind<IRenderTimer>().ToConstant(Timer)
.Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface())
.Bind<IKeyboardDevice>().ToConstant(keyboard);
Compositor = new Compositor(
AvaloniaLocator.Current.GetRequiredService<IRenderLoop>(),
AvaloniaLocator.Current.GetService<IPlatformOpenGlInterface>());
}

Loading…
Cancel
Save