Browse Source

Replace UseGpu and UseEgl parameters with consistent RenderingMode enum on every platform

pull/11898/head
Max Katz 3 years ago
parent
commit
6a50fc5a92
  1. 71
      src/Android/Avalonia.Android/AndroidPlatform.cs
  2. 7
      src/Avalonia.OpenGL/Egl/EglPlatformGraphics.cs
  3. 12
      src/Avalonia.X11/Glx/GlxPlatformFeature.cs
  4. 82
      src/Avalonia.X11/X11Platform.cs
  5. 2
      src/Windows/Avalonia.Win32/Win32PlatformOptions.cs

71
src/Android/Avalonia.Android/AndroidPlatform.cs

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia.Controls;
using Avalonia.Android;
using Avalonia.Android.Platform;
@ -22,6 +24,36 @@ namespace Avalonia
.UseSkia();
}
}
public enum AndroidRenderingMode
{
/// <summary>
/// Avalonia is rendered into a framebuffer.
/// </summary>
Software = 1,
/// <summary>
/// Enables android EGL rendering.
/// </summary>
Egl = 2
}
public sealed class AndroidPlatformOptions
{
/// <summary>
/// Gets or sets Avalonia rendering modes with fallbacks.
/// The first element in the array has the highest priority.
/// The default value is: <see cref="AndroidRenderingMode.Egl"/>, <see cref="AndroidRenderingMode.Software"/>.
/// </summary>
/// <remarks>
/// If application should work on as wide range of devices as possible, at least add <see cref="AndroidRenderingMode.Software"/> as a fallback value.
/// </remarks>
/// <exception cref="System.InvalidOperationException">Thrown if no values were matched.</exception>
public IReadOnlyList<AndroidRenderingMode> RenderingMode { get; set; } = new[]
{
AndroidRenderingMode.Egl, AndroidRenderingMode.Software
};
}
}
namespace Avalonia.Android
@ -47,18 +79,39 @@ namespace Avalonia.Android
.Bind<IRenderTimer>().ToConstant(new ChoreographerTimer())
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>();
if (Options.UseGpu)
var graphics = InitializeGraphics(Options);
if (graphics is not null)
{
EglPlatformGraphics.TryInitialize();
AvaloniaLocator.CurrentMutable.Bind<IPlatformGraphics>().ToConstant(graphics);
}
Compositor = new Compositor(AvaloniaLocator.Current.GetService<IPlatformGraphics>());
Compositor = new Compositor(graphics);
}
}
private static IPlatformGraphics InitializeGraphics(AndroidPlatformOptions opts)
{
if (opts.RenderingMode is null || !opts.RenderingMode.Any())
{
throw new InvalidOperationException($"{nameof(AndroidPlatformOptions)}.{nameof(AndroidPlatformOptions.RenderingMode)} must not be empty or null");
}
public sealed class AndroidPlatformOptions
{
public bool UseDeferredRendering { get; set; } = false;
public bool UseGpu { get; set; } = true;
foreach (var renderingMode in opts.RenderingMode)
{
if (renderingMode == AndroidRenderingMode.Software)
{
return null;
}
if (renderingMode == AndroidRenderingMode.Egl)
{
if (EglPlatformGraphics.TryCreate() is { } egl)
{
return egl;
}
}
}
throw new InvalidOperationException($"{nameof(AndroidPlatformOptions)}.{nameof(AndroidPlatformOptions.RenderingMode)} has a value of \"{string.Join(", ", opts.RenderingMode)}\", but no options were applied.");
}
}
}

7
src/Avalonia.OpenGL/Egl/EglPlatformGraphics.cs

