A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

82 lines
2.3 KiB

using System;
using System.Runtime.InteropServices;
using Avalonia.Native.Interop;
using Avalonia.Platform;
namespace Avalonia.Native
{
internal unsafe class DeferredFramebuffer : ILockedFramebuffer
{
private readonly Func<Action<IAvnWindowBase>, bool> _lockWindow;
public DeferredFramebuffer(Func<Action<IAvnWindowBase>, bool> lockWindow,
int width, int height, Vector dpi)
{
_lockWindow = lockWindow;
Address = Marshal.AllocHGlobal(width * height * 4);
Size = new PixelSize(width, height);
RowBytes = width * 4;
Dpi = dpi;
Format = PixelFormat.Bgra8888;
}
public IntPtr Address { get; set; }
public PixelSize Size { get; set; }
public int Height { get; set; }
public int RowBytes { get; set; }
public Vector Dpi { get; set; }
public PixelFormat Format { get; set; }
class Disposer : CallbackBase
{
private IntPtr _ptr;
public Disposer(IntPtr ptr)
{
_ptr = ptr;
}
protected override void Destroyed()
{
if(_ptr != IntPtr.Zero)
{
Marshal.FreeHGlobal(_ptr);
_ptr = IntPtr.Zero;
}
}
}
public void Dispose()
{
if (Address == IntPtr.Zero)
return;
if (!_lockWindow(win =>
{
var fb = new AvnFramebuffer
{
Data = Address.ToPointer(),
Dpi = new AvnVector
{
X = Dpi.X,
Y = Dpi.Y
},
Width = Size.Width,
Height = Size.Height,
PixelFormat = (AvnPixelFormat)Format,
Stride = RowBytes
};
using (var d = new Disposer(Address))
{
win.ThreadSafeSetSwRenderedFrame(&fb, d);
}
}))
{
Marshal.FreeHGlobal(Address);
}
Address = IntPtr.Zero;
}
}
}