use core::ffi::c_void;
use jni::JNIEnv;
use jni::sys::jobject;
use raw_window_handle::{
AndroidDisplayHandle, AndroidNdkWindowHandle, DisplayHandle, HandleError, HasDisplayHandle,
HasWindowHandle, RawDisplayHandle, RawWindowHandle, WindowHandle,
};
use std::sync::{Arc, Mutex};
pub struct AppSurface {
pub native_window: Arc<NativeWindow>,
pub scale_factor: f32,
pub ctx: crate::IASDQContext,
pub callback_to_app: Option<extern "C" fn(arg: i32)>,
}
impl AppSurface {
pub fn new(env: *mut JNIEnv, surface: jobject) -> Self {
let native_window = Arc::new(NativeWindow::new(env, surface));
let backends = wgpu::Backends::VULKAN;
let instance = wgpu::Instance::new(&wgpu::InstanceDescriptor {
backends,
..Default::default()
});
let handle: Box<dyn wgpu::WindowHandle> = Box::new(native_window.clone());
let surface = instance
.create_surface(wgpu::SurfaceTarget::Window(handle))
.unwrap();
let ctx = futures_lite::future::block_on(crate::create_iasdq_context(
instance,
surface,
(native_window.get_width(), native_window.get_height()),
));
Self {
native_window,
scale_factor: 1.0,
ctx,
callback_to_app: None,
}
}
pub fn get_view_size(&self) -> (u32, u32) {
(
self.native_window.get_width(),
self.native_window.get_height(),
)
}
}
pub struct NativeWindow {
a_native_window: Arc<Mutex<*mut ndk_sys::ANativeWindow>>,
}
impl NativeWindow {
fn new(env: *mut JNIEnv, surface: jobject) -> Self {
let a_native_window = unsafe {
ndk_sys::ANativeWindow_fromSurface(env as *mut _, surface as *mut _)
};
Self {
a_native_window: Arc::new(Mutex::new(a_native_window)),
}
}
pub fn get_raw_window(&self) -> *mut ndk_sys::ANativeWindow {
let a_native_window = self.a_native_window.lock().unwrap();
*a_native_window
}
fn get_width(&self) -> u32 {
unsafe { ndk_sys::ANativeWindow_getWidth(*self.a_native_window.lock().unwrap()) as u32 }
}
fn get_height(&self) -> u32 {
unsafe { ndk_sys::ANativeWindow_getHeight(*self.a_native_window.lock().unwrap()) as u32 }
}
}
impl Drop for NativeWindow {
fn drop(&mut self) {
unsafe {
ndk_sys::ANativeWindow_release(*self.a_native_window.lock().unwrap());
}
}
}
impl HasWindowHandle for NativeWindow {
fn window_handle(&self) -> Result<WindowHandle<'_>, HandleError> {
unsafe {
let a_native_window = self.a_native_window.lock().unwrap();
let handle = AndroidNdkWindowHandle::new(
core::ptr::NonNull::new(*a_native_window as *mut _ as *mut c_void).unwrap(),
);
Ok(WindowHandle::borrow_raw(RawWindowHandle::AndroidNdk(
handle,
)))
}
}
}
impl HasDisplayHandle for NativeWindow {
fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
unsafe {
Ok(DisplayHandle::borrow_raw(RawDisplayHandle::Android(
AndroidDisplayHandle::new(),
)))
}
}
}
unsafe impl Send for NativeWindow {}
unsafe impl Sync for NativeWindow {}