Browse Source

IPlatformGpu

pull/8105/head
Nikita Tsukanov 4 years ago
parent
commit
223a675433
  1. 16
      src/Avalonia.Base/Platform/IPlatformGpu.cs
  2. 4
      src/Avalonia.Base/Rendering/Composition/Compositor.cs
  3. 22
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs
  4. 6
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs
  5. 2
      src/Avalonia.Native/AvaloniaNativePlatformOpenGlInterface.cs
  6. 2
      src/Avalonia.OpenGL/Egl/EglPlatformOpenGlInterface.cs
  7. 3
      src/Avalonia.OpenGL/IGlContext.cs
  8. 6
      src/Avalonia.OpenGL/IPlatformOpenGlInterface.cs
  9. 2
      src/Avalonia.X11/Glx/GlxPlatformFeature.cs
  10. 6
      src/Avalonia.X11/X11Platform.cs
  11. 2
      src/Windows/Avalonia.Win32/OpenGl/WglPlatformOpenGlInterface.cs
  12. 61
      src/Windows/Avalonia.Win32/Win32GlManager.cs
  13. 6
      src/Windows/Avalonia.Win32/Win32Platform.cs
  14. 2
      src/iOS/Avalonia.iOS/EaglDisplay.cs

16
src/Avalonia.Base/Platform/IPlatformGpu.cs

@ -0,0 +1,16 @@
using System;
using Avalonia.Metadata;
namespace Avalonia.Platform;
[Unstable]
public interface IPlatformGpu
{
IPlatformGpuContext PrimaryContext { get; }
}
[Unstable]
public interface IPlatformGpuContext : IDisposable
{
IDisposable EnsureCurrent();
}

4
src/Avalonia.Base/Rendering/Composition/Compositor.cs

