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.
 
 
 

107 lines
3.5 KiB

using System;
using System.Runtime.InteropServices;
using Android.Runtime;
using Android.Views;
using Avalonia.Platform;
namespace Avalonia.Android.Platform.SkiaPlatform
{
class AndroidFramebuffer : ILockedFramebuffer
{
private IntPtr _window;
public AndroidFramebuffer(Surface surface, double scaling)
{
if(surface == null)
throw new ArgumentNullException(nameof(surface));
_window = ANativeWindow_fromSurface(JNIEnv.Handle, surface.Handle);
if (_window == IntPtr.Zero)
throw new Exception("Unable to obtain ANativeWindow");
ANativeWindow_Buffer buffer;
var rc = new ARect()
{
right = ANativeWindow_getWidth(_window),
bottom = ANativeWindow_getHeight(_window)
};
Size = new PixelSize(rc.right, rc.bottom);
ANativeWindow_lock(_window, out buffer, ref rc);
Format = buffer.format == AndroidPixelFormat.WINDOW_FORMAT_RGB_565
? PixelFormat.Rgb565 : PixelFormat.Rgba8888;
RowBytes = buffer.stride * (Format == PixelFormat.Rgb565 ? 2 : 4);
Address = buffer.bits;
Dpi = new Vector(96, 96) * scaling;
}
public void Dispose()
{
ANativeWindow_unlockAndPost(_window);
ANativeWindow_release(_window);
_window = IntPtr.Zero;
Address = IntPtr.Zero;
}
public IntPtr Address { get; set; }
public PixelSize Size { get; }
public int RowBytes { get; }
public Vector Dpi { get; }
public PixelFormat Format { get; }
[DllImport("android")]
internal static extern IntPtr ANativeWindow_fromSurface(IntPtr jniEnv, IntPtr handle);
[DllImport("android")]
internal static extern int ANativeWindow_getWidth(IntPtr window);
[DllImport("android")]
internal static extern int ANativeWindow_getHeight(IntPtr window);
[DllImport("android")]
internal static extern void ANativeWindow_release(IntPtr window);
[DllImport("android")]
internal static extern void ANativeWindow_unlockAndPost(IntPtr window);
[DllImport("android")]
internal static extern int ANativeWindow_lock(IntPtr window, out ANativeWindow_Buffer outBuffer, ref ARect inOutDirtyBounds);
public enum AndroidPixelFormat
{
WINDOW_FORMAT_RGBA_8888 = 1,
WINDOW_FORMAT_RGBX_8888 = 2,
WINDOW_FORMAT_RGB_565 = 4,
}
internal struct ARect
{
public int left;
public int top;
public int right;
public int bottom;
}
internal struct ANativeWindow_Buffer
{
// The number of pixels that are show horizontally.
public int width;
// The number of pixels that are shown vertically.
public int height;
// The number of *pixels* that a line in the buffer takes in
// memory. This may be >= width.
public int stride;
// The format of the buffer. One of WINDOW_FORMAT_*
public AndroidPixelFormat format;
// The actual bits.
public IntPtr bits;
// Do not touch.
uint reserved1;
uint reserved2;
uint reserved3;
uint reserved4;
uint reserved5;
uint reserved6;
}
}
}