123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- 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;
- }
- }
- }
|