Browse Source

Now using non-pumping mode for UpdateScene in deferred renderer, also improved the non-pumping sync context

pull/5149/head
Nikita Tsukanov 6 years ago
parent
commit
6e3bf60f28
  1. 14
      src/Avalonia.Base/Utilities/NonPumpingLockHelper.cs
  2. 1
      src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
  3. 26
      src/Windows/Avalonia.Win32/NonPumpingSyncContext.cs
  4. 2
      src/Windows/Avalonia.Win32/Win32Platform.cs

14
src/Avalonia.Base/Utilities/NonPumpingLockHelper.cs

@ -0,0 +1,14 @@
using System;
namespace Avalonia.Utilities
{
public class NonPumpingLockHelper
{
public interface IHelperImpl
{
IDisposable Use();
}
public static IDisposable Use() => AvaloniaLocator.Current.GetService<IHelperImpl>()?.Use();
}
}

1
src/Avalonia.Visuals/Rendering/DeferredRenderer.cs

@ -607,6 +607,7 @@ namespace Avalonia.Rendering
private bool? UpdateScene()
{
Dispatcher.UIThread.VerifyAccess();
using var noPump = NonPumpingLockHelper.Use();
lock (_sceneLock)
{
if (_disposed)

26
src/Windows/Avalonia.Win32/NonPumpingSyncContext.cs

@ -2,6 +2,7 @@ using System;
using System.Runtime.ConstrainedExecution;
using System.Threading;
using Avalonia.Threading;
using Avalonia.Utilities;
using Avalonia.Win32.Interop;
namespace Avalonia.Win32
@ -10,9 +11,9 @@ namespace Avalonia.Win32
{
private readonly SynchronizationContext _inner;
private NonPumpingSyncContext()
private NonPumpingSyncContext(SynchronizationContext inner)
{
_inner = Current;
_inner = inner;
SetWaitNotificationRequired();
SetSynchronizationContext(this);
}
@ -27,8 +28,25 @@ namespace Avalonia.Win32
millisecondsTimeout, false);
}
public void Dispose() => SynchronizationContext.SetSynchronizationContext(_inner);
public void Dispose() => SetSynchronizationContext(_inner);
public static IDisposable Use() => new NonPumpingSyncContext();
public static IDisposable Use()
{
var current = Current;
if (current == null)
{
if (Thread.CurrentThread.GetApartmentState() != ApartmentState.STA)
return null;
}
if (current is NonPumpingSyncContext)
return null;
return new NonPumpingSyncContext(current);
}
internal class HelperImpl : NonPumpingLockHelper.IHelperImpl
{
IDisposable NonPumpingLockHelper.IHelperImpl.Use() => NonPumpingSyncContext.Use();
}
}
}

2
src/Windows/Avalonia.Win32/Win32Platform.cs

@ -16,6 +16,7 @@ using Avalonia.OpenGL.Egl;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Threading;
using Avalonia.Utilities;
using Avalonia.Win32.Input;
using Avalonia.Win32.Interop;
using static Avalonia.Win32.Interop.UnmanagedMethods;
@ -110,6 +111,7 @@ namespace Avalonia.Win32
.Bind<IWindowingPlatform>().ToConstant(s_instance)
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>()
.Bind<IPlatformIconLoader>().ToConstant(s_instance)
.Bind<NonPumpingLockHelper.IHelperImpl>().ToConstant(new NonPumpingSyncContext.HelperImpl())
.Bind<IMountedVolumeInfoProvider>().ToConstant(new WindowsMountedVolumeInfoProvider());
Win32GlManager.Initialize();

Loading…
Cancel
Save