RendererHost.axaml.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using Avalonia;
  2. using Avalonia.Controls;
  3. using Avalonia.Markup.Xaml;
  4. using Ryujinx.Common.Configuration;
  5. using Silk.NET.Vulkan;
  6. using SPB.Graphics.OpenGL;
  7. using SPB.Windowing;
  8. using System;
  9. namespace Ryujinx.Ava.Ui.Controls
  10. {
  11. public partial class RendererHost : UserControl, IDisposable
  12. {
  13. private readonly GraphicsDebugLevel _graphicsDebugLevel;
  14. private EmbeddedWindow _currentWindow;
  15. public bool IsVulkan { get; private set; }
  16. public RendererHost(GraphicsDebugLevel graphicsDebugLevel)
  17. {
  18. _graphicsDebugLevel = graphicsDebugLevel;
  19. InitializeComponent();
  20. }
  21. public RendererHost()
  22. {
  23. InitializeComponent();
  24. }
  25. public void CreateOpenGL()
  26. {
  27. Dispose();
  28. _currentWindow = new OpenGLEmbeddedWindow(3, 3, _graphicsDebugLevel);
  29. Initialize();
  30. IsVulkan = false;
  31. }
  32. private void Initialize()
  33. {
  34. _currentWindow.WindowCreated += CurrentWindow_WindowCreated;
  35. _currentWindow.SizeChanged += CurrentWindow_SizeChanged;
  36. Content = _currentWindow;
  37. }
  38. public void CreateVulkan()
  39. {
  40. Dispose();
  41. _currentWindow = new VulkanEmbeddedWindow();
  42. Initialize();
  43. IsVulkan = true;
  44. }
  45. public OpenGLContextBase GetContext()
  46. {
  47. if (_currentWindow is OpenGLEmbeddedWindow openGlEmbeddedWindow)
  48. {
  49. return openGlEmbeddedWindow.Context;
  50. }
  51. return null;
  52. }
  53. protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
  54. {
  55. base.OnDetachedFromVisualTree(e);
  56. Dispose();
  57. }
  58. private void CurrentWindow_SizeChanged(object sender, Size e)
  59. {
  60. SizeChanged?.Invoke(sender, e);
  61. }
  62. private void CurrentWindow_WindowCreated(object sender, IntPtr e)
  63. {
  64. RendererInitialized?.Invoke(this, EventArgs.Empty);
  65. }
  66. public void MakeCurrent()
  67. {
  68. if (_currentWindow is OpenGLEmbeddedWindow openGlEmbeddedWindow)
  69. {
  70. openGlEmbeddedWindow.MakeCurrent();
  71. }
  72. }
  73. public void MakeCurrent(SwappableNativeWindowBase window)
  74. {
  75. if (_currentWindow is OpenGLEmbeddedWindow openGlEmbeddedWindow)
  76. {
  77. openGlEmbeddedWindow.MakeCurrent(window);
  78. }
  79. }
  80. public void SwapBuffers()
  81. {
  82. if (_currentWindow is OpenGLEmbeddedWindow openGlEmbeddedWindow)
  83. {
  84. openGlEmbeddedWindow.SwapBuffers();
  85. }
  86. }
  87. public event EventHandler<EventArgs> RendererInitialized;
  88. public event Action<object, Size> SizeChanged;
  89. public void Dispose()
  90. {
  91. if (_currentWindow != null)
  92. {
  93. _currentWindow.WindowCreated -= CurrentWindow_WindowCreated;
  94. _currentWindow.SizeChanged -= CurrentWindow_SizeChanged;
  95. }
  96. }
  97. public SurfaceKHR CreateVulkanSurface(Instance instance, Vk api)
  98. {
  99. return (_currentWindow is VulkanEmbeddedWindow vulkanEmbeddedWindow)
  100. ? vulkanEmbeddedWindow.CreateSurface(instance)
  101. : default;
  102. }
  103. }
  104. }