diff options
author | 2024-08-30 14:10:29 +0100 | |
---|---|---|
committer | 2024-09-02 21:59:29 +0100 | |
commit | abc932e45eb8aadef04361143ab1a2ff38aeae8c (patch) | |
tree | d02d1375aa796096ae1e2295407e8a9b27f3a0bc | |
parent | a73d62cdc4ec3ca69168204984ebafcd12477438 (diff) |
Add Rust wrapper around AHardwareBuffer_Desc.
Bug: 359100544
Test: atest libnativewindow_rs-internal_test
Test: atest libbufferstreams-internal_test
Change-Id: I9065ca34cebde50a97b1e5331e293347bc42f563
-rw-r--r-- | libs/bufferstreams/rust/src/stream_config.rs | 24 | ||||
-rw-r--r-- | libs/nativewindow/rust/src/lib.rs | 225 | ||||
-rw-r--r-- | libs/nativewindow/tests/benchmark/buffer_benchmarks.rs | 7 |
3 files changed, 146 insertions, 110 deletions
diff --git a/libs/bufferstreams/rust/src/stream_config.rs b/libs/bufferstreams/rust/src/stream_config.rs index 454bdf144e..8288f9f3cf 100644 --- a/libs/bufferstreams/rust/src/stream_config.rs +++ b/libs/bufferstreams/rust/src/stream_config.rs @@ -32,10 +32,23 @@ pub struct StreamConfig { pub stride: u32, } +impl From<StreamConfig> for HardwareBufferDescription { + fn from(config: StreamConfig) -> Self { + HardwareBufferDescription::new( + config.width, + config.height, + config.layers, + config.format, + config.usage, + config.stride, + ) + } +} + impl StreamConfig { /// Tries to create a new HardwareBuffer from settings in a [StreamConfig]. pub fn create_hardware_buffer(&self) -> Option<HardwareBuffer> { - HardwareBuffer::new(self.width, self.height, self.layers, self.format, self.usage) + HardwareBuffer::new(&(*self).into()) } } @@ -59,9 +72,10 @@ mod test { assert!(maybe_buffer.is_some()); let buffer = maybe_buffer.unwrap(); - assert_eq!(config.width, buffer.width()); - assert_eq!(config.height, buffer.height()); - assert_eq!(config.format, buffer.format()); - assert_eq!(config.usage, buffer.usage()); + let description = buffer.description(); + assert_eq!(config.width, description.width()); + assert_eq!(config.height, description.height()); + assert_eq!(config.format, description.format()); + assert_eq!(config.usage, description.usage()); } } diff --git a/libs/nativewindow/rust/src/lib.rs b/libs/nativewindow/rust/src/lib.rs index 54dad04071..931c311e65 100644 --- a/libs/nativewindow/rust/src/lib.rs +++ b/libs/nativewindow/rust/src/lib.rs @@ -30,31 +30,29 @@ use binder::{ unstable_api::{status_result, AsNative}, StatusCode, }; -use ffi::{AHardwareBuffer, AHardwareBuffer_readFromParcel, AHardwareBuffer_writeToParcel}; +use ffi::{ + AHardwareBuffer, AHardwareBuffer_Desc, AHardwareBuffer_readFromParcel, + AHardwareBuffer_writeToParcel, +}; use std::fmt::{self, Debug, Formatter}; use std::mem::ManuallyDrop; use std::ptr::{self, null_mut, NonNull}; -/// Wrapper around an opaque C `AHardwareBuffer`. -#[derive(PartialEq, Eq)] -pub struct HardwareBuffer(NonNull<AHardwareBuffer>); +/// Wrapper around a C `AHardwareBuffer_Desc`. +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct HardwareBufferDescription(AHardwareBuffer_Desc); -impl HardwareBuffer { - /// Test whether the given format and usage flag combination is allocatable. If this function - /// returns true, it means that a buffer with the given description can be allocated on this - /// implementation, unless resource exhaustion occurs. If this function returns false, it means - /// that the allocation of the given description will never succeed. - /// - /// Available since API 29 - pub fn is_supported( +impl HardwareBufferDescription { + /// Creates a new `HardwareBufferDescription` with the given parameters. + pub fn new( width: u32, height: u32, layers: u32, format: AHardwareBuffer_Format::Type, usage: AHardwareBuffer_UsageFlags, stride: u32, - ) -> bool { - let buffer_desc = ffi::AHardwareBuffer_Desc { + ) -> Self { + Self(AHardwareBuffer_Desc { width, height, layers, @@ -63,9 +61,69 @@ impl HardwareBuffer { stride, rfu0: 0, rfu1: 0, - }; - // SAFETY: *buffer_desc will never be null. - let status = unsafe { ffi::AHardwareBuffer_isSupported(&buffer_desc) }; + }) + } + + /// Returns the width from the buffer description. + pub fn width(&self) -> u32 { + self.0.width + } + + /// Returns the height from the buffer description. + pub fn height(&self) -> u32 { + self.0.height + } + + /// Returns the number from layers from the buffer description. + pub fn layers(&self) -> u32 { + self.0.layers + } + + /// Returns the format from the buffer description. + pub fn format(&self) -> AHardwareBuffer_Format::Type { + self.0.format + } + + /// Returns the usage bitvector from the buffer description. + pub fn usage(&self) -> AHardwareBuffer_UsageFlags { + AHardwareBuffer_UsageFlags(self.0.usage) + } + + /// Returns the stride from the buffer description. + pub fn stride(&self) -> u32 { + self.0.stride + } +} + +impl Default for HardwareBufferDescription { + fn default() -> Self { + Self(AHardwareBuffer_Desc { + width: 0, + height: 0, + layers: 0, + format: 0, + usage: 0, + stride: 0, + rfu0: 0, + rfu1: 0, + }) + } +} + +/// Wrapper around an opaque C `AHardwareBuffer`. +#[derive(PartialEq, Eq)] +pub struct HardwareBuffer(NonNull<AHardwareBuffer>); + +impl HardwareBuffer { + /// Test whether the given format and usage flag combination is allocatable. If this function + /// returns true, it means that a buffer with the given description can be allocated on this + /// implementation, unless resource exhaustion occurs. If this function returns false, it means + /// that the allocation of the given description will never succeed. + /// + /// Available since API 29 + pub fn is_supported(buffer_description: &HardwareBufferDescription) -> bool { + // SAFETY: The pointer comes from a reference so must be valid. + let status = unsafe { ffi::AHardwareBuffer_isSupported(&buffer_description.0) }; status == 1 } @@ -77,27 +135,11 @@ impl HardwareBuffer { /// /// Available since API level 26. #[inline] - pub fn new( - width: u32, - height: u32, - layers: u32, - format: AHardwareBuffer_Format::Type, - usage: AHardwareBuffer_UsageFlags, - ) -> Option<Self> { - let buffer_desc = ffi::AHardwareBuffer_Desc { - width, - height, - layers, - format, - usage: usage.0, - stride: 0, - rfu0: 0, - rfu1: 0, - }; + pub fn new(buffer_description: &HardwareBufferDescription) -> Option<Self> { let mut ptr = ptr::null_mut(); // SAFETY: The returned pointer is valid until we drop/deallocate it. The function may fail // and return a status, but we check it later. - let status = unsafe { ffi::AHardwareBuffer_allocate(&buffer_desc, &mut ptr) }; + let status = unsafe { ffi::AHardwareBuffer_allocate(&buffer_description.0, &mut ptr) }; if status == 0 { Some(Self(NonNull::new(ptr).expect("Allocated AHardwareBuffer was null"))) @@ -112,7 +154,7 @@ impl HardwareBuffer { /// in. pub fn create_from_handle( handle: &NativeHandle, - buffer_desc: &ffi::AHardwareBuffer_Desc, + buffer_description: &HardwareBufferDescription, ) -> Result<Self, StatusCode> { let mut buffer = ptr::null_mut(); // SAFETY: The caller guarantees that `handle` is valid, and the buffer pointer is valid @@ -121,7 +163,7 @@ impl HardwareBuffer { // it. let status = unsafe { ffi::AHardwareBuffer_createFromHandle( - buffer_desc, + &buffer_description.0, handle.as_raw().as_ptr(), ffi::CreateFromHandleMethod_AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE .try_into() @@ -202,37 +244,8 @@ impl HardwareBuffer { out_id } - /// Get the width of this buffer - pub fn width(&self) -> u32 { - self.description().width - } - - /// Get the height of this buffer - pub fn height(&self) -> u32 { - self.description().height - } - - /// Get the number of layers of this buffer - pub fn layers(&self) -> u32 { - self.description().layers - } - - /// Get the format of this buffer - pub fn format(&self) -> AHardwareBuffer_Format::Type { - self.description().format - } - - /// Get the usage bitvector of this buffer - pub fn usage(&self) -> AHardwareBuffer_UsageFlags { - AHardwareBuffer_UsageFlags(self.description().usage) - } - - /// Get the stride of this buffer - pub fn stride(&self) -> u32 { - self.description().stride - } - - fn description(&self) -> ffi::AHardwareBuffer_Desc { + /// Returns the description of this buffer. + pub fn description(&self) -> HardwareBufferDescription { let mut buffer_desc = ffi::AHardwareBuffer_Desc { width: 0, height: 0, @@ -245,7 +258,7 @@ impl HardwareBuffer { }; // SAFETY: neither the buffer nor AHardwareBuffer_Desc pointers will be null. unsafe { ffi::AHardwareBuffer_describe(self.0.as_ref(), &mut buffer_desc) }; - buffer_desc + HardwareBufferDescription(buffer_desc) } } @@ -328,19 +341,27 @@ mod test { #[test] fn create_valid_buffer_returns_ok() { - let buffer = HardwareBuffer::new( + let buffer = HardwareBuffer::new(&HardwareBufferDescription::new( 512, 512, 1, AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, - ); + 0, + )); assert!(buffer.is_some()); } #[test] fn create_invalid_buffer_returns_err() { - let buffer = HardwareBuffer::new(512, 512, 1, 0, AHardwareBuffer_UsageFlags(0)); + let buffer = HardwareBuffer::new(&HardwareBufferDescription::new( + 512, + 512, + 1, + 0, + AHardwareBuffer_UsageFlags(0), + 0, + )); assert!(buffer.is_none()); } @@ -366,39 +387,45 @@ mod test { // SAFETY: The pointer must be valid because it was just allocated successfully, and we // don't use it after calling this. let buffer = unsafe { HardwareBuffer::from_raw(NonNull::new(raw_buffer_ptr).unwrap()) }; - assert_eq!(buffer.width(), 1024); + assert_eq!(buffer.description().width(), 1024); } #[test] fn basic_getters() { - let buffer = HardwareBuffer::new( + let buffer = HardwareBuffer::new(&HardwareBufferDescription::new( 1024, 512, 1, AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, - ) + 0, + )) .expect("Buffer with some basic parameters was not created successfully"); - assert_eq!(buffer.width(), 1024); - assert_eq!(buffer.height(), 512); - assert_eq!(buffer.layers(), 1); - assert_eq!(buffer.format(), AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM); + let description = buffer.description(); + assert_eq!(description.width(), 1024); + assert_eq!(description.height(), 512); + assert_eq!(description.layers(), 1); assert_eq!( - buffer.usage(), + description.format(), + AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM + ); + assert_eq!( + description.usage(), AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN ); } #[test] fn id_getter() { - let buffer = HardwareBuffer::new( + let buffer = HardwareBuffer::new(&HardwareBufferDescription::new( 1024, 512, 1, AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, - ) + 0, + )) .expect("Buffer with some basic parameters was not created successfully"); assert_ne!(0, buffer.id()); @@ -406,13 +433,14 @@ mod test { #[test] fn clone() { - let buffer = HardwareBuffer::new( + let buffer = HardwareBuffer::new(&HardwareBufferDescription::new( 1024, 512, 1, AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, - ) + 0, + )) .expect("Buffer with some basic parameters was not created successfully"); let buffer2 = buffer.clone(); @@ -421,13 +449,14 @@ mod test { #[test] fn into_raw() { - let buffer = HardwareBuffer::new( + let buffer = HardwareBuffer::new(&HardwareBufferDescription::new( 1024, 512, 1, AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, - ) + 0, + )) .expect("Buffer with some basic parameters was not created successfully"); let buffer2 = buffer.clone(); @@ -440,31 +469,23 @@ mod test { #[test] fn native_handle_and_back() { - let buffer = HardwareBuffer::new( + let buffer_description = HardwareBufferDescription::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"); + 1024, + ); + let buffer = HardwareBuffer::new(&buffer_description) + .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) + let buffer2 = HardwareBuffer::create_from_handle(&native_handle, &buffer_description) .expect("Failed to create buffer from native handle"); - assert_eq!(buffer.description(), buffer_desc); - assert_eq!(buffer2.description(), buffer_desc); + assert_eq!(buffer.description(), buffer_description); + assert_eq!(buffer2.description(), buffer_description); } } diff --git a/libs/nativewindow/tests/benchmark/buffer_benchmarks.rs b/libs/nativewindow/tests/benchmark/buffer_benchmarks.rs index 876f6c8e26..73a7e95149 100644 --- a/libs/nativewindow/tests/benchmark/buffer_benchmarks.rs +++ b/libs/nativewindow/tests/benchmark/buffer_benchmarks.rs @@ -22,13 +22,14 @@ use nativewindow::*; #[inline] fn create_720p_buffer() -> HardwareBuffer { - HardwareBuffer::new( + HardwareBuffer::new(&HardwareBufferDescription::new( 1280, 720, 1, AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM, AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN, - ) + 0, + )) .unwrap() } @@ -51,7 +52,7 @@ fn criterion_benchmark(c: &mut Criterion) { // underlying call to AHardwareBuffer_describe. c.bench_with_input(BenchmarkId::new("desc", "buffer"), &buffer, |b, buffer| { b.iter(|| { - buffer.width(); + buffer.description().width(); }) }); } |