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.
107 lines
3.5 KiB
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;
|
|
}
|
|
}
|
|
}
|
|
|