AngleWin32EglDisplay.cs 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Runtime.InteropServices;
  4. using static Avalonia.OpenGL.EglConsts;
  5. namespace Avalonia.OpenGL.Angle
  6. {
  7. public class AngleWin32EglDisplay : EglDisplay
  8. {
  9. struct AngleInfo
  10. {
  11. public IntPtr Display { get; set; }
  12. public AngleOptions.PlatformApi PlatformApi { get; set; }
  13. }
  14. static AngleInfo CreateAngleDisplay(EglInterface _egl)
  15. {
  16. if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
  17. throw new PlatformNotSupportedException();
  18. var display = IntPtr.Zero;
  19. AngleOptions.PlatformApi angleApi = default;
  20. {
  21. if (_egl.GetPlatformDisplayEXT == null)
  22. throw new OpenGlException("eglGetPlatformDisplayEXT is not supported by libegl.dll");
  23. var allowedApis = AvaloniaLocator.Current.GetService<AngleOptions>()?.AllowedPlatformApis
  24. ?? new [] { AngleOptions.PlatformApi.DirectX11, AngleOptions.PlatformApi.DirectX9 };
  25. foreach (var platformApi in allowedApis)
  26. {
  27. int dapi;
  28. if (platformApi == AngleOptions.PlatformApi.DirectX9)
  29. dapi = EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE;
  30. else if (platformApi == AngleOptions.PlatformApi.DirectX11)
  31. dapi = EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE;
  32. else
  33. continue;
  34. display = _egl.GetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, IntPtr.Zero,
  35. new[] { EGL_PLATFORM_ANGLE_TYPE_ANGLE, dapi, EGL_NONE });
  36. if (display != IntPtr.Zero)
  37. {
  38. angleApi = platformApi;
  39. break;
  40. }
  41. }
  42. if (display == IntPtr.Zero)
  43. throw new OpenGlException("Unable to create ANGLE display");
  44. return new AngleInfo { Display = display, PlatformApi = angleApi };
  45. }
  46. }
  47. private AngleWin32EglDisplay(EglInterface egl, AngleInfo info) : base(egl, info.Display)
  48. {
  49. PlatformApi = info.PlatformApi;
  50. }
  51. public AngleWin32EglDisplay(EglInterface egl) : this(egl, CreateAngleDisplay(egl))
  52. {
  53. }
  54. public AngleWin32EglDisplay() : this(new AngleEglInterface())
  55. {
  56. }
  57. public AngleOptions.PlatformApi PlatformApi { get; }
  58. public IntPtr GetDirect3DDevice()
  59. {
  60. if (!EglInterface.QueryDisplayAttribExt(Handle, EglConsts.EGL_DEVICE_EXT, out var eglDevice))
  61. throw new OpenGlException("Unable to get EGL_DEVICE_EXT");
  62. if (!EglInterface.QueryDeviceAttribExt(eglDevice, PlatformApi == AngleOptions.PlatformApi.DirectX9 ? EGL_D3D9_DEVICE_ANGLE : EGL_D3D11_DEVICE_ANGLE, out var d3dDeviceHandle))
  63. throw new OpenGlException("Unable to get EGL_D3D9_DEVICE_ANGLE");
  64. return d3dDeviceHandle;
  65. }
  66. public EglSurface WrapDirect3D11Texture(IntPtr handle)
  67. {
  68. if (PlatformApi != AngleOptions.PlatformApi.DirectX11)
  69. throw new InvalidOperationException("Current platform API is " + PlatformApi);
  70. return CreatePBufferFromClientBuffer(EGL_D3D_TEXTURE_ANGLE, handle, new[] { EGL_NONE, EGL_NONE });
  71. }
  72. }
  73. }