Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ndk/native_window: Implement HasWindowHandle for 0.4 and 0.6 (and maintain 0.5) #434

Merged
merged 1 commit into from
Oct 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ndk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
- native_window: Add `set_buffers_transform()`, `try_allocate_buffers()` and `set_frame_rate*()`. (#425)
- hardware_buffer: Add `id()` to retrieve a system-wide unique identifier for a `HardwareBuffer`. (#428)
- **Breaking:** bitmap: Strip `Android` prefix from structs and enums, and `Bitmap` from `Result`. (#430)
- **Breaking:** `raw-window-handle 0.5` support is now behind an _optional_ `rwh_05` crate feature and `raw-window-handle` `0.4` and `0.6` support is provided via the new `rwh_04` and (default-enabled) `rwh_06` crate features. (#434)

# 0.7.0 (2022-07-24)

Expand Down
7 changes: 5 additions & 2 deletions ndk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ repository = "https://github.com/rust-mobile/ndk"
rust-version = "1.66"

[features]
all = ["audio", "bitmap","media", "api-level-31"]
default = ["rwh_06"]
all = ["audio", "bitmap","media", "api-level-31", "rwh_04", "rwh_05", "rwh_06"]

audio = ["ffi/audio", "api-level-26"]
bitmap = ["ffi/bitmap"]
Expand All @@ -36,7 +37,9 @@ bitflags = "2.0.0"
jni-sys = "0.3.0"
log = "0.4"
num_enum = "0.7"
raw-window-handle = "0.5"
rwh_04 = { package = "raw-window-handle", version = "0.4", optional = true }
rwh_05 = { package = "raw-window-handle", version = "0.5", optional = true }
rwh_06 = { package = "raw-window-handle", version = "0.6", optional = true }
thiserror = "1.0.23"

[dependencies.jni]
Expand Down
49 changes: 37 additions & 12 deletions ndk/src/native_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ use crate::utils::status_to_io_result;

pub use super::hardware_buffer_format::HardwareBufferFormat;
use jni_sys::{jobject, JNIEnv};
use raw_window_handle::{AndroidNdkWindowHandle, HasRawWindowHandle, RawWindowHandle};
use std::{ffi::c_void, io::Result, mem::MaybeUninit, ptr::NonNull};
use std::{ffi::c_void, io, mem::MaybeUninit, ptr::NonNull};

pub type Rect = ffi::ARect;

Expand Down Expand Up @@ -39,11 +38,34 @@ impl Clone for NativeWindow {
}
}

unsafe impl HasRawWindowHandle for NativeWindow {
fn raw_window_handle(&self) -> RawWindowHandle {
let mut handle = AndroidNdkWindowHandle::empty();
handle.a_native_window = self.ptr.as_ptr() as *mut c_void;
RawWindowHandle::AndroidNdk(handle)
#[cfg(feature = "rwh_04")]
unsafe impl rwh_04::HasRawWindowHandle for NativeWindow {
fn raw_window_handle(&self) -> rwh_04::RawWindowHandle {
let mut handle = rwh_04::AndroidNdkHandle::empty();
handle.a_native_window = self.ptr.as_ptr().cast();
rwh_04::RawWindowHandle::AndroidNdk(handle)
}
}

#[cfg(feature = "rwh_05")]
unsafe impl rwh_05::HasRawWindowHandle for NativeWindow {
fn raw_window_handle(&self) -> rwh_05::RawWindowHandle {
let mut handle = rwh_05::AndroidNdkWindowHandle::empty();
handle.a_native_window = self.ptr.as_ptr().cast();
rwh_05::RawWindowHandle::AndroidNdk(handle)
}
}

#[cfg(feature = "rwh_06")]
impl rwh_06::HasWindowHandle for NativeWindow {
fn window_handle(&self) -> Result<rwh_06::WindowHandle<'_>, rwh_06::HandleError> {
let handle = rwh_06::AndroidNdkWindowHandle::new(self.ptr.cast());
let handle = rwh_06::RawWindowHandle::AndroidNdk(handle);
// SAFETY: All fields of the "raw" `AndroidNdkWindowHandle` struct are filled out. The
// returned pointer is also kept valid by `NativeWindow` (until `Drop`), which is lifetime-
// borrowed in the returned `WindowHandle<'_>` and cannot be outlived. Its value won't
// change throughout the lifetime of this `NativeWindow`.
Ok(unsafe { rwh_06::WindowHandle::borrow_raw(handle) })
}
}

Expand Down Expand Up @@ -98,7 +120,7 @@ impl NativeWindow {
width: i32,
height: i32,
format: Option<HardwareBufferFormat>,
) -> Result<()> {
) -> io::Result<()> {
let format = format.map_or(0, |f| {
u32::from(f)
.try_into()
Expand All @@ -112,7 +134,7 @@ impl NativeWindow {

/// Set a transform that will be applied to future buffers posted to the window.
#[cfg(feature = "api-level-26")]
pub fn set_buffers_transform(&self, transform: NativeWindowTransform) -> Result<()> {
pub fn set_buffers_transform(&self, transform: NativeWindowTransform) -> io::Result<()> {
let status = unsafe {
ffi::ANativeWindow_setBuffersTransform(self.ptr.as_ptr(), transform.bits() as i32)
};
Expand All @@ -133,7 +155,7 @@ impl NativeWindow {
&self,
frame_rate: f32,
compatibility: FrameRateCompatibility,
) -> Result<()> {
) -> io::Result<()> {
let compatibility = (compatibility as u32)
.try_into()
.expect("i8 overflow in FrameRateCompatibility");
Expand Down Expand Up @@ -180,7 +202,7 @@ impl NativeWindow {
frame_rate: f32,
compatibility: FrameRateCompatibility,
change_frame_rate_strategy: ChangeFrameRateStrategy,
) -> Result<()> {
) -> io::Result<()> {
let compatibility = (compatibility as u32)
.try_into()
.expect("i8 overflow in FrameRateCompatibility");
Expand Down Expand Up @@ -235,7 +257,10 @@ impl NativeWindow {
///
/// Optionally pass the region you intend to draw into `dirty_bounds`. When this function
/// returns it is updated (commonly enlarged) with the actual area the caller needs to redraw.
pub fn lock(&self, dirty_bounds: Option<&mut Rect>) -> Result<NativeWindowBufferLockGuard<'_>> {
pub fn lock(
&self,
dirty_bounds: Option<&mut Rect>,
) -> io::Result<NativeWindowBufferLockGuard<'_>> {
let dirty_bounds = match dirty_bounds {
Some(dirty_bounds) => dirty_bounds,
None => std::ptr::null_mut(),
Expand Down
Loading