EglGlPlatformSurface.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using System;
  2. using System.Threading;
  3. namespace Avalonia.OpenGL
  4. {
  5. public class EglGlPlatformSurface : IGlPlatformSurface
  6. {
  7. public interface IEglWindowGlPlatformSurfaceInfo
  8. {
  9. IntPtr Handle { get; }
  10. PixelSize Size { get; }
  11. double Scaling { get; }
  12. }
  13. private readonly EglDisplay _display;
  14. private readonly EglContext _context;
  15. private readonly IEglWindowGlPlatformSurfaceInfo _info;
  16. public EglGlPlatformSurface(EglDisplay display, EglContext context, IEglWindowGlPlatformSurfaceInfo info)
  17. {
  18. _display = display;
  19. _context = context;
  20. _info = info;
  21. }
  22. public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget()
  23. {
  24. var glSurface = _display.CreateWindowSurface(_info.Handle);
  25. return new RenderTarget(_display, _context, glSurface, _info);
  26. }
  27. class RenderTarget : IGlPlatformSurfaceRenderTargetWithCorruptionInfo
  28. {
  29. private readonly EglDisplay _display;
  30. private readonly EglContext _context;
  31. private readonly EglSurface _glSurface;
  32. private readonly IEglWindowGlPlatformSurfaceInfo _info;
  33. private PixelSize _initialSize;
  34. public RenderTarget(EglDisplay display, EglContext context,
  35. EglSurface glSurface, IEglWindowGlPlatformSurfaceInfo info)
  36. {
  37. _display = display;
  38. _context = context;
  39. _glSurface = glSurface;
  40. _info = info;
  41. _initialSize = info.Size;
  42. }
  43. public void Dispose() => _glSurface.Dispose();
  44. public bool IsCorrupted => _initialSize != _info.Size;
  45. public IGlPlatformSurfaceRenderingSession BeginDraw()
  46. {
  47. var l = _context.Lock();
  48. try
  49. {
  50. if (IsCorrupted)
  51. throw new RenderTargetCorruptedException();
  52. _context.MakeCurrent(_glSurface);
  53. _display.EglInterface.WaitClient();
  54. _display.EglInterface.WaitGL();
  55. _display.EglInterface.WaitNative();
  56. return new Session(_display, _context, _glSurface, _info, l);
  57. }
  58. catch
  59. {
  60. l.Dispose();
  61. throw;
  62. }
  63. }
  64. class Session : IGlPlatformSurfaceRenderingSession
  65. {
  66. private readonly EglContext _context;
  67. private readonly EglSurface _glSurface;
  68. private readonly IEglWindowGlPlatformSurfaceInfo _info;
  69. private readonly EglDisplay _display;
  70. private IDisposable _lock;
  71. public Session(EglDisplay display, EglContext context,
  72. EglSurface glSurface, IEglWindowGlPlatformSurfaceInfo info,
  73. IDisposable @lock)
  74. {
  75. _context = context;
  76. _display = display;
  77. _glSurface = glSurface;
  78. _info = info;
  79. _lock = @lock;
  80. }
  81. public void Dispose()
  82. {
  83. _context.Display.GlInterface.Flush();
  84. _display.EglInterface.WaitGL();
  85. _glSurface.SwapBuffers();
  86. _display.EglInterface.WaitClient();
  87. _display.EglInterface.WaitGL();
  88. _display.EglInterface.WaitNative();
  89. _context.Display.ClearContext();
  90. _lock.Dispose();
  91. }
  92. public IGlDisplay Display => _context.Display;
  93. public PixelSize Size => _info.Size;
  94. public double Scaling => _info.Scaling;
  95. public bool IsYFlipped { get; }
  96. }
  97. }
  98. }
  99. }