RendererHost.axaml.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using Avalonia;
  2. using Avalonia.Controls;
  3. using Gommon;
  4. using Ryujinx.Common.Configuration;
  5. using Ryujinx.Common.Logging;
  6. using Ryujinx.UI.Common.Configuration;
  7. using System;
  8. using System.Runtime.InteropServices;
  9. namespace Ryujinx.Ava.UI.Renderer
  10. {
  11. public partial class RendererHost : UserControl, IDisposable
  12. {
  13. public readonly EmbeddedWindow EmbeddedWindow;
  14. public event EventHandler<EventArgs> WindowCreated;
  15. public event Action<object, Size> BoundsChanged;
  16. public RendererHost()
  17. {
  18. InitializeComponent();
  19. EmbeddedWindow = ConfigurationState.Instance.Graphics.GraphicsBackend.Value switch
  20. {
  21. GraphicsBackend.OpenGl => new EmbeddedWindowOpenGL(),
  22. GraphicsBackend.Metal => new EmbeddedWindowMetal(),
  23. GraphicsBackend.Vulkan or GraphicsBackend.Auto => new EmbeddedWindowVulkan(),
  24. _ => throw new NotSupportedException()
  25. };
  26. Initialize();
  27. }
  28. public static readonly string[] KnownGreatMetalTitles =
  29. [
  30. "01006A800016E000", // Smash Ultimate
  31. "0100000000010000", // Super Mario Odyessy
  32. "01008C0016544000", // Sea of Stars
  33. "01005CA01580E000", // Persona 5
  34. "010028600EBDA000", // Mario 3D World
  35. ];
  36. public GraphicsBackend Backend =>
  37. EmbeddedWindow switch
  38. {
  39. EmbeddedWindowVulkan => GraphicsBackend.Vulkan,
  40. EmbeddedWindowOpenGL => GraphicsBackend.OpenGl,
  41. EmbeddedWindowMetal => GraphicsBackend.Metal,
  42. _ => throw new NotImplementedException()
  43. };
  44. public RendererHost(string titleId)
  45. {
  46. InitializeComponent();
  47. switch (ConfigurationState.Instance.Graphics.GraphicsBackend.Value)
  48. {
  49. case GraphicsBackend.Auto:
  50. EmbeddedWindow =
  51. OperatingSystem.IsMacOS() &&
  52. RuntimeInformation.ProcessArchitecture == Architecture.Arm64 &&
  53. KnownGreatMetalTitles.ContainsIgnoreCase(titleId)
  54. ? new EmbeddedWindowMetal()
  55. : new EmbeddedWindowVulkan();
  56. string backendText = EmbeddedWindow is EmbeddedWindowVulkan ? "Vulkan" : "Metal";
  57. Logger.Info?.PrintMsg(LogClass.Gpu, $"Auto: Using {backendText}");
  58. break;
  59. case GraphicsBackend.OpenGl:
  60. EmbeddedWindow = new EmbeddedWindowOpenGL();
  61. break;
  62. case GraphicsBackend.Metal:
  63. EmbeddedWindow = new EmbeddedWindowMetal();
  64. break;
  65. case GraphicsBackend.Vulkan:
  66. EmbeddedWindow = new EmbeddedWindowVulkan();
  67. break;
  68. }
  69. Initialize();
  70. }
  71. private void Initialize()
  72. {
  73. EmbeddedWindow.WindowCreated += CurrentWindow_WindowCreated;
  74. EmbeddedWindow.BoundsChanged += CurrentWindow_BoundsChanged;
  75. Content = EmbeddedWindow;
  76. }
  77. public void Dispose()
  78. {
  79. if (EmbeddedWindow != null)
  80. {
  81. EmbeddedWindow.WindowCreated -= CurrentWindow_WindowCreated;
  82. EmbeddedWindow.BoundsChanged -= CurrentWindow_BoundsChanged;
  83. }
  84. GC.SuppressFinalize(this);
  85. }
  86. protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
  87. {
  88. base.OnDetachedFromVisualTree(e);
  89. Dispose();
  90. }
  91. private void CurrentWindow_BoundsChanged(object sender, Size e)
  92. {
  93. BoundsChanged?.Invoke(sender, e);
  94. }
  95. private void CurrentWindow_WindowCreated(object sender, nint e)
  96. {
  97. WindowCreated?.Invoke(this, EventArgs.Empty);
  98. }
  99. }
  100. }