Browse Source

Reduce flicker

pull/5012/head
Nikita Tsukanov 5 years ago
parent
commit
16fc224a0f
  1. 28
      src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs
  2. 18
      src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs
  3. 4
      src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs
  4. 46
      src/Windows/Avalonia.Win32/WinRT/winrt.idl
  5. 10
      src/tools/MicroComGenerator/CSharpGen.cs

28
src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositedWindow.cs

@ -1,5 +1,7 @@
using System;
using System.Numerics;
using System.Reactive.Disposables;
using System.Threading;
using Avalonia.MicroCom;
using Avalonia.OpenGL;
using Avalonia.OpenGL.Egl;
@ -10,6 +12,7 @@ namespace Avalonia.Win32.WinRT.Composition
public class WinUICompositedWindow : IDisposable
{
private EglContext _syncContext;
private readonly object _pumpLock;
private readonly IVisual _blurVisual;
private ICompositionTarget _compositionTarget;
private IVisual _contentVisual;
@ -17,14 +20,19 @@ namespace Avalonia.Win32.WinRT.Composition
private PixelSize _size;
private static Guid IID_ID3D11Texture2D = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c");
private ICompositor _compositor;
internal WinUICompositedWindow(EglContext syncContext,
ICompositor compositor,
object pumpLock,
ICompositionTarget compositionTarget,
ICompositionDrawingSurfaceInterop surfaceInterop,
IVisual contentVisual, IVisual blurVisual)
{
_compositor = compositor.CloneReference();
_syncContext = syncContext;
_pumpLock = pumpLock;
_blurVisual = blurVisual.CloneReference();
_compositionTarget = compositionTarget.CloneReference();
_contentVisual = contentVisual.CloneReference();
@ -36,7 +44,7 @@ namespace Avalonia.Win32.WinRT.Composition
{
using (_syncContext.EnsureLocked())
{
if (_size != size)
//if (_size != size)
{
_surfaceInterop.Resize(new UnmanagedMethods.POINT { X = size.Width, Y = size.Height });
_contentVisual.SetSize(new Vector2(size.Width, size.Height));
@ -70,10 +78,26 @@ namespace Avalonia.Win32.WinRT.Composition
_blurVisual.SetIsVisible(enable ? 1 : 0);
}
public IDisposable BeginTransaction()
{
Monitor.Enter(_pumpLock);
//var batch = _compositor.CreateScopedBatch(CompositionBatchTypes.Effect);
return Disposable.Create(() =>
{
Monitor.Exit(_pumpLock);
/*
batch?.End();
batch?.Dispose();
batch = null;*/
});
}
public void Dispose()
{
if (_syncContext == null)
{
_compositor.Dispose();
_blurVisual.Dispose();
_contentVisual.Dispose();
_surfaceInterop.Dispose();

18
src/Windows/Avalonia.Win32/WinRT/Composition/WinUICompositorConnection.cs

@ -25,10 +25,12 @@ namespace Avalonia.Win32.WinRT.Composition
private EglPlatformOpenGlInterface _gl;
private ICompositorDesktopInterop _compositorDesktopInterop;
private ICompositionBrush _blurBrush;
private object _pumpLock = new object();
public WinUICompositorConnection(EglPlatformOpenGlInterface gl)
public WinUICompositorConnection(EglPlatformOpenGlInterface gl, object pumpLock)
{
_gl = gl;
_pumpLock = pumpLock;
_syncContext = _gl.PrimaryEglContext;
_angle = (AngleWin32EglDisplay)_gl.Display;
_compositor = NativeWinRTMethods.CreateInstance<ICompositor>("Windows.UI.Composition.Compositor");
@ -46,6 +48,7 @@ namespace Avalonia.Win32.WinRT.Composition
static WinUICompositorConnection TryCreateCore(EglPlatformOpenGlInterface angle)
{
var tcs = new TaskCompletionSource<WinUICompositorConnection>();
var pumpLock = new object();
var th = new Thread(() =>
{
try
@ -56,11 +59,16 @@ namespace Avalonia.Win32.WinRT.Composition
dwSize = Marshal.SizeOf<NativeWinRTMethods.DispatcherQueueOptions>(),
threadType = NativeWinRTMethods.DISPATCHERQUEUE_THREAD_TYPE.DQTYPE_THREAD_CURRENT
});
tcs.SetResult(new WinUICompositorConnection(angle));
tcs.SetResult(new WinUICompositorConnection(angle, pumpLock));
while (true)
{
while (UnmanagedMethods.GetMessage(out var msg, IntPtr.Zero, 0, 0) != 0)
UnmanagedMethods.DispatchMessage(ref msg);
while (true)
{
if (UnmanagedMethods.GetMessage(out var msg, IntPtr.Zero, 0, 0) == 0)
return;
lock (pumpLock)
UnmanagedMethods.DispatchMessage(ref msg);
}
}
}
catch (Exception e)
@ -141,7 +149,7 @@ namespace Avalonia.Win32.WinRT.Composition
containerChildren.InsertAtTop(blur);
containerChildren.InsertAtTop(visual);
return new WinUICompositedWindow(_syncContext, target, surfaceInterop, visual, blur);
return new WinUICompositedWindow(_syncContext, _compositor, _pumpLock, target, surfaceInterop, visual, blur);
}

4
src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs

@ -60,6 +60,7 @@ namespace Avalonia.Win32.WinRT.Composition
var contextLock = _egl.PrimaryEglContext.EnsureCurrent();
IUnknown texture = null;
EglSurface surface = null;
IDisposable transaction = null;
var success = false;
try
{
@ -67,6 +68,7 @@ namespace Avalonia.Win32.WinRT.Composition
throw new ObjectDisposedException(GetType().FullName);
var size = _info.Size;
transaction = _window.Item.BeginTransaction();
_window.Item.ResizeIfNeeded(size);
texture = _window.Item.BeginDrawToTexture(out var offset);
@ -79,6 +81,7 @@ namespace Avalonia.Win32.WinRT.Composition
surface?.Dispose();
texture?.Dispose();
_window.Item.EndDraw();
transaction?.Dispose();
contextLock?.Dispose();
}, true);
success = true;
@ -90,6 +93,7 @@ namespace Avalonia.Win32.WinRT.Composition
{
surface?.Dispose();
texture?.Dispose();
transaction?.Dispose();
contextLock.Dispose();
}
}

46
src/Windows/Avalonia.Win32/WinRT/winrt.idl

@ -328,7 +328,7 @@ interface ICompositor : IInspectable
HRESULT CreatePropertySet([out] [retval] void** result);
HRESULT CreateQuaternionKeyFrameAnimation([out] [retval] void** result);
HRESULT CreateScalarKeyFrameAnimation([out] [retval] void** result);
HRESULT CreateScopedBatch([in] CompositionBatchTypes batchType, [out] [retval] void** result);
HRESULT CreateScopedBatch([in] CompositionBatchTypes batchType, [out] [retval] ICompositionScopedBatch** result);
HRESULT CreateSpriteVisual([out] [retval] ISpriteVisual** result);
HRESULT CreateSurfaceBrush([out] [retval] ICompositionSurfaceBrush** result);
HRESULT CreateSurfaceBrushWithSurface([in] ICompositionSurface* surface,
@ -456,11 +456,41 @@ interface ICompositionDrawingSurface : IInspectable
[propget] HRESULT GetSize([out] [retval] POINT* value);
}
enum CompositionBitmapInterpolationMode
{
NearestNeighbor,
Linear,
MagLinearMinLinearMipLinear,
MagLinearMinLinearMipNearest,
MagLinearMinNearestMipLinear,
MagLinearMinNearestMipNearest,
MagNearestMinLinearMipLinear,
MagNearestMinLinearMipNearest,
MagNearestMinNearestMipLinear,
MagNearestMinNearestMipNearest,
}
enum CompositionStretch
{
None,
Fill,
Uniform,
UniformToFill,
}
[uuid(AD016D79-1E4C-4C0D-9C29-83338C87C162)]
interface ICompositionSurfaceBrush : IInspectable
{
//TODO
[propget] HRESULT BitmapInterpolationMode([out] [retval] CompositionBitmapInterpolationMode* value);
[propput] HRESULT BitmapInterpolationMode([in] CompositionBitmapInterpolationMode value);
[propget] HRESULT HorizontalAlignmentRatio([out] [retval] FLOAT* value);
[propput] HRESULT HorizontalAlignmentRatio([in] FLOAT value);
[propget] HRESULT Stretch([out] [retval] CompositionStretch* value);
[propput] HRESULT Stretch([in] CompositionStretch value);
[propget] HRESULT Surface([out] [retval] ICompositionSurface** value);
[propput] HRESULT Surface([in] ICompositionSurface* value);
[propget] HRESULT VerticalAlignmentRatio([out] [retval] FLOAT* value);
[propput] HRESULT VerticalAlignmentRatio([in] FLOAT value);
}
[uuid(AB0D7608-30C0-40E9-B568-B60A6BD1FB46)]
@ -649,3 +679,15 @@ interface ICompositionColorBrush : IInspectable
[propget] HRESULT Color([out] [retval] Color* value);
[propput] HRESULT Color([in] Color value);
}
[uuid(0D00DAD0-FB07-46FD-8C72-6280D1A3D1DD)]
interface ICompositionScopedBatch : IInspectable
{
[propget] HRESULT IsActive([out] [retval] boolean* value);
[propget] HRESULT IsEnded([out] [retval] boolean* value);
HRESULT End();
HRESULT Resume();
HRESULT Suspend();
[eventadd] HRESULT AddCompleted([in] void* handler, [out] [retval] int* token);
[eventremove] HRESULT RemoveCompleted([in] int token);
}

10
src/tools/MicroComGenerator/CSharpGen.cs

@ -121,7 +121,8 @@ namespace MicroComGenerator
NamespaceDeclarationSyntax GenerateEnums(NamespaceDeclarationSyntax ns)
{
return ns.AddMembers(_idl.Enums.Select(e =>
EnumDeclaration(e.Name)
{
var dec = EnumDeclaration(e.Name)
.WithModifiers(TokenList(Token(_visibility)))
.WithMembers(SeparatedList(e.Select(m =>
{
@ -129,8 +130,11 @@ namespace MicroComGenerator
if (m.Value != null)
return member.WithEqualsValue(EqualsValueClause(ParseExpression(m.Value)));
return member;
})))
).ToArray());
})));
if (e.HasAttribute("flags"))
dec = dec.AddAttribute("System.Flags");
return dec;
}).ToArray());
}
NamespaceDeclarationSyntax GenerateStructs(NamespaceDeclarationSyntax ns)

Loading…
Cancel
Save