@ -16,13 +16,6 @@ namespace Avalonia.OpenGL.Egl
_display = display;
}
public static void TryInitialize()
{
var feature = TryCreate();
if (feature != null)
AvaloniaLocator.CurrentMutable.Bind<IPlatformGraphics>().ToConstant(feature);
}
public static EglPlatformGraphics? TryCreate() => TryCreate(() => new EglDisplay(new EglDisplayCreationOptions
{
Egl = new EglInterface(),

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

@ -15,18 +15,6 @@ namespace Avalonia.X11.Glx
IPlatformGraphicsContext IPlatformGraphics.CreateContext() => Display.CreateContext();
public IPlatformGraphicsContext GetSharedContext() => throw new NotSupportedException();
public static bool TryInitialize(X11Info x11, IList<GlVersion> glProfiles)
{
var feature = TryCreate(x11, glProfiles);
if (feature != null)
{
AvaloniaLocator.CurrentMutable.Bind<IPlatformGraphics>().ToConstant(feature);
return true;
}
return false;
}
public static GlxPlatformGraphics TryCreate(X11Info x11, IList<GlVersion> glProfiles)
{

82
src/Avalonia.X11/X11Platform.cs

@ -93,17 +93,13 @@ namespace Avalonia.X11
XI2 = xi2;
}
if (options.UseGpu)
var graphics = InitializeGraphics(options, Info);
if (graphics is not null)
{
if (options.UseEGL)
EglPlatformGraphics.TryInitialize();
else
GlxPlatformGraphics.TryInitialize(Info, Options.GlProfiles);
AvaloniaLocator.CurrentMutable.Bind<IPlatformGraphics>().ToConstant(graphics);
}
var gl = AvaloniaLocator.Current.GetService<IPlatformGraphics>();
Compositor = new Compositor(gl);
Compositor = new Compositor(graphics);
}
public IntPtr DeferredDisplay { get; set; }
@ -185,25 +181,81 @@ namespace Avalonia.X11
return false;
}
private static IPlatformGraphics InitializeGraphics(X11PlatformOptions opts, X11Info info)
{
if (opts.RenderingMode is null || !opts.RenderingMode.Any())
{
throw new InvalidOperationException($"{nameof(X11PlatformOptions)}.{nameof(X11PlatformOptions.RenderingMode)} must not be empty or null");
}
foreach (var renderingMode in opts.RenderingMode)
{
if (renderingMode == X11RenderingMode.Software)
{
return null;
}
if (renderingMode == X11RenderingMode.Glx)
{
if (GlxPlatformGraphics.TryCreate(info, opts.GlProfiles) is { } glx)
{
return glx;
}
}
if (renderingMode == X11RenderingMode.Egl)
{
if (EglPlatformGraphics.TryCreate() is { } egl)
{
return egl;
}
}
}
throw new InvalidOperationException($"{nameof(X11PlatformOptions)}.{nameof(X11PlatformOptions.RenderingMode)} has a value of \"{string.Join(", ", opts.RenderingMode)}\", but no options were applied.");
}
}
}
namespace Avalonia
{
public enum X11RenderingMode
{
/// <summary>
/// Avalonia is rendered into a framebuffer.
/// </summary>
Software = 1,
/// <summary>
/// Enables Glx rendering.
/// </summary>
Glx = 2,
/// <summary>
/// Enables native Linux EGL rendering.
/// </summary>
Egl = 3
}
/// <summary>
/// Platform-specific options which apply to Linux.
/// </summary>
public class X11PlatformOptions
{
/// <summary>
/// Enables native Linux EGL when set to true. The default value is false.
/// Gets or sets Avalonia rendering modes with fallbacks.
/// The first element in the array has the highest priority.
/// The default value is: <see cref="X11RenderingMode.Glx"/>, <see cref="X11RenderingMode.Software"/>.
/// </summary>
public bool UseEGL { get; set; }
/// <summary>
/// Determines whether to use GPU for rendering in your project. The default value is true.
/// </summary>
public bool UseGpu { get; set; } = true;
/// <remarks>
/// If application should work on as wide range of devices as possible, at least add <see cref="X11RenderingMode.Software"/> as a fallback value.
/// </remarks>
/// <exception cref="System.InvalidOperationException">Thrown if no values were matched.</exception>
public IReadOnlyList<X11RenderingMode> RenderingMode { get; set; } = new[]
{
X11RenderingMode.Glx, X11RenderingMode.Software
};
/// <summary>
/// Embeds popups to the window when set to true. The default value is false.

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

@ -19,7 +19,7 @@ public enum Win32RenderingMode
/// <summary>
/// Avalonia would try to use native Widows OpenGL with GPU rendering.
/// </summary>
Wgl
Wgl = 3
}
public enum Win32CompositionMode

Loading…
Cancel
Save