DeferredFramebuffer.cs 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright (c) The Avalonia Project. All rights reserved.
  2. // Licensed under the MIT license. See licence.md file in the project root for full license information.
  3. using System;
  4. using System.Runtime.InteropServices;
  5. using Avalonia.Native.Interop;
  6. using Avalonia.Platform;
  7. using SharpGen.Runtime;
  8. namespace Avalonia.Native
  9. {
  10. public class DeferredFramebuffer : ILockedFramebuffer
  11. {
  12. private readonly Func<Action<IAvnWindowBase>, bool> _lockWindow;
  13. public DeferredFramebuffer(Func<Action<IAvnWindowBase>, bool> lockWindow,
  14. int width, int height, Vector dpi)
  15. {
  16. _lockWindow = lockWindow;
  17. Address = Marshal.AllocHGlobal(width * height * 4);
  18. Width = width;
  19. Height = height;
  20. RowBytes = width * 4;
  21. Dpi = dpi;
  22. Format = PixelFormat.Rgba8888;
  23. }
  24. public IntPtr Address { get; set; }
  25. public int Width { get; set; }
  26. public int Height { get; set; }
  27. public int RowBytes { get; set; }
  28. public Vector Dpi { get; set; }
  29. public PixelFormat Format { get; set; }
  30. class Disposer : CallbackBase
  31. {
  32. private IntPtr _ptr;
  33. public Disposer(IntPtr ptr)
  34. {
  35. _ptr = ptr;
  36. }
  37. protected override void Destroyed()
  38. {
  39. if(_ptr != IntPtr.Zero)
  40. {
  41. Marshal.FreeHGlobal(_ptr);
  42. _ptr = IntPtr.Zero;
  43. }
  44. }
  45. }
  46. public void Dispose()
  47. {
  48. if (Address == IntPtr.Zero)
  49. return;
  50. if (!_lockWindow(win =>
  51. {
  52. var fb = new AvnFramebuffer
  53. {
  54. Data = Address,
  55. Dpi = new AvnVector
  56. {
  57. X = Dpi.X,
  58. Y = Dpi.Y
  59. },
  60. Width = Width,
  61. Height = Height,
  62. PixelFormat = (AvnPixelFormat)Format,
  63. Stride = RowBytes
  64. };
  65. using (var d = new Disposer(Address))
  66. {
  67. win.ThreadSafeSetSwRenderedFrame(ref fb, d);
  68. }
  69. }))
  70. {
  71. Marshal.FreeHGlobal(Address);
  72. }
  73. Address = IntPtr.Zero;
  74. }
  75. }
  76. }