Skip to content

Commit

Permalink
ndk/native_window: Implement HasWindowHandle for 0.4 and 0.6 (and m…
Browse files Browse the repository at this point in the history
…aintain 0.5)

Following [the same strategy in winit], move `raw-window-handle 0.5`
behind a `rwh_05` feature and add `raw-window-handle 0.4` and the newly
released `raw-window-handle 0.6` behind a corresponding `rwh04`/`rwh_06`
feature.  The new **non-raw** trait and **lifetimed** type since `0.6`
have been implemented instead, as `raw-window-handle` provides blanket
implementations to coerce/convert back to `Raw*` types.

[the same strategy in winit]: rust-windowing/winit#3126
  • Loading branch information
MarijnS95 committed Oct 8, 2023
1 parent 66af2c3 commit 9d56d0f
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 14 deletions.
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

0 comments on commit 9d56d0f

Please sign in to comment.