diff --git a/ndk/src/hardware_buffer.rs b/ndk/src/hardware_buffer.rs index 9d52ee4a..c68aa69a 100644 --- a/ndk/src/hardware_buffer.rs +++ b/ndk/src/hardware_buffer.rs @@ -1,6 +1,7 @@ #![cfg(feature = "hardware_buffer")] + +pub use super::hardware_buffer_format::HardwareBufferFormat; use jni_sys::{jobject, JNIEnv}; -use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::{ convert::TryInto, mem::MaybeUninit, ops::Deref, os::raw::c_void, os::unix::io::RawFd, ptr::NonNull, @@ -79,26 +80,6 @@ impl HardwareBufferUsage { Self(ffi::AHardwareBuffer_UsageFlags_AHARDWAREBUFFER_USAGE_VENDOR_19); } -#[repr(u32)] -#[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] -#[allow(non_camel_case_types)] -pub enum HardwareBufferFormat { - R8G8B8A8_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM.0, - R8G8B8X8_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM.0, - R8G8B8_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM.0, - R5G6B5_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM.0, - R16G16B16A16_FLOAT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT.0, - R10G10B10A2_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM.0, - BLOB = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_BLOB.0, - D16_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D16_UNORM.0, - D24_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D24_UNORM.0, - D24_UNORM_S8_UINT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT.0, - D32_FLOAT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D32_FLOAT.0, - D32_FLOAT_S8_UINT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT.0, - S8_UINT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_S8_UINT.0, - Y8Cb8Cr8_420 = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420.0, -} - #[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)] pub struct HardwareBufferError(pub i32); diff --git a/ndk/src/hardware_buffer_format.rs b/ndk/src/hardware_buffer_format.rs new file mode 100644 index 00000000..9d6501d8 --- /dev/null +++ b/ndk/src/hardware_buffer_format.rs @@ -0,0 +1,34 @@ +use num_enum::{IntoPrimitive, TryFromPrimitive}; + +#[repr(u32)] +#[derive(Copy, Clone, Debug, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] +#[allow(non_camel_case_types)] +pub enum HardwareBufferFormat { + /// Matches deprecated [`ffi::ANativeWindow_LegacyFormat_WINDOW_FORMAT_RGBA_8888`]. + R8G8B8A8_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM.0, + /// Matches deprecated [`ffi::ANativeWindow_LegacyFormat_WINDOW_FORMAT_RGBX_8888`]. + R8G8B8X8_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM.0, + #[cfg(feature = "api-level-26")] + R8G8B8_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM.0, + /// Matches deprecated [`ffi::ANativeWindow_LegacyFormat_WINDOW_FORMAT_RGB_565`]. + R5G6B5_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R5G6B5_UNORM.0, + R16G16B16A16_FLOAT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R16G16B16A16_FLOAT.0, + #[cfg(feature = "api-level-26")] + R10G10B10A2_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R10G10B10A2_UNORM.0, + #[cfg(feature = "api-level-26")] + BLOB = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_BLOB.0, + #[cfg(feature = "api-level-26")] + D16_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D16_UNORM.0, + #[cfg(feature = "api-level-26")] + D24_UNORM = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D24_UNORM.0, + #[cfg(feature = "api-level-26")] + D24_UNORM_S8_UINT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D24_UNORM_S8_UINT.0, + #[cfg(feature = "api-level-26")] + D32_FLOAT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D32_FLOAT.0, + #[cfg(feature = "api-level-26")] + D32_FLOAT_S8_UINT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_D32_FLOAT_S8_UINT.0, + #[cfg(feature = "api-level-26")] + S8_UINT = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_S8_UINT.0, + #[cfg(feature = "api-level-26")] + Y8Cb8Cr8_420 = ffi::AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_Y8Cb8Cr8_420.0, +} diff --git a/ndk/src/lib.rs b/ndk/src/lib.rs index 77dd1878..19a8bbc4 100644 --- a/ndk/src/lib.rs +++ b/ndk/src/lib.rs @@ -16,15 +16,15 @@ #![warn(missing_debug_implementations, trivial_casts)] pub mod asset; +pub mod audio; pub mod bitmap; pub mod configuration; pub mod event; +pub mod hardware_buffer; +pub mod hardware_buffer_format; pub mod input_queue; pub mod looper; +pub mod media; pub mod native_activity; pub mod native_window; - -pub mod audio; -pub mod hardware_buffer; -pub mod media; pub mod trace; diff --git a/ndk/src/native_activity.rs b/ndk/src/native_activity.rs index 9811560d..c64a3cb0 100644 --- a/ndk/src/native_activity.rs +++ b/ndk/src/native_activity.rs @@ -3,7 +3,6 @@ //! See also [the NDK //! docs](https://developer.android.com/ndk/reference/struct/a-native-activity.html) -//use num_enum::{IntoPrimitive, TryFromPrimitive}; use std::ffi::CStr; use std::os::raw::c_void; use std::ptr::NonNull; @@ -178,11 +177,3 @@ impl NativeActivity { unsafe { ffi::ANativeActivity_setWindowFormat(self.ptr.as_ptr(), format.into()) } }*/ } - -/*#[derive(Debug, Clone, Copy, PartialEq, Eq, TryFromPrimitive, IntoPrimitive)] -#[repr(u32)] -pub enum WindowFormat { - Rgb565 = ffi::ANativeWindow_LegacyFormat_WINDOW_FORMAT_RGB_565, - Rgba8888 = ffi::ANativeWindow_LegacyFormat_WINDOW_FORMAT_RGBA_8888, - Rgbx8888 = ffi::ANativeWindow_LegacyFormat_WINDOW_FORMAT_RGBX_8888, -}*/ diff --git a/ndk/src/native_window.rs b/ndk/src/native_window.rs index 057fa8d4..fe99d1b3 100644 --- a/ndk/src/native_window.rs +++ b/ndk/src/native_window.rs @@ -1,9 +1,11 @@ //! Bindings for [`ffi::ANativeWindow`] +pub use super::hardware_buffer_format::HardwareBufferFormat; use jni_sys::{jobject, JNIEnv}; use raw_window_handle::{AndroidNdkHandle, HasRawWindowHandle, RawWindowHandle}; -use std::{ffi::c_void, ptr::NonNull}; +use std::{convert::TryFrom, ffi::c_void, ptr::NonNull}; +/// #[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct NativeWindow { ptr: NonNull, @@ -20,10 +22,8 @@ impl Drop for NativeWindow { impl Clone for NativeWindow { fn clone(&self) -> Self { - unsafe { - ffi::ANativeWindow_acquire(self.ptr.as_ptr()); - Self { ptr: self.ptr } - } + unsafe { ffi::ANativeWindow_acquire(self.ptr.as_ptr()) } + Self { ptr: self.ptr } } } @@ -65,6 +65,35 @@ impl NativeWindow { unsafe { ffi::ANativeWindow_getWidth(self.ptr.as_ptr()) } } + /// Return the current pixel format ([`HardwareBufferFormat`]) of the window surface. + pub fn format(&self) -> HardwareBufferFormat { + let value = unsafe { ffi::ANativeWindow_getFormat(self.ptr.as_ptr()) }; + let value = u32::try_from(value).unwrap(); + HardwareBufferFormat::try_from(value).unwrap() + } + + /// Change the format and size of the window buffers. + /// + /// The width and height control the number of pixels in the buffers, not the dimensions of the window on screen. If these are different than the window's physical size, then its buffer will be scaled to match that size when compositing it to the screen. The width and height must be either both zero or both non-zero. + /// + /// For all of these parameters, if `0` or [`None`] is supplied then the window's base value will come back in force. + pub fn set_buffers_geometry( + &self, + width: i32, + height: i32, + format: Option, + ) -> Result<(), i32> { + let format: u32 = format.map_or(0, |f| f.into()); + let r = unsafe { + ffi::ANativeWindow_setBuffersGeometry(self.ptr.as_ptr(), width, height, format as i32) + }; + if r == 0 { + Ok(()) + } else { + Err(r) + } + } + /// Return the [`NativeWindow`] associated with a JNI [`android.view.Surface`] pointer. /// /// # Safety