csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
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.
70 lines
2.3 KiB
70 lines
2.3 KiB
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using Avalonia.Platform;
|
|
|
|
namespace Avalonia.LinuxFramebuffer.Output
|
|
{
|
|
internal unsafe class FbDevBackBuffer : IDisposable
|
|
{
|
|
private readonly int _fb;
|
|
private readonly fb_fix_screeninfo _fixedInfo;
|
|
private readonly fb_var_screeninfo _varInfo;
|
|
private readonly IntPtr _targetAddress;
|
|
private readonly object _lock = new object();
|
|
|
|
public FbDevBackBuffer(int fb, fb_fix_screeninfo fixedInfo, fb_var_screeninfo varInfo, IntPtr targetAddress)
|
|
{
|
|
_fb = fb;
|
|
_fixedInfo = fixedInfo;
|
|
_varInfo = varInfo;
|
|
_targetAddress = targetAddress;
|
|
Address = Marshal.AllocHGlobal(RowBytes * Size.Height);
|
|
}
|
|
|
|
|
|
public void Dispose()
|
|
{
|
|
if (Address != IntPtr.Zero)
|
|
{
|
|
Marshal.FreeHGlobal(Address);
|
|
Address = IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
public ILockedFramebuffer Lock(Vector dpi)
|
|
{
|
|
Monitor.Enter(_lock);
|
|
try
|
|
{
|
|
return new LockedFramebuffer(Address,
|
|
new PixelSize((int)_varInfo.xres, (int)_varInfo.yres),
|
|
(int)_fixedInfo.line_length, dpi,
|
|
_varInfo.bits_per_pixel == 16 ? PixelFormat.Rgb565
|
|
: _varInfo.blue.offset == 16 ? PixelFormat.Rgba8888
|
|
: PixelFormat.Bgra8888,
|
|
() =>
|
|
{
|
|
try
|
|
{
|
|
NativeUnsafeMethods.ioctl(_fb, FbIoCtl.FBIO_WAITFORVSYNC, null);
|
|
NativeUnsafeMethods.memcpy(_targetAddress, Address, new IntPtr(RowBytes * Size.Height));
|
|
}
|
|
finally
|
|
{
|
|
Monitor.Exit(_lock);
|
|
}
|
|
});
|
|
}
|
|
catch
|
|
{
|
|
Monitor.Exit(_lock);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public IntPtr Address { get; private set; }
|
|
public PixelSize Size => new PixelSize((int)_varInfo.xres, (int) _varInfo.yres);
|
|
public int RowBytes => (int) _fixedInfo.line_length;
|
|
}
|
|
}
|
|
|