GLRenderer.cs 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using ARMeilleure.Translation;
  2. using ARMeilleure.Translation.PTC;
  3. using Gdk;
  4. using Gtk;
  5. using OpenTK.Graphics.OpenGL;
  6. using Ryujinx.Common;
  7. using Ryujinx.Common.Configuration;
  8. using Ryujinx.Configuration;
  9. using Ryujinx.Graphics.OpenGL;
  10. using Ryujinx.HLE.HOS.Services.Hid;
  11. using Ryujinx.Input;
  12. using Ryujinx.Input.HLE;
  13. using Ryujinx.Ui.Widgets;
  14. using SPB.Graphics;
  15. using SPB.Graphics.OpenGL;
  16. using SPB.Platform;
  17. using SPB.Platform.GLX;
  18. using SPB.Platform.WGL;
  19. using SPB.Windowing;
  20. using System;
  21. using System.Diagnostics;
  22. using System.Linq;
  23. using System.Runtime.InteropServices;
  24. using System.Threading;
  25. using Key = Ryujinx.Input.Key;
  26. namespace Ryujinx.Ui
  27. {
  28. using Switch = HLE.Switch;
  29. public class GlRenderer : RendererWidgetBase
  30. {
  31. private GraphicsDebugLevel _glLogLevel;
  32. private bool _initializedOpenGL;
  33. private OpenGLContextBase _openGLContext;
  34. private SwappableNativeWindowBase _nativeWindow;
  35. public GlRenderer(InputManager inputManager, GraphicsDebugLevel glLogLevel) : base(inputManager, glLogLevel)
  36. {
  37. _glLogLevel = glLogLevel;
  38. }
  39. protected override bool OnDrawn(Cairo.Context cr)
  40. {
  41. if (!_initializedOpenGL)
  42. {
  43. IntializeOpenGL();
  44. }
  45. return true;
  46. }
  47. private void IntializeOpenGL()
  48. {
  49. _nativeWindow = RetrieveNativeWindow();
  50. Window.EnsureNative();
  51. _openGLContext = PlatformHelper.CreateOpenGLContext(GetGraphicsMode(), 3, 3, _glLogLevel == GraphicsDebugLevel.None ? OpenGLContextFlags.Compat : OpenGLContextFlags.Compat | OpenGLContextFlags.Debug);
  52. _openGLContext.Initialize(_nativeWindow);
  53. _openGLContext.MakeCurrent(_nativeWindow);
  54. // Release the GL exclusivity that SPB gave us as we aren't going to use it in GTK Thread.
  55. _openGLContext.MakeCurrent(null);
  56. WaitEvent.Set();
  57. _initializedOpenGL = true;
  58. }
  59. private SwappableNativeWindowBase RetrieveNativeWindow()
  60. {
  61. if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
  62. {
  63. IntPtr windowHandle = gdk_win32_window_get_handle(Window.Handle);
  64. return new WGLWindow(new NativeHandle(windowHandle));
  65. }
  66. else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
  67. {
  68. IntPtr displayHandle = gdk_x11_display_get_xdisplay(Display.Handle);
  69. IntPtr windowHandle = gdk_x11_window_get_xid(Window.Handle);
  70. return new GLXWindow(new NativeHandle(displayHandle), new NativeHandle(windowHandle));
  71. }
  72. throw new NotImplementedException();
  73. }
  74. [DllImport("libgdk-3-0.dll")]
  75. private static extern IntPtr gdk_win32_window_get_handle(IntPtr d);
  76. [DllImport("libgdk-3.so.0")]
  77. private static extern IntPtr gdk_x11_display_get_xdisplay(IntPtr gdkDisplay);
  78. [DllImport("libgdk-3.so.0")]
  79. private static extern IntPtr gdk_x11_window_get_xid(IntPtr gdkWindow);
  80. private static FramebufferFormat GetGraphicsMode()
  81. {
  82. return Environment.OSVersion.Platform == PlatformID.Unix ? new FramebufferFormat(new ColorFormat(8, 8, 8, 0), 16, 0, ColorFormat.Zero, 0, 2, false) : FramebufferFormat.Default;
  83. }
  84. public override void InitializeRenderer()
  85. {
  86. // First take exclusivity on the OpenGL context.
  87. ((Renderer)Renderer).InitializeBackgroundContext(SPBOpenGLContext.CreateBackgroundContext(_openGLContext));
  88. _openGLContext.MakeCurrent(_nativeWindow);
  89. GL.ClearColor(0, 0, 0, 1.0f);
  90. GL.Clear(ClearBufferMask.ColorBufferBit);
  91. SwapBuffers();
  92. }
  93. public override void SwapBuffers()
  94. {
  95. _nativeWindow.SwapBuffers();
  96. }
  97. public override string GetGpuVendorName()
  98. {
  99. return ((Renderer)Renderer).GpuVendor;
  100. }
  101. protected override void Dispose(bool disposing)
  102. {
  103. // Try to bind the OpenGL context before calling the shutdown event
  104. try
  105. {
  106. _openGLContext?.MakeCurrent(_nativeWindow);
  107. }
  108. catch (Exception) { }
  109. Device.DisposeGpu();
  110. NpadManager.Dispose();
  111. // Unbind context and destroy everything
  112. try
  113. {
  114. _openGLContext?.MakeCurrent(null);
  115. }
  116. catch (Exception) { }
  117. _openGLContext.Dispose();
  118. }
  119. }
  120. }