Loading libs/nativewindow/rust/src/lib.rs +74 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,50 @@ impl HardwareBuffer { } } /// Creates a `HardwareBuffer` from a native handle. /// /// The native handle is cloned, so this doesn't take ownership of the original handle passed /// in. pub fn create_from_handle( handle: &NativeHandle, buffer_desc: &ffi::AHardwareBuffer_Desc, ) -> Result<Self, StatusCode> { let mut buffer = ptr::null_mut(); // SAFETY: The caller guarantees that `handle` is valid, and the buffer pointer is valid // because it comes from a reference. The method we pass means that // `AHardwareBuffer_createFromHandle` will clone the handle rather than taking ownership of // it. let status = unsafe { ffi::AHardwareBuffer_createFromHandle( buffer_desc, handle.as_raw().as_ptr(), ffi::CreateFromHandleMethod_AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE .try_into() .unwrap(), &mut buffer, ) }; status_result(status)?; Ok(Self(NonNull::new(buffer).expect("Allocated AHardwareBuffer was null"))) } /// Returns a clone of the native handle of the buffer. /// /// Returns `None` if the operation fails for any reason. pub fn cloned_native_handle(&self) -> Option<NativeHandle> { // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid // because it must have been allocated by `AHardwareBuffer_allocate`, // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet // released it. let native_handle = unsafe { ffi::AHardwareBuffer_getNativeHandle(self.0.as_ptr()) }; NonNull::new(native_handle.cast_mut()).and_then(|native_handle| { // SAFETY: `AHardwareBuffer_getNativeHandle` should have returned a valid pointer which // is valid at least as long as the buffer is, and `clone_from_raw` clones it rather // than taking ownership of it so the original `native_handle` isn't stored. unsafe { NativeHandle::clone_from_raw(native_handle) } }) } /// Adopts the given raw pointer and wraps it in a Rust HardwareBuffer. /// /// # Safety Loading Loading @@ -393,4 +437,34 @@ mod test { assert_eq!(remade_buffer, buffer2); } #[test] fn native_handle_and_back() { let buffer = HardwareBuffer::new( 1024, 512, 1, AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, ) .expect("Buffer with some basic parameters was not created successfully"); let native_handle = buffer.cloned_native_handle().expect("Failed to get native handle for buffer"); let buffer_desc = ffi::AHardwareBuffer_Desc { width: 1024, height: 512, layers: 1, format: AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, usage: AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN.0, stride: 1024, rfu0: 0, rfu1: 0, }; let buffer2 = HardwareBuffer::create_from_handle(&native_handle, &buffer_desc) .expect("Failed to create buffer from native handle"); assert_eq!(buffer.description(), buffer_desc); assert_eq!(buffer2.description(), buffer_desc); } } libs/nativewindow/rust/sys/nativewindow_bindings.h +1 −0 Original line number Diff line number Diff line Loading @@ -21,3 +21,4 @@ #include <android/native_window.h> #include <android/native_window_aidl.h> #include <cutils/native_handle.h> #include <vndk/hardware_buffer.h> Loading
libs/nativewindow/rust/src/lib.rs +74 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,50 @@ impl HardwareBuffer { } } /// Creates a `HardwareBuffer` from a native handle. /// /// The native handle is cloned, so this doesn't take ownership of the original handle passed /// in. pub fn create_from_handle( handle: &NativeHandle, buffer_desc: &ffi::AHardwareBuffer_Desc, ) -> Result<Self, StatusCode> { let mut buffer = ptr::null_mut(); // SAFETY: The caller guarantees that `handle` is valid, and the buffer pointer is valid // because it comes from a reference. The method we pass means that // `AHardwareBuffer_createFromHandle` will clone the handle rather than taking ownership of // it. let status = unsafe { ffi::AHardwareBuffer_createFromHandle( buffer_desc, handle.as_raw().as_ptr(), ffi::CreateFromHandleMethod_AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE .try_into() .unwrap(), &mut buffer, ) }; status_result(status)?; Ok(Self(NonNull::new(buffer).expect("Allocated AHardwareBuffer was null"))) } /// Returns a clone of the native handle of the buffer. /// /// Returns `None` if the operation fails for any reason. pub fn cloned_native_handle(&self) -> Option<NativeHandle> { // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid // because it must have been allocated by `AHardwareBuffer_allocate`, // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet // released it. let native_handle = unsafe { ffi::AHardwareBuffer_getNativeHandle(self.0.as_ptr()) }; NonNull::new(native_handle.cast_mut()).and_then(|native_handle| { // SAFETY: `AHardwareBuffer_getNativeHandle` should have returned a valid pointer which // is valid at least as long as the buffer is, and `clone_from_raw` clones it rather // than taking ownership of it so the original `native_handle` isn't stored. unsafe { NativeHandle::clone_from_raw(native_handle) } }) } /// Adopts the given raw pointer and wraps it in a Rust HardwareBuffer. /// /// # Safety Loading Loading @@ -393,4 +437,34 @@ mod test { assert_eq!(remade_buffer, buffer2); } #[test] fn native_handle_and_back() { let buffer = HardwareBuffer::new( 1024, 512, 1, AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, ) .expect("Buffer with some basic parameters was not created successfully"); let native_handle = buffer.cloned_native_handle().expect("Failed to get native handle for buffer"); let buffer_desc = ffi::AHardwareBuffer_Desc { width: 1024, height: 512, layers: 1, format: AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, usage: AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN.0, stride: 1024, rfu0: 0, rfu1: 0, }; let buffer2 = HardwareBuffer::create_from_handle(&native_handle, &buffer_desc) .expect("Failed to create buffer from native handle"); assert_eq!(buffer.description(), buffer_desc); assert_eq!(buffer2.description(), buffer_desc); } }
libs/nativewindow/rust/sys/nativewindow_bindings.h +1 −0 Original line number Diff line number Diff line Loading @@ -21,3 +21,4 @@ #include <android/native_window.h> #include <android/native_window_aidl.h> #include <cutils/native_handle.h> #include <vndk/hardware_buffer.h>