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() private bool? UpdateScene()
{ {
Dispatcher.UIThread.VerifyAccess(); Dispatcher.UIThread.VerifyAccess();
using var noPump = NonPumpingLockHelper.Use();
lock (_sceneLock) lock (_sceneLock)
{ {
if (_disposed) if (_disposed)

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

@ -2,6 +2,7 @@ using System;
using System.Runtime.ConstrainedExecution; using System.Runtime.ConstrainedExecution;
using System.Threading; using System.Threading;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.Utilities;
using Avalonia.Win32.Interop; using Avalonia.Win32.Interop;
namespace Avalonia.Win32 namespace Avalonia.Win32
@ -10,9 +11,9 @@ namespace Avalonia.Win32
{ {
private readonly SynchronizationContext _inner; private readonly SynchronizationContext _inner;
private NonPumpingSyncContext() private NonPumpingSyncContext(SynchronizationContext inner)
{ {
_inner = Current; _inner = inner;
SetWaitNotificationRequired(); SetWaitNotificationRequired();
SetSynchronizationContext(this); SetSynchronizationContext(this);
} }
@ -27,8 +28,25 @@ namespace Avalonia.Win32
millisecondsTimeout, false); 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.Platform;
using Avalonia.Rendering; using Avalonia.Rendering;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.Utilities;
using Avalonia.Win32.Input; using Avalonia.Win32.Input;
using Avalonia.Win32.Interop; using Avalonia.Win32.Interop;
using static Avalonia.Win32.Interop.UnmanagedMethods; using static Avalonia.Win32.Interop.UnmanagedMethods;
@ -110,6 +111,7 @@ namespace Avalonia.Win32
.Bind<IWindowingPlatform>().ToConstant(s_instance) .Bind<IWindowingPlatform>().ToConstant(s_instance)
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>() .Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>()
.Bind<IPlatformIconLoader>().ToConstant(s_instance) .Bind<IPlatformIconLoader>().ToConstant(s_instance)
.Bind<NonPumpingLockHelper.IHelperImpl>().ToConstant(new NonPumpingSyncContext.HelperImpl())
.Bind<IMountedVolumeInfoProvider>().ToConstant(new WindowsMountedVolumeInfoProvider()); .Bind<IMountedVolumeInfoProvider>().ToConstant(new WindowsMountedVolumeInfoProvider());
Win32GlManager.Initialize(); Win32GlManager.Initialize();

Loading…
Cancel
Save