@ -24,9 +24,9 @@ namespace Avalonia.Rendering.Composition
internal ServerCompositor Server => _server;
internal CompositionEasingFunction DefaultEasing { get; }
public Compositor(IRenderLoop loop)
public Compositor(IRenderLoop loop, IPlatformGpu? gpu)
{
_server = new ServerCompositor(loop, _batchObjectPool, _batchMemoryPool);
_server = new ServerCompositor(loop, gpu, _batchObjectPool, _batchMemoryPool);
_implicitBatchCommit = ImplicitBatchCommit;
DefaultEasing = new CubicBezierEasingFunction(this,
new Vector2(0.25f, 0.1f), new Vector2(0.25f, 1f));

22
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs

@ -93,12 +93,6 @@ namespace Avalonia.Rendering.Composition.Server
_redrawRequested = false;
using (var targetContext = _renderTarget.CreateDrawingContext(null))
{
// This is a hack to safely dispose layer created by some other render target
// because we can only dispose layers with the corresponding GPU context being
// active on the current thread
while (Compositor.LayersToDispose.Count > 0)
Compositor.LayersToDispose.Dequeue().Dispose();
var layerSize = Size * Scaling;
if (layerSize != _layerSize || _layer == null)
{
@ -164,14 +158,20 @@ namespace Avalonia.Rendering.Composition.Server
public void Dispose()
{
if(_disposed)
return;
_disposed = true;
if (_layer != null)
using (_compositor.GpuContext?.EnsureCurrent())
{
Compositor.LayersToDispose.Enqueue(_layer);
_layer = null;
if (_layer != null)
{
_layer.Dispose();
_layer = null;
}
_renderTarget?.Dispose();
_renderTarget = null;
}
_renderTarget?.Dispose();
_renderTarget = null;
}
public void AddVisual(ServerCompositionVisual visual)

6
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs

@ -20,10 +20,12 @@ namespace Avalonia.Rendering.Composition.Server
private List<IAnimationInstance> _animationsToUpdate = new();
private BatchStreamObjectPool<object?> _batchObjectPool;
private BatchStreamMemoryPool _batchMemoryPool;
public Queue<IDrawingContextLayerImpl> LayersToDispose { get; } = new();
public IPlatformGpuContext? GpuContext { get; }
public ServerCompositor(IRenderLoop renderLoop, BatchStreamObjectPool<object?> batchObjectPool, BatchStreamMemoryPool batchMemoryPool)
public ServerCompositor(IRenderLoop renderLoop, IPlatformGpu? platformGpu,
BatchStreamObjectPool<object?> batchObjectPool, BatchStreamMemoryPool batchMemoryPool)
{
GpuContext = platformGpu?.PrimaryContext;
_renderLoop = renderLoop;
_batchObjectPool = batchObjectPool;
_batchMemoryPool = batchMemoryPool;

2
src/Avalonia.Native/AvaloniaNativePlatformOpenGlInterface.cs

@ -3,6 +3,7 @@ using Avalonia.OpenGL;
using Avalonia.Native.Interop;
using System.Drawing;
using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
using Avalonia.Threading;
namespace Avalonia.Native
@ -37,6 +38,7 @@ namespace Avalonia.Native
internal GlContext MainContext { get; }
public IGlContext PrimaryContext => MainContext;
IPlatformGpuContext IPlatformGpu.PrimaryContext => PrimaryContext;
public bool CanShareContexts => true;
public bool CanCreateContexts => true;

2
src/Avalonia.OpenGL/Egl/EglPlatformOpenGlInterface.cs

@ -1,5 +1,6 @@
using System;
using Avalonia.Logging;
using Avalonia.Platform;
using static Avalonia.OpenGL.Egl.EglConsts;
namespace Avalonia.OpenGL.Egl
@ -12,6 +13,7 @@ namespace Avalonia.OpenGL.Egl
public EglContext PrimaryEglContext { get; }
public IGlContext PrimaryContext => PrimaryEglContext;
IPlatformGpuContext IPlatformGpu.PrimaryContext => PrimaryContext;
public EglPlatformOpenGlInterface(EglDisplay display)
{

3
src/Avalonia.OpenGL/IGlContext.cs

@ -1,8 +1,9 @@
using System;
using Avalonia.Platform;
namespace Avalonia.OpenGL
{
public interface IGlContext : IDisposable
public interface IGlContext : IPlatformGpuContext
{
GlVersion Version { get; }
GlInterface GlInterface { get; }

6
src/Avalonia.OpenGL/IPlatformOpenGlInterface.cs

@ -1,8 +1,10 @@
using Avalonia.Platform;
namespace Avalonia.OpenGL
{
public interface IPlatformOpenGlInterface
public interface IPlatformOpenGlInterface : IPlatformGpu
{
IGlContext PrimaryContext { get; }
new IGlContext PrimaryContext { get; }
IGlContext CreateSharedContext();
bool CanShareContexts { get; }
bool CanCreateContexts { get; }

2
src/Avalonia.X11/Glx/GlxPlatformFeature.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using Avalonia.Logging;
using Avalonia.OpenGL;
using Avalonia.Platform;
namespace Avalonia.X11.Glx
{
@ -14,6 +15,7 @@ namespace Avalonia.X11.Glx
public IGlContext CreateSharedContext() => Display.CreateContext(PrimaryContext);
public GlxContext DeferredContext { get; private set; }
public IGlContext PrimaryContext => DeferredContext;
IPlatformGpuContext IPlatformGpu.PrimaryContext => PrimaryContext;
public static bool TryInitialize(X11Info x11, IList<GlVersion> glProfiles)
{

6
src/Avalonia.X11/X11Platform.cs

@ -103,8 +103,12 @@ namespace Avalonia.X11
GlxPlatformOpenGlInterface.TryInitialize(Info, Options.GlProfiles);
}
var gl = AvaloniaLocator.Current.GetService<IPlatformOpenGlInterface>();
if (gl != null)
AvaloniaLocator.CurrentMutable.Bind<IPlatformGpu>().ToConstant(gl);
if (options.UseCompositor)
Compositor = new Compositor(AvaloniaLocator.Current.GetService<IRenderLoop>()!);
Compositor = new Compositor(AvaloniaLocator.Current.GetService<IRenderLoop>()!, gl);
}

2
src/Windows/Avalonia.Win32/OpenGl/WglPlatformOpenGlInterface.cs

@ -2,12 +2,14 @@ using System;
using System.Linq;
using Avalonia.Logging;
using Avalonia.OpenGL;
using Avalonia.Platform;
namespace Avalonia.Win32.OpenGl
{
class WglPlatformOpenGlInterface : IPlatformOpenGlInterface
{
public WglContext PrimaryContext { get; }
IPlatformGpuContext IPlatformGpu.PrimaryContext => PrimaryContext;
IGlContext IPlatformOpenGlInterface.PrimaryContext => PrimaryContext;
public IGlContext CreateSharedContext() => WglDisplay.CreateContext(new[] { PrimaryContext.Version }, PrimaryContext);

61
src/Windows/Avalonia.Win32/Win32GlManager.cs

@ -1,6 +1,7 @@
using Avalonia.OpenGL;
using Avalonia.OpenGL.Angle;
using Avalonia.OpenGL.Egl;
using Avalonia.Platform;
using Avalonia.Win32.OpenGl;
using Avalonia.Win32.WinRT.Composition;
@ -9,45 +10,53 @@ namespace Avalonia.Win32
static class Win32GlManager
{
public static void Initialize()
public static IPlatformOpenGlInterface Initialize()
{
AvaloniaLocator.CurrentMutable.Bind<IPlatformOpenGlInterface>().ToLazy<IPlatformOpenGlInterface>(() =>
var gl = InitializeCore();
AvaloniaLocator.CurrentMutable.Bind<IPlatformOpenGlInterface>().ToConstant(gl);
AvaloniaLocator.CurrentMutable.Bind<IPlatformGpu>().ToConstant(gl);
return gl;
}
static IPlatformOpenGlInterface InitializeCore()
{
var opts = AvaloniaLocator.Current.GetService<Win32PlatformOptions>() ?? new Win32PlatformOptions();
if (opts.UseWgl)
{
var opts = AvaloniaLocator.Current.GetService<Win32PlatformOptions>() ?? new Win32PlatformOptions();
if (opts.UseWgl)
{
var wgl = WglPlatformOpenGlInterface.TryCreate();
return wgl;
}
var wgl = WglPlatformOpenGlInterface.TryCreate();
return wgl;
}
if (opts.AllowEglInitialization ?? Win32Platform.WindowsVersion > PlatformConstants.Windows7)
{
var egl = EglPlatformOpenGlInterface.TryCreate(() => new AngleWin32EglDisplay());
if (opts.AllowEglInitialization ?? Win32Platform.WindowsVersion > PlatformConstants.Windows7)
{
var egl = EglPlatformOpenGlInterface.TryCreate(() => new AngleWin32EglDisplay());
if (egl != null)
if (egl != null)
{
if (opts.EglRendererBlacklist != null)
{
if (opts.EglRendererBlacklist != null)
foreach (var item in opts.EglRendererBlacklist)
{
foreach (var item in opts.EglRendererBlacklist)
if (egl.PrimaryEglContext.GlInterface.Renderer.Contains(item))
{
if (egl.PrimaryEglContext.GlInterface.Renderer.Contains(item))
{
return null;
}
return null;
}
}
if (opts.UseWindowsUIComposition)
{
WinUICompositorConnection.TryCreateAndRegister(egl, opts.CompositionBackdropCornerRadius);
}
}
return egl;
if (opts.UseWindowsUIComposition)
{
WinUICompositorConnection.TryCreateAndRegister(egl, opts.CompositionBackdropCornerRadius);
}
}
return null;
});
return egl;
}
return null;
}
}
}

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

@ -180,15 +180,15 @@ namespace Avalonia.Win32
.Bind<IMountedVolumeInfoProvider>().ToConstant(new WindowsMountedVolumeInfoProvider())
.Bind<IPlatformLifetimeEventsImpl>().ToConstant(s_instance);
Win32GlManager.Initialize();
var gl = Win32GlManager.Initialize();
_uiThread = Thread.CurrentThread;
if (OleContext.Current != null)
AvaloniaLocator.CurrentMutable.Bind<IPlatformDragSource>().ToSingleton<DragSource>();
if (Options.UseCompositor)
Compositor = new Compositor(AvaloniaLocator.Current.GetRequiredService<IRenderLoop>());
Compositor = new Compositor(AvaloniaLocator.Current.GetRequiredService<IRenderLoop>(), gl);
}
public bool HasMessages()

2
src/iOS/Avalonia.iOS/EaglDisplay.cs

@ -1,6 +1,7 @@
using System;
using System.Reactive.Disposables;
using Avalonia.OpenGL;
using Avalonia.Platform;
using OpenGLES;
namespace Avalonia.iOS
@ -9,6 +10,7 @@ namespace Avalonia.iOS
{
public IGlContext PrimaryContext => Context;
public IGlContext CreateSharedContext() => throw new NotSupportedException();
IPlatformGpuContext IPlatformGpu.PrimaryContext => PrimaryContext;
public bool CanShareContexts => false;
public bool CanCreateContexts => false;
public IGlContext CreateContext() => throw new System.NotSupportedException();

Loading…
Cancel
Save