feat(graphics): implement ANativeWindow C-ABI exported functions
This commit is contained in:
parent
bac8afeb83
commit
a5f60dd899
3 changed files with 113 additions and 0 deletions
86
crates/molotov-core/src/graphics/c_api.rs
Normal file
86
crates/molotov-core/src/graphics/c_api.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#![allow(non_snake_case)]
|
||||
use super::surface::GraphicsSurface;
|
||||
use super::types::{ANativeWindow_Buffer, ARect, WindowFormat};
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ANativeWindow_acquire(window: *mut ()) {
|
||||
if let Some(s) = (window as *mut GraphicsSurface).as_ref() {
|
||||
s.acquire();
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ANativeWindow_release(window: *mut ()) {
|
||||
if !window.is_null() {
|
||||
let ptr = window as *mut GraphicsSurface;
|
||||
if (*ptr).release() == 0 {
|
||||
drop(Box::from_raw(ptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ANativeWindow_getWidth(window: *mut ()) -> i32 {
|
||||
if let Some(s) = (window as *mut GraphicsSurface).as_ref() {
|
||||
s.width()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ANativeWindow_getHeight(window: *mut ()) -> i32 {
|
||||
if let Some(s) = (window as *mut GraphicsSurface).as_ref() {
|
||||
s.height()
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ANativeWindow_getFormat(window: *mut ()) -> i32 {
|
||||
if let Some(s) = (window as *mut GraphicsSurface).as_ref() {
|
||||
s.format() as i32
|
||||
} else {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ANativeWindow_setBuffersGeometry(
|
||||
window: *mut (),
|
||||
width: i32,
|
||||
height: i32,
|
||||
format: i32,
|
||||
) -> i32 {
|
||||
if let Some(s) = (window as *mut GraphicsSurface).as_mut() {
|
||||
let fmt = WindowFormat::from_i32(format).unwrap_or(WindowFormat::Rgba8888);
|
||||
s.set_geometry(width, height, fmt);
|
||||
0
|
||||
} else {
|
||||
-libc::EINVAL
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ANativeWindow_lock(
|
||||
window: *mut (),
|
||||
outBuffer: *mut ANativeWindow_Buffer,
|
||||
inOutDirtyBounds: *mut ARect,
|
||||
) -> i32 {
|
||||
if let Some(s) = (window as *mut GraphicsSurface).as_mut() {
|
||||
s.lock(outBuffer, inOutDirtyBounds)
|
||||
} else {
|
||||
-libc::EINVAL
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn ANativeWindow_unlockAndPost(window: *mut ()) -> i32 {
|
||||
if let Some(s) = (window as *mut GraphicsSurface).as_mut() {
|
||||
s.unlock_and_post()
|
||||
} else {
|
||||
-libc::EINVAL
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
pub mod c_api;
|
||||
pub mod surface;
|
||||
pub mod types;
|
||||
pub mod window;
|
||||
|
|
|
|||
26
crates/molotov-core/tests/anativewindow_c_api_test.rs
Normal file
26
crates/molotov-core/tests/anativewindow_c_api_test.rs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
use molotov_core::graphics::c_api::*;
|
||||
use molotov_core::graphics::surface::GraphicsSurface;
|
||||
use molotov_core::graphics::types::{ANativeWindow_Buffer, WindowFormat};
|
||||
|
||||
#[test]
|
||||
fn test_anativewindow_c_api_lifecycle() {
|
||||
let surface = Box::new(GraphicsSurface::new(640, 480, WindowFormat::Rgba8888));
|
||||
let handle = Box::into_raw(surface) as *mut ();
|
||||
|
||||
unsafe {
|
||||
assert_eq!(ANativeWindow_getWidth(handle), 640);
|
||||
assert_eq!(ANativeWindow_getHeight(handle), 480);
|
||||
assert_eq!(ANativeWindow_getFormat(handle), 1);
|
||||
|
||||
ANativeWindow_setBuffersGeometry(handle, 800, 600, 1);
|
||||
assert_eq!(ANativeWindow_getWidth(handle), 800);
|
||||
assert_eq!(ANativeWindow_getHeight(handle), 600);
|
||||
|
||||
let mut buf = std::mem::MaybeUninit::<ANativeWindow_Buffer>::uninit();
|
||||
assert_eq!(ANativeWindow_lock(handle, buf.as_mut_ptr(), std::ptr::null_mut()), 0);
|
||||
assert_eq!(ANativeWindow_unlockAndPost(handle), 0);
|
||||
|
||||
ANativeWindow_release(handle);
|
||||
}
|
||||
}
|
||||
Reference in a new issue