xref: /aosp_15_r20/frameworks/native/libs/nativewindow/rust/src/lib.rs (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 // Copyright (C) 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Pleasant Rust bindings for libnativewindow, including AHardwareBuffer
16 
17 extern crate nativewindow_bindgen as ffi;
18 
19 mod handle;
20 mod surface;
21 
22 pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};
23 pub use handle::NativeHandle;
24 pub use surface::{buffer::Buffer, Surface};
25 
26 use binder::{
27     binder_impl::{BorrowedParcel, UnstructuredParcelable},
28     impl_deserialize_for_unstructured_parcelable, impl_serialize_for_unstructured_parcelable,
29     unstable_api::{status_result, AsNative},
30     StatusCode,
31 };
32 use ffi::{
33     AHardwareBuffer, AHardwareBuffer_Desc, AHardwareBuffer_Plane, AHardwareBuffer_Planes,
34     AHardwareBuffer_readFromParcel, AHardwareBuffer_writeToParcel, ARect,
35 };
36 use std::ffi::c_void;
37 use std::fmt::{self, Debug, Formatter};
38 use std::mem::{forget, ManuallyDrop};
39 use std::os::fd::{AsRawFd, BorrowedFd, FromRawFd, OwnedFd};
40 use std::ptr::{self, null, null_mut, NonNull};
41 
42 /// Wrapper around a C `AHardwareBuffer_Desc`.
43 #[derive(Clone, Debug, PartialEq, Eq)]
44 pub struct HardwareBufferDescription(AHardwareBuffer_Desc);
45 
46 impl HardwareBufferDescription {
47     /// Creates a new `HardwareBufferDescription` with the given parameters.
new( width: u32, height: u32, layers: u32, format: AHardwareBuffer_Format::Type, usage: AHardwareBuffer_UsageFlags, stride: u32, ) -> Self48     pub fn new(
49         width: u32,
50         height: u32,
51         layers: u32,
52         format: AHardwareBuffer_Format::Type,
53         usage: AHardwareBuffer_UsageFlags,
54         stride: u32,
55     ) -> Self {
56         Self(AHardwareBuffer_Desc {
57             width,
58             height,
59             layers,
60             format,
61             usage: usage.0,
62             stride,
63             rfu0: 0,
64             rfu1: 0,
65         })
66     }
67 
68     /// Returns the width from the buffer description.
width(&self) -> u3269     pub fn width(&self) -> u32 {
70         self.0.width
71     }
72 
73     /// Returns the height from the buffer description.
height(&self) -> u3274     pub fn height(&self) -> u32 {
75         self.0.height
76     }
77 
78     /// Returns the number from layers from the buffer description.
layers(&self) -> u3279     pub fn layers(&self) -> u32 {
80         self.0.layers
81     }
82 
83     /// Returns the format from the buffer description.
format(&self) -> AHardwareBuffer_Format::Type84     pub fn format(&self) -> AHardwareBuffer_Format::Type {
85         self.0.format
86     }
87 
88     /// Returns the usage bitvector from the buffer description.
usage(&self) -> AHardwareBuffer_UsageFlags89     pub fn usage(&self) -> AHardwareBuffer_UsageFlags {
90         AHardwareBuffer_UsageFlags(self.0.usage)
91     }
92 
93     /// Returns the stride from the buffer description.
stride(&self) -> u3294     pub fn stride(&self) -> u32 {
95         self.0.stride
96     }
97 }
98 
99 impl Default for HardwareBufferDescription {
default() -> Self100     fn default() -> Self {
101         Self(AHardwareBuffer_Desc {
102             width: 0,
103             height: 0,
104             layers: 0,
105             format: 0,
106             usage: 0,
107             stride: 0,
108             rfu0: 0,
109             rfu1: 0,
110         })
111     }
112 }
113 
114 /// Wrapper around an opaque C `AHardwareBuffer`.
115 #[derive(PartialEq, Eq)]
116 pub struct HardwareBuffer(NonNull<AHardwareBuffer>);
117 
118 impl HardwareBuffer {
119     /// Test whether the given format and usage flag combination is allocatable.  If this function
120     /// returns true, it means that a buffer with the given description can be allocated on this
121     /// implementation, unless resource exhaustion occurs. If this function returns false, it means
122     /// that the allocation of the given description will never succeed.
123     ///
124     /// Available since API 29
is_supported(buffer_description: &HardwareBufferDescription) -> bool125     pub fn is_supported(buffer_description: &HardwareBufferDescription) -> bool {
126         // SAFETY: The pointer comes from a reference so must be valid.
127         let status = unsafe { ffi::AHardwareBuffer_isSupported(&buffer_description.0) };
128 
129         status == 1
130     }
131 
132     /// Allocates a buffer that matches the passed AHardwareBuffer_Desc. If allocation succeeds, the
133     /// buffer can be used according to the usage flags specified in its description. If a buffer is
134     /// used in ways not compatible with its usage flags, the results are undefined and may include
135     /// program termination.
136     ///
137     /// Available since API level 26.
138     #[inline]
new(buffer_description: &HardwareBufferDescription) -> Option<Self>139     pub fn new(buffer_description: &HardwareBufferDescription) -> Option<Self> {
140         let mut ptr = ptr::null_mut();
141         // SAFETY: The returned pointer is valid until we drop/deallocate it. The function may fail
142         // and return a status, but we check it later.
143         let status = unsafe { ffi::AHardwareBuffer_allocate(&buffer_description.0, &mut ptr) };
144 
145         if status == 0 {
146             Some(Self(NonNull::new(ptr).expect("Allocated AHardwareBuffer was null")))
147         } else {
148             None
149         }
150     }
151 
152     /// Creates a `HardwareBuffer` from a native handle.
153     ///
154     /// The native handle is cloned, so this doesn't take ownership of the original handle passed
155     /// in.
create_from_handle( handle: &NativeHandle, buffer_description: &HardwareBufferDescription, ) -> Result<Self, StatusCode>156     pub fn create_from_handle(
157         handle: &NativeHandle,
158         buffer_description: &HardwareBufferDescription,
159     ) -> Result<Self, StatusCode> {
160         let mut buffer = ptr::null_mut();
161         // SAFETY: The caller guarantees that `handle` is valid, and the buffer pointer is valid
162         // because it comes from a reference. The method we pass means that
163         // `AHardwareBuffer_createFromHandle` will clone the handle rather than taking ownership of
164         // it.
165         let status = unsafe {
166             ffi::AHardwareBuffer_createFromHandle(
167                 &buffer_description.0,
168                 handle.as_raw().as_ptr(),
169                 ffi::CreateFromHandleMethod_AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE
170                     .try_into()
171                     .unwrap(),
172                 &mut buffer,
173             )
174         };
175         status_result(status)?;
176         Ok(Self(NonNull::new(buffer).expect("Allocated AHardwareBuffer was null")))
177     }
178 
179     /// Returns a clone of the native handle of the buffer.
180     ///
181     /// Returns `None` if the operation fails for any reason.
cloned_native_handle(&self) -> Option<NativeHandle>182     pub fn cloned_native_handle(&self) -> Option<NativeHandle> {
183         // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
184         // because it must have been allocated by `AHardwareBuffer_allocate`,
185         // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
186         // released it.
187         let native_handle = unsafe { ffi::AHardwareBuffer_getNativeHandle(self.0.as_ptr()) };
188         NonNull::new(native_handle.cast_mut()).and_then(|native_handle| {
189             // SAFETY: `AHardwareBuffer_getNativeHandle` should have returned a valid pointer which
190             // is valid at least as long as the buffer is, and `clone_from_raw` clones it rather
191             // than taking ownership of it so the original `native_handle` isn't stored.
192             unsafe { NativeHandle::clone_from_raw(native_handle) }
193         })
194     }
195 
196     /// Adopts the given raw pointer and wraps it in a Rust HardwareBuffer.
197     ///
198     /// # Safety
199     ///
200     /// This function takes ownership of the pointer and does NOT increment the refcount on the
201     /// buffer. If the caller uses the pointer after the created object is dropped it will cause
202     /// undefined behaviour. If the caller wants to continue using the pointer after calling this
203     /// then use [`clone_from_raw`](Self::clone_from_raw) instead.
from_raw(buffer_ptr: NonNull<AHardwareBuffer>) -> Self204     pub unsafe fn from_raw(buffer_ptr: NonNull<AHardwareBuffer>) -> Self {
205         Self(buffer_ptr)
206     }
207 
208     /// Creates a new Rust HardwareBuffer to wrap the given `AHardwareBuffer` without taking
209     /// ownership of it.
210     ///
211     /// Unlike [`from_raw`](Self::from_raw) this method will increment the refcount on the buffer.
212     /// This means that the caller can continue to use the raw buffer it passed in, and must call
213     /// [`AHardwareBuffer_release`](ffi::AHardwareBuffer_release) when it is finished with it to
214     /// avoid a memory leak.
215     ///
216     /// # Safety
217     ///
218     /// The buffer pointer must point to a valid `AHardwareBuffer`.
clone_from_raw(buffer: NonNull<AHardwareBuffer>) -> Self219     pub unsafe fn clone_from_raw(buffer: NonNull<AHardwareBuffer>) -> Self {
220         // SAFETY: The caller guarantees that the AHardwareBuffer pointer is valid.
221         unsafe { ffi::AHardwareBuffer_acquire(buffer.as_ptr()) };
222         Self(buffer)
223     }
224 
225     /// Returns the internal `AHardwareBuffer` pointer.
226     ///
227     /// This is only valid as long as this `HardwareBuffer` exists, so shouldn't be stored. It can
228     /// be used to provide a pointer for a C/C++ API over FFI.
as_raw(&self) -> NonNull<AHardwareBuffer>229     pub fn as_raw(&self) -> NonNull<AHardwareBuffer> {
230         self.0
231     }
232 
233     /// Gets the internal `AHardwareBuffer` pointer without decrementing the refcount. This can
234     /// be used for a C/C++ API which takes ownership of the pointer.
235     ///
236     /// The caller is responsible for releasing the `AHardwareBuffer` pointer by calling
237     /// `AHardwareBuffer_release` when it is finished with it, or may convert it back to a Rust
238     /// `HardwareBuffer` by calling [`HardwareBuffer::from_raw`].
into_raw(self) -> NonNull<AHardwareBuffer>239     pub fn into_raw(self) -> NonNull<AHardwareBuffer> {
240         let buffer = ManuallyDrop::new(self);
241         buffer.0
242     }
243 
244     /// Get the system wide unique id for an AHardwareBuffer. This function may panic in extreme
245     /// and undocumented circumstances.
246     ///
247     /// Available since API level 31.
id(&self) -> u64248     pub fn id(&self) -> u64 {
249         let mut out_id = 0;
250         // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
251         // because it must have been allocated by `AHardwareBuffer_allocate`,
252         // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
253         // released it. The id pointer must be valid because it comes from a reference.
254         let status = unsafe { ffi::AHardwareBuffer_getId(self.0.as_ptr(), &mut out_id) };
255         assert_eq!(status, 0, "id() failed for AHardwareBuffer with error code: {status}");
256 
257         out_id
258     }
259 
260     /// Returns the description of this buffer.
description(&self) -> HardwareBufferDescription261     pub fn description(&self) -> HardwareBufferDescription {
262         let mut buffer_desc = ffi::AHardwareBuffer_Desc {
263             width: 0,
264             height: 0,
265             layers: 0,
266             format: 0,
267             usage: 0,
268             stride: 0,
269             rfu0: 0,
270             rfu1: 0,
271         };
272         // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid, and the
273         // AHardwareBuffer_Desc pointer is valid because it comes from a reference.
274         unsafe { ffi::AHardwareBuffer_describe(self.0.as_ref(), &mut buffer_desc) };
275         HardwareBufferDescription(buffer_desc)
276     }
277 
278     /// Locks the hardware buffer for direct CPU access.
279     ///
280     /// # Safety
281     ///
282     /// - If `fence` is `None`, the caller must ensure that all writes to the buffer have completed
283     ///   before calling this function.
284     /// - If the buffer has `AHARDWAREBUFFER_FORMAT_BLOB`, multiple threads or process may lock the
285     ///   buffer simultaneously, but the caller must ensure that they don't access it simultaneously
286     ///   and break Rust's aliasing rules, like any other shared memory.
287     /// - Otherwise if `usage` includes `AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY` or
288     ///   `AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN`, the caller must ensure that no other threads or
289     ///   processes lock the buffer simultaneously for any usage.
290     /// - Otherwise, the caller must ensure that no other threads lock the buffer for writing
291     ///   simultaneously.
292     /// - If `rect` is not `None`, the caller must not modify the buffer outside of that rectangle.
lock<'a>( &'a self, usage: AHardwareBuffer_UsageFlags, fence: Option<BorrowedFd>, rect: Option<&ARect>, ) -> Result<HardwareBufferGuard<'a>, StatusCode>293     pub unsafe fn lock<'a>(
294         &'a self,
295         usage: AHardwareBuffer_UsageFlags,
296         fence: Option<BorrowedFd>,
297         rect: Option<&ARect>,
298     ) -> Result<HardwareBufferGuard<'a>, StatusCode> {
299         let fence = if let Some(fence) = fence { fence.as_raw_fd() } else { -1 };
300         let rect = rect.map(ptr::from_ref).unwrap_or(null());
301         let mut address = null_mut();
302         // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid, and the buffer address out
303         // pointer is valid because it comes from a reference. Our caller promises that writes have
304         // completed and there will be no simultaneous read/write locks.
305         let status = unsafe {
306             ffi::AHardwareBuffer_lock(self.0.as_ptr(), usage.0, fence, rect, &mut address)
307         };
308         status_result(status)?;
309         Ok(HardwareBufferGuard {
310             buffer: self,
311             address: NonNull::new(address)
312                 .expect("AHardwareBuffer_lock set a null outVirtualAddress"),
313         })
314     }
315 
316     /// Lock a potentially multi-planar hardware buffer for direct CPU access.
317     ///
318     /// # Safety
319     ///
320     /// - If `fence` is `None`, the caller must ensure that all writes to the buffer have completed
321     ///   before calling this function.
322     /// - If the buffer has `AHARDWAREBUFFER_FORMAT_BLOB`, multiple threads or process may lock the
323     ///   buffer simultaneously, but the caller must ensure that they don't access it simultaneously
324     ///   and break Rust's aliasing rules, like any other shared memory.
325     /// - Otherwise if `usage` includes `AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY` or
326     ///   `AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN`, the caller must ensure that no other threads or
327     ///   processes lock the buffer simultaneously for any usage.
328     /// - Otherwise, the caller must ensure that no other threads lock the buffer for writing
329     ///   simultaneously.
330     /// - If `rect` is not `None`, the caller must not modify the buffer outside of that rectangle.
lock_planes<'a>( &'a self, usage: AHardwareBuffer_UsageFlags, fence: Option<BorrowedFd>, rect: Option<&ARect>, ) -> Result<Vec<PlaneGuard<'a>>, StatusCode>331     pub unsafe fn lock_planes<'a>(
332         &'a self,
333         usage: AHardwareBuffer_UsageFlags,
334         fence: Option<BorrowedFd>,
335         rect: Option<&ARect>,
336     ) -> Result<Vec<PlaneGuard<'a>>, StatusCode> {
337         let fence = if let Some(fence) = fence { fence.as_raw_fd() } else { -1 };
338         let rect = rect.map(ptr::from_ref).unwrap_or(null());
339         let mut planes = AHardwareBuffer_Planes {
340             planeCount: 0,
341             planes: [const { AHardwareBuffer_Plane { data: null_mut(), pixelStride: 0, rowStride: 0 } };
342                 4],
343         };
344 
345         // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid, and the various out
346         // pointers are valid because they come from references. Our caller promises that writes have
347         // completed and there will be no simultaneous read/write locks.
348         let status = unsafe {
349             ffi::AHardwareBuffer_lockPlanes(self.0.as_ptr(), usage.0, fence, rect, &mut planes)
350         };
351         status_result(status)?;
352         let plane_count = planes.planeCount.try_into().unwrap();
353         Ok(planes.planes[..plane_count]
354             .iter()
355             .map(|plane| PlaneGuard {
356                 guard: HardwareBufferGuard {
357                     buffer: self,
358                     address: NonNull::new(plane.data)
359                         .expect("AHardwareBuffer_lockAndGetInfo set a null outVirtualAddress"),
360                 },
361                 pixel_stride: plane.pixelStride,
362                 row_stride: plane.rowStride,
363             })
364             .collect())
365     }
366 
367     /// Locks the hardware buffer for direct CPU access, returning information about the bytes per
368     /// pixel and stride as well.
369     ///
370     /// # Safety
371     ///
372     /// - If `fence` is `None`, the caller must ensure that all writes to the buffer have completed
373     ///   before calling this function.
374     /// - If the buffer has `AHARDWAREBUFFER_FORMAT_BLOB`, multiple threads or process may lock the
375     ///   buffer simultaneously, but the caller must ensure that they don't access it simultaneously
376     ///   and break Rust's aliasing rules, like any other shared memory.
377     /// - Otherwise if `usage` includes `AHARDWAREBUFFER_USAGE_CPU_WRITE_RARELY` or
378     ///   `AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN`, the caller must ensure that no other threads or
379     ///   processes lock the buffer simultaneously for any usage.
380     /// - Otherwise, the caller must ensure that no other threads lock the buffer for writing
381     ///   simultaneously.
lock_and_get_info<'a>( &'a self, usage: AHardwareBuffer_UsageFlags, fence: Option<BorrowedFd>, rect: Option<&ARect>, ) -> Result<LockedBufferInfo<'a>, StatusCode>382     pub unsafe fn lock_and_get_info<'a>(
383         &'a self,
384         usage: AHardwareBuffer_UsageFlags,
385         fence: Option<BorrowedFd>,
386         rect: Option<&ARect>,
387     ) -> Result<LockedBufferInfo<'a>, StatusCode> {
388         let fence = if let Some(fence) = fence { fence.as_raw_fd() } else { -1 };
389         let rect = rect.map(ptr::from_ref).unwrap_or(null());
390         let mut address = null_mut();
391         let mut bytes_per_pixel = 0;
392         let mut stride = 0;
393         // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid, and the various out
394         // pointers are valid because they come from references. Our caller promises that writes have
395         // completed and there will be no simultaneous read/write locks.
396         let status = unsafe {
397             ffi::AHardwareBuffer_lockAndGetInfo(
398                 self.0.as_ptr(),
399                 usage.0,
400                 fence,
401                 rect,
402                 &mut address,
403                 &mut bytes_per_pixel,
404                 &mut stride,
405             )
406         };
407         status_result(status)?;
408         Ok(LockedBufferInfo {
409             guard: HardwareBufferGuard {
410                 buffer: self,
411                 address: NonNull::new(address)
412                     .expect("AHardwareBuffer_lockAndGetInfo set a null outVirtualAddress"),
413             },
414             bytes_per_pixel: bytes_per_pixel as u32,
415             stride: stride as u32,
416         })
417     }
418 
419     /// Unlocks the hardware buffer from direct CPU access.
420     ///
421     /// Must be called after all changes to the buffer are completed by the caller. This will block
422     /// until the unlocking is complete and the buffer contents are updated.
unlock(&self) -> Result<(), StatusCode>423     fn unlock(&self) -> Result<(), StatusCode> {
424         // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid.
425         let status = unsafe { ffi::AHardwareBuffer_unlock(self.0.as_ptr(), null_mut()) };
426         status_result(status)?;
427         Ok(())
428     }
429 
430     /// Unlocks the hardware buffer from direct CPU access.
431     ///
432     /// Must be called after all changes to the buffer are completed by the caller.
433     ///
434     /// This may not block until all work is completed, but rather will return a file descriptor
435     /// which will be signalled once the unlocking is complete and the buffer contents is updated.
436     /// If `Ok(None)` is returned then unlocking has already completed and no further waiting is
437     /// necessary. The file descriptor may be passed to a subsequent call to [`Self::lock`].
unlock_with_fence( &self, guard: HardwareBufferGuard, ) -> Result<Option<OwnedFd>, StatusCode>438     pub fn unlock_with_fence(
439         &self,
440         guard: HardwareBufferGuard,
441     ) -> Result<Option<OwnedFd>, StatusCode> {
442         // Forget the guard so that its `Drop` implementation doesn't try to unlock the
443         // HardwareBuffer again.
444         forget(guard);
445 
446         let mut fence = -2;
447         // SAFETY: The `AHardwareBuffer` pointer we wrap is always valid.
448         let status = unsafe { ffi::AHardwareBuffer_unlock(self.0.as_ptr(), &mut fence) };
449         let fence = if fence < 0 {
450             None
451         } else {
452             // SAFETY: `AHardwareBuffer_unlock` gives us ownership of the fence file descriptor.
453             Some(unsafe { OwnedFd::from_raw_fd(fence) })
454         };
455         status_result(status)?;
456         Ok(fence)
457     }
458 }
459 
460 impl Drop for HardwareBuffer {
drop(&mut self)461     fn drop(&mut self) {
462         // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
463         // because it must have been allocated by `AHardwareBuffer_allocate`,
464         // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
465         // released it.
466         unsafe { ffi::AHardwareBuffer_release(self.0.as_ptr()) }
467     }
468 }
469 
470 impl Debug for HardwareBuffer {
fmt(&self, f: &mut Formatter) -> fmt::Result471     fn fmt(&self, f: &mut Formatter) -> fmt::Result {
472         f.debug_struct("HardwareBuffer").field("id", &self.id()).finish()
473     }
474 }
475 
476 impl Clone for HardwareBuffer {
clone(&self) -> Self477     fn clone(&self) -> Self {
478         // SAFETY: ptr is guaranteed to be non-null and the acquire can not fail.
479         unsafe { ffi::AHardwareBuffer_acquire(self.0.as_ptr()) };
480         Self(self.0)
481     }
482 }
483 
484 impl UnstructuredParcelable for HardwareBuffer {
write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode>485     fn write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
486         let status =
487         // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
488         // because it must have been allocated by `AHardwareBuffer_allocate`,
489         // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
490         // released it.
491             unsafe { AHardwareBuffer_writeToParcel(self.0.as_ptr(), parcel.as_native_mut()) };
492         status_result(status)
493     }
494 
from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode>495     fn from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode> {
496         let mut buffer = null_mut();
497 
498         let status =
499         // SAFETY: Both pointers must be valid because they are obtained from references.
500         // `AHardwareBuffer_readFromParcel` doesn't store them or do anything else special
501         // with them. If it returns success then it will have allocated a new
502         // `AHardwareBuffer` and incremented the reference count, so we can use it until we
503         // release it.
504             unsafe { AHardwareBuffer_readFromParcel(parcel.as_native(), &mut buffer) };
505 
506         status_result(status)?;
507 
508         Ok(Self(
509             NonNull::new(buffer).expect(
510                 "AHardwareBuffer_readFromParcel returned success but didn't allocate buffer",
511             ),
512         ))
513     }
514 }
515 
516 impl_deserialize_for_unstructured_parcelable!(HardwareBuffer);
517 impl_serialize_for_unstructured_parcelable!(HardwareBuffer);
518 
519 // SAFETY: The underlying *AHardwareBuffers can be moved between threads.
520 unsafe impl Send for HardwareBuffer {}
521 
522 // SAFETY: The underlying *AHardwareBuffers can be used from multiple threads.
523 //
524 // AHardwareBuffers are backed by C++ GraphicBuffers, which are mostly immutable. The only cases
525 // where they are not immutable are:
526 //
527 //   - reallocation (which is never actually done across the codebase and requires special
528 //     privileges/platform code access to do)
529 //   - "locking" for reading/writing (which is explicitly allowed to be done across multiple threads
530 //     according to the docs on the underlying gralloc calls)
531 unsafe impl Sync for HardwareBuffer {}
532 
533 /// A guard for when a `HardwareBuffer` is locked.
534 ///
535 /// The `HardwareBuffer` will be unlocked when this is dropped, or may be unlocked via
536 /// [`HardwareBuffer::unlock_with_fence`].
537 #[derive(Debug)]
538 pub struct HardwareBufferGuard<'a> {
539     buffer: &'a HardwareBuffer,
540     /// The address of the buffer in memory.
541     pub address: NonNull<c_void>,
542 }
543 
544 impl<'a> Drop for HardwareBufferGuard<'a> {
drop(&mut self)545     fn drop(&mut self) {
546         self.buffer
547             .unlock()
548             .expect("Failed to unlock HardwareBuffer when dropping HardwareBufferGuard");
549     }
550 }
551 
552 /// A guard for when a `HardwareBuffer` is locked, with additional information about the number of
553 /// bytes per pixel and stride.
554 #[derive(Debug)]
555 pub struct LockedBufferInfo<'a> {
556     /// The locked buffer guard.
557     pub guard: HardwareBufferGuard<'a>,
558     /// The number of bytes used for each pixel in the buffer.
559     pub bytes_per_pixel: u32,
560     /// The stride in bytes between rows in the buffer.
561     pub stride: u32,
562 }
563 
564 /// A guard for a single plane of a locked `HardwareBuffer`, with additional information about the
565 /// stride.
566 #[derive(Debug)]
567 pub struct PlaneGuard<'a> {
568     /// The locked buffer guard.
569     pub guard: HardwareBufferGuard<'a>,
570     /// The stride in bytes between the color channel for one pixel to the next pixel.
571     pub pixel_stride: u32,
572     /// The stride in bytes between rows in the buffer.
573     pub row_stride: u32,
574 }
575 
576 #[cfg(test)]
577 mod test {
578     use super::*;
579 
580     #[test]
create_valid_buffer_returns_ok()581     fn create_valid_buffer_returns_ok() {
582         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
583             512,
584             512,
585             1,
586             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
587             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
588             0,
589         ));
590         assert!(buffer.is_some());
591     }
592 
593     #[test]
create_invalid_buffer_returns_err()594     fn create_invalid_buffer_returns_err() {
595         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
596             512,
597             512,
598             1,
599             0,
600             AHardwareBuffer_UsageFlags(0),
601             0,
602         ));
603         assert!(buffer.is_none());
604     }
605 
606     #[test]
from_raw_allows_getters()607     fn from_raw_allows_getters() {
608         let buffer_desc = ffi::AHardwareBuffer_Desc {
609             width: 1024,
610             height: 512,
611             layers: 1,
612             format: AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
613             usage: AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN.0,
614             stride: 0,
615             rfu0: 0,
616             rfu1: 0,
617         };
618         let mut raw_buffer_ptr = ptr::null_mut();
619 
620         // SAFETY: The pointers are valid because they come from references, and
621         // `AHardwareBuffer_allocate` doesn't retain them after it returns.
622         let status = unsafe { ffi::AHardwareBuffer_allocate(&buffer_desc, &mut raw_buffer_ptr) };
623         assert_eq!(status, 0);
624 
625         // SAFETY: The pointer must be valid because it was just allocated successfully, and we
626         // don't use it after calling this.
627         let buffer = unsafe { HardwareBuffer::from_raw(NonNull::new(raw_buffer_ptr).unwrap()) };
628         assert_eq!(buffer.description().width(), 1024);
629     }
630 
631     #[test]
basic_getters()632     fn basic_getters() {
633         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
634             1024,
635             512,
636             1,
637             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
638             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
639             0,
640         ))
641         .expect("Buffer with some basic parameters was not created successfully");
642 
643         let description = buffer.description();
644         assert_eq!(description.width(), 1024);
645         assert_eq!(description.height(), 512);
646         assert_eq!(description.layers(), 1);
647         assert_eq!(
648             description.format(),
649             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM
650         );
651         assert_eq!(
652             description.usage(),
653             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN
654         );
655     }
656 
657     #[test]
id_getter()658     fn id_getter() {
659         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
660             1024,
661             512,
662             1,
663             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
664             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
665             0,
666         ))
667         .expect("Buffer with some basic parameters was not created successfully");
668 
669         assert_ne!(0, buffer.id());
670     }
671 
672     #[test]
clone()673     fn clone() {
674         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
675             1024,
676             512,
677             1,
678             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
679             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
680             0,
681         ))
682         .expect("Buffer with some basic parameters was not created successfully");
683         let buffer2 = buffer.clone();
684 
685         assert_eq!(buffer, buffer2);
686     }
687 
688     #[test]
into_raw()689     fn into_raw() {
690         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
691             1024,
692             512,
693             1,
694             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
695             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
696             0,
697         ))
698         .expect("Buffer with some basic parameters was not created successfully");
699         let buffer2 = buffer.clone();
700 
701         let raw_buffer = buffer.into_raw();
702         // SAFETY: This is the same pointer we had before.
703         let remade_buffer = unsafe { HardwareBuffer::from_raw(raw_buffer) };
704 
705         assert_eq!(remade_buffer, buffer2);
706     }
707 
708     #[test]
native_handle_and_back()709     fn native_handle_and_back() {
710         let buffer_description = HardwareBufferDescription::new(
711             1024,
712             512,
713             1,
714             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
715             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
716             1024,
717         );
718         let buffer = HardwareBuffer::new(&buffer_description)
719             .expect("Buffer with some basic parameters was not created successfully");
720 
721         let native_handle =
722             buffer.cloned_native_handle().expect("Failed to get native handle for buffer");
723         let buffer2 = HardwareBuffer::create_from_handle(&native_handle, &buffer_description)
724             .expect("Failed to create buffer from native handle");
725 
726         assert_eq!(buffer.description(), buffer_description);
727         assert_eq!(buffer2.description(), buffer_description);
728     }
729 
730     #[test]
lock()731     fn lock() {
732         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
733             1024,
734             512,
735             1,
736             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
737             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
738             0,
739         ))
740         .expect("Failed to create buffer");
741 
742         // SAFETY: No other threads or processes have access to the buffer.
743         let guard = unsafe {
744             buffer.lock(
745                 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
746                 None,
747                 None,
748             )
749         }
750         .unwrap();
751 
752         drop(guard);
753     }
754 
755     #[test]
lock_with_rect()756     fn lock_with_rect() {
757         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
758             1024,
759             512,
760             1,
761             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
762             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
763             0,
764         ))
765         .expect("Failed to create buffer");
766         let rect = ARect { left: 10, right: 20, top: 35, bottom: 45 };
767 
768         // SAFETY: No other threads or processes have access to the buffer.
769         let guard = unsafe {
770             buffer.lock(
771                 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
772                 None,
773                 Some(&rect),
774             )
775         }
776         .unwrap();
777 
778         drop(guard);
779     }
780 
781     #[test]
unlock_with_fence()782     fn unlock_with_fence() {
783         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
784             1024,
785             512,
786             1,
787             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
788             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
789             0,
790         ))
791         .expect("Failed to create buffer");
792 
793         // SAFETY: No other threads or processes have access to the buffer.
794         let guard = unsafe {
795             buffer.lock(
796                 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
797                 None,
798                 None,
799             )
800         }
801         .unwrap();
802 
803         buffer.unlock_with_fence(guard).unwrap();
804     }
805 
806     #[test]
lock_with_info()807     fn lock_with_info() {
808         const WIDTH: u32 = 1024;
809         let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
810             WIDTH,
811             512,
812             1,
813             AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
814             AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
815             0,
816         ))
817         .expect("Failed to create buffer");
818 
819         // SAFETY: No other threads or processes have access to the buffer.
820         let info = unsafe {
821             buffer.lock_and_get_info(
822                 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
823                 None,
824                 None,
825             )
826         }
827         .unwrap();
828 
829         assert_eq!(info.bytes_per_pixel, 4);
830         assert_eq!(info.stride, WIDTH * 4);
831         drop(info);
832     }
833 }
834