Skip to content

Commit

Permalink
native_window: Add format() getter and set_buffers_geometry() setter
Browse files Browse the repository at this point in the history
Android's `NativeWindow` allow querying the format through
`ANativeWindow_getFormat` and setting it through
`ANativeWindow_setBuffersGeometry` together with the dimensions to use
for the buffer.
  • Loading branch information
MarijnS95 committed May 20, 2022
1 parent be55263 commit 5bac4a1
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 39 deletions.
23 changes: 2 additions & 21 deletions ndk/src/hardware_buffer.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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);

Expand Down
34 changes: 34 additions & 0 deletions ndk/src/hardware_buffer_format.rs
Original file line number Diff line number Diff line change
@@ -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,
}
8 changes: 4 additions & 4 deletions ndk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
9 changes: 0 additions & 9 deletions ndk/src/native_activity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
}*/
39 changes: 34 additions & 5 deletions ndk/src/native_window.rs
Original file line number Diff line number Diff line change
@@ -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};

/// <https://developer.android.com/ndk/reference/group/a-native-window>
#[derive(Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct NativeWindow {
ptr: NonNull<ffi::ANativeWindow>,
Expand All @@ -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 }
}
}

Expand Down Expand Up @@ -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<HardwareBufferFormat>,
) -> 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
Expand Down

0 comments on commit 5bac4a1

Please sign in to comment.