blob: 931c311e6530b790d5965afe6995e2321421d69f [file] [log] [blame]
Jim Shargo7df9f752023-07-18 20:33:45 +00001// 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
17extern crate nativewindow_bindgen as ffi;
18
Andrew Walbran9487efd2024-08-20 18:37:59 +010019mod handle;
Jiyong Park8032bff2024-04-01 16:17:15 +090020mod surface;
Andrew Walbran9487efd2024-08-20 18:37:59 +010021
22pub use handle::NativeHandle;
Jiyong Park8032bff2024-04-01 16:17:15 +090023pub use surface::Surface;
Andrew Walbran8ee0ef12024-01-12 15:56:14 +000024
Andrew Walbran43bddb62023-09-01 16:43:09 +010025pub use ffi::{AHardwareBuffer_Format, AHardwareBuffer_UsageFlags};
Jim Shargo7df9f752023-07-18 20:33:45 +000026
Andrew Walbran43bddb62023-09-01 16:43:09 +010027use binder::{
Andrew Walbrane9573af2024-01-11 16:34:16 +000028 binder_impl::{BorrowedParcel, UnstructuredParcelable},
29 impl_deserialize_for_unstructured_parcelable, impl_serialize_for_unstructured_parcelable,
Andrew Walbran43bddb62023-09-01 16:43:09 +010030 unstable_api::{status_result, AsNative},
31 StatusCode,
32};
Andrew Walbranabc932e2024-08-30 14:10:29 +010033use ffi::{
34 AHardwareBuffer, AHardwareBuffer_Desc, AHardwareBuffer_readFromParcel,
35 AHardwareBuffer_writeToParcel,
36};
Jim Shargob69c6ef2023-10-05 22:54:51 +000037use std::fmt::{self, Debug, Formatter};
38use std::mem::ManuallyDrop;
Andrew Walbran43bddb62023-09-01 16:43:09 +010039use std::ptr::{self, null_mut, NonNull};
Jim Shargo7df9f752023-07-18 20:33:45 +000040
Andrew Walbranabc932e2024-08-30 14:10:29 +010041/// Wrapper around a C `AHardwareBuffer_Desc`.
42#[derive(Clone, Debug, PartialEq, Eq)]
43pub struct HardwareBufferDescription(AHardwareBuffer_Desc);
44
45impl HardwareBufferDescription {
46 /// Creates a new `HardwareBufferDescription` with the given parameters.
47 pub fn new(
48 width: u32,
49 height: u32,
50 layers: u32,
51 format: AHardwareBuffer_Format::Type,
52 usage: AHardwareBuffer_UsageFlags,
53 stride: u32,
54 ) -> Self {
55 Self(AHardwareBuffer_Desc {
56 width,
57 height,
58 layers,
59 format,
60 usage: usage.0,
61 stride,
62 rfu0: 0,
63 rfu1: 0,
64 })
65 }
66
67 /// Returns the width from the buffer description.
68 pub fn width(&self) -> u32 {
69 self.0.width
70 }
71
72 /// Returns the height from the buffer description.
73 pub fn height(&self) -> u32 {
74 self.0.height
75 }
76
77 /// Returns the number from layers from the buffer description.
78 pub fn layers(&self) -> u32 {
79 self.0.layers
80 }
81
82 /// Returns the format from the buffer description.
83 pub fn format(&self) -> AHardwareBuffer_Format::Type {
84 self.0.format
85 }
86
87 /// Returns the usage bitvector from the buffer description.
88 pub fn usage(&self) -> AHardwareBuffer_UsageFlags {
89 AHardwareBuffer_UsageFlags(self.0.usage)
90 }
91
92 /// Returns the stride from the buffer description.
93 pub fn stride(&self) -> u32 {
94 self.0.stride
95 }
96}
97
98impl Default for HardwareBufferDescription {
99 fn default() -> Self {
100 Self(AHardwareBuffer_Desc {
101 width: 0,
102 height: 0,
103 layers: 0,
104 format: 0,
105 usage: 0,
106 stride: 0,
107 rfu0: 0,
108 rfu1: 0,
109 })
110 }
111}
112
Andrew Walbran43bddb62023-09-01 16:43:09 +0100113/// Wrapper around an opaque C `AHardwareBuffer`.
Jim Shargob69c6ef2023-10-05 22:54:51 +0000114#[derive(PartialEq, Eq)]
115pub struct HardwareBuffer(NonNull<AHardwareBuffer>);
Jim Shargo7df9f752023-07-18 20:33:45 +0000116
Jim Shargob69c6ef2023-10-05 22:54:51 +0000117impl HardwareBuffer {
Jim Shargo7df9f752023-07-18 20:33:45 +0000118 /// Test whether the given format and usage flag combination is allocatable. If this function
119 /// returns true, it means that a buffer with the given description can be allocated on this
120 /// implementation, unless resource exhaustion occurs. If this function returns false, it means
121 /// that the allocation of the given description will never succeed.
122 ///
123 /// Available since API 29
Andrew Walbranabc932e2024-08-30 14:10:29 +0100124 pub fn is_supported(buffer_description: &HardwareBufferDescription) -> bool {
125 // SAFETY: The pointer comes from a reference so must be valid.
126 let status = unsafe { ffi::AHardwareBuffer_isSupported(&buffer_description.0) };
Jim Shargo7df9f752023-07-18 20:33:45 +0000127
128 status == 1
129 }
130
131 /// Allocates a buffer that matches the passed AHardwareBuffer_Desc. If allocation succeeds, the
132 /// buffer can be used according to the usage flags specified in its description. If a buffer is
133 /// used in ways not compatible with its usage flags, the results are undefined and may include
134 /// program termination.
135 ///
136 /// Available since API level 26.
Jim Shargoe4680d72023-08-07 16:46:45 +0000137 #[inline]
Andrew Walbranabc932e2024-08-30 14:10:29 +0100138 pub fn new(buffer_description: &HardwareBufferDescription) -> Option<Self> {
Jim Shargob69c6ef2023-10-05 22:54:51 +0000139 let mut ptr = ptr::null_mut();
Jim Shargo7df9f752023-07-18 20:33:45 +0000140 // SAFETY: The returned pointer is valid until we drop/deallocate it. The function may fail
141 // and return a status, but we check it later.
Andrew Walbranabc932e2024-08-30 14:10:29 +0100142 let status = unsafe { ffi::AHardwareBuffer_allocate(&buffer_description.0, &mut ptr) };
Jim Shargo7df9f752023-07-18 20:33:45 +0000143
144 if status == 0 {
Jim Shargob69c6ef2023-10-05 22:54:51 +0000145 Some(Self(NonNull::new(ptr).expect("Allocated AHardwareBuffer was null")))
Jim Shargo7df9f752023-07-18 20:33:45 +0000146 } else {
147 None
148 }
149 }
150
Andrew Walbrana73d62c2024-08-20 17:20:56 +0100151 /// Creates a `HardwareBuffer` from a native handle.
152 ///
153 /// The native handle is cloned, so this doesn't take ownership of the original handle passed
154 /// in.
155 pub fn create_from_handle(
156 handle: &NativeHandle,
Andrew Walbranabc932e2024-08-30 14:10:29 +0100157 buffer_description: &HardwareBufferDescription,
Andrew Walbrana73d62c2024-08-20 17:20:56 +0100158 ) -> Result<Self, StatusCode> {
159 let mut buffer = ptr::null_mut();
160 // SAFETY: The caller guarantees that `handle` is valid, and the buffer pointer is valid
161 // because it comes from a reference. The method we pass means that
162 // `AHardwareBuffer_createFromHandle` will clone the handle rather than taking ownership of
163 // it.
164 let status = unsafe {
165 ffi::AHardwareBuffer_createFromHandle(
Andrew Walbranabc932e2024-08-30 14:10:29 +0100166 &buffer_description.0,
Andrew Walbrana73d62c2024-08-20 17:20:56 +0100167 handle.as_raw().as_ptr(),
168 ffi::CreateFromHandleMethod_AHARDWAREBUFFER_CREATE_FROM_HANDLE_METHOD_CLONE
169 .try_into()
170 .unwrap(),
171 &mut buffer,
172 )
173 };
174 status_result(status)?;
175 Ok(Self(NonNull::new(buffer).expect("Allocated AHardwareBuffer was null")))
176 }
177
178 /// Returns a clone of the native handle of the buffer.
179 ///
180 /// Returns `None` if the operation fails for any reason.
181 pub fn cloned_native_handle(&self) -> Option<NativeHandle> {
182 // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
183 // because it must have been allocated by `AHardwareBuffer_allocate`,
184 // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
185 // released it.
186 let native_handle = unsafe { ffi::AHardwareBuffer_getNativeHandle(self.0.as_ptr()) };
187 NonNull::new(native_handle.cast_mut()).and_then(|native_handle| {
188 // SAFETY: `AHardwareBuffer_getNativeHandle` should have returned a valid pointer which
189 // is valid at least as long as the buffer is, and `clone_from_raw` clones it rather
190 // than taking ownership of it so the original `native_handle` isn't stored.
191 unsafe { NativeHandle::clone_from_raw(native_handle) }
192 })
193 }
194
Andrew Walbrana0b3a9d2024-01-12 16:43:12 +0000195 /// Adopts the given raw pointer and wraps it in a Rust HardwareBuffer.
Jim Shargo7df9f752023-07-18 20:33:45 +0000196 ///
197 /// # Safety
198 ///
Andrew Walbrana0b3a9d2024-01-12 16:43:12 +0000199 /// This function takes ownership of the pointer and does NOT increment the refcount on the
200 /// buffer. If the caller uses the pointer after the created object is dropped it will cause
201 /// undefined behaviour. If the caller wants to continue using the pointer after calling this
202 /// then use [`clone_from_raw`](Self::clone_from_raw) instead.
Jim Shargob69c6ef2023-10-05 22:54:51 +0000203 pub unsafe fn from_raw(buffer_ptr: NonNull<AHardwareBuffer>) -> Self {
204 Self(buffer_ptr)
205 }
206
Andrew Walbrana0b3a9d2024-01-12 16:43:12 +0000207 /// Creates a new Rust HardwareBuffer to wrap the given AHardwareBuffer without taking ownership
208 /// of it.
209 ///
210 /// Unlike [`from_raw`](Self::from_raw) this method will increment the refcount on the buffer.
211 /// This means that the caller can continue to use the raw buffer it passed in, and must call
212 /// [`AHardwareBuffer_release`](ffi::AHardwareBuffer_release) when it is finished with it to
213 /// avoid a memory leak.
214 ///
215 /// # Safety
216 ///
217 /// The buffer pointer must point to a valid `AHardwareBuffer`.
218 pub unsafe fn clone_from_raw(buffer: NonNull<AHardwareBuffer>) -> Self {
219 // SAFETY: The caller guarantees that the AHardwareBuffer pointer is valid.
220 unsafe { ffi::AHardwareBuffer_acquire(buffer.as_ptr()) };
221 Self(buffer)
222 }
223
Jim Shargob69c6ef2023-10-05 22:54:51 +0000224 /// Get the internal |AHardwareBuffer| pointer without decrementing the refcount. This can
225 /// be used to provide a pointer to the AHB for a C/C++ API over the FFI.
226 pub fn into_raw(self) -> NonNull<AHardwareBuffer> {
227 let buffer = ManuallyDrop::new(self);
228 buffer.0
Jim Shargo7df9f752023-07-18 20:33:45 +0000229 }
230
231 /// Get the system wide unique id for an AHardwareBuffer. This function may panic in extreme
232 /// and undocumented circumstances.
233 ///
234 /// Available since API level 31.
235 pub fn id(&self) -> u64 {
236 let mut out_id = 0;
Andrew Walbran43bddb62023-09-01 16:43:09 +0100237 // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
238 // because it must have been allocated by `AHardwareBuffer_allocate`,
239 // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
240 // released it. The id pointer must be valid because it comes from a reference.
241 let status = unsafe { ffi::AHardwareBuffer_getId(self.0.as_ptr(), &mut out_id) };
Jim Shargo7df9f752023-07-18 20:33:45 +0000242 assert_eq!(status, 0, "id() failed for AHardwareBuffer with error code: {status}");
243
244 out_id
245 }
246
Andrew Walbranabc932e2024-08-30 14:10:29 +0100247 /// Returns the description of this buffer.
248 pub fn description(&self) -> HardwareBufferDescription {
Jim Shargo7df9f752023-07-18 20:33:45 +0000249 let mut buffer_desc = ffi::AHardwareBuffer_Desc {
250 width: 0,
251 height: 0,
252 layers: 0,
253 format: 0,
254 usage: 0,
255 stride: 0,
256 rfu0: 0,
257 rfu1: 0,
258 };
259 // SAFETY: neither the buffer nor AHardwareBuffer_Desc pointers will be null.
Jim Shargob69c6ef2023-10-05 22:54:51 +0000260 unsafe { ffi::AHardwareBuffer_describe(self.0.as_ref(), &mut buffer_desc) };
Andrew Walbranabc932e2024-08-30 14:10:29 +0100261 HardwareBufferDescription(buffer_desc)
Jim Shargo7df9f752023-07-18 20:33:45 +0000262 }
263}
264
Jim Shargob69c6ef2023-10-05 22:54:51 +0000265impl Drop for HardwareBuffer {
Jim Shargo7df9f752023-07-18 20:33:45 +0000266 fn drop(&mut self) {
Andrew Walbran43bddb62023-09-01 16:43:09 +0100267 // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
268 // because it must have been allocated by `AHardwareBuffer_allocate`,
269 // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
270 // released it.
Jim Shargob69c6ef2023-10-05 22:54:51 +0000271 unsafe { ffi::AHardwareBuffer_release(self.0.as_ptr()) }
Jim Shargo7df9f752023-07-18 20:33:45 +0000272 }
273}
274
Jim Shargob69c6ef2023-10-05 22:54:51 +0000275impl Debug for HardwareBuffer {
Andrew Walbran8ee0ef12024-01-12 15:56:14 +0000276 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
Jim Shargob69c6ef2023-10-05 22:54:51 +0000277 f.debug_struct("HardwareBuffer").field("id", &self.id()).finish()
278 }
279}
280
281impl Clone for HardwareBuffer {
282 fn clone(&self) -> Self {
283 // SAFETY: ptr is guaranteed to be non-null and the acquire can not fail.
284 unsafe { ffi::AHardwareBuffer_acquire(self.0.as_ptr()) };
285 Self(self.0)
286 }
287}
288
Andrew Walbrane9573af2024-01-11 16:34:16 +0000289impl UnstructuredParcelable for HardwareBuffer {
290 fn write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
291 let status =
292 // SAFETY: The AHardwareBuffer pointer we pass is guaranteed to be non-null and valid
293 // because it must have been allocated by `AHardwareBuffer_allocate`,
294 // `AHardwareBuffer_readFromParcel` or the caller of `from_raw` and we have not yet
295 // released it.
296 unsafe { AHardwareBuffer_writeToParcel(self.0.as_ptr(), parcel.as_native_mut()) };
297 status_result(status)
298 }
299
300 fn from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode> {
301 let mut buffer = null_mut();
302
303 let status =
304 // SAFETY: Both pointers must be valid because they are obtained from references.
305 // `AHardwareBuffer_readFromParcel` doesn't store them or do anything else special
306 // with them. If it returns success then it will have allocated a new
307 // `AHardwareBuffer` and incremented the reference count, so we can use it until we
308 // release it.
309 unsafe { AHardwareBuffer_readFromParcel(parcel.as_native(), &mut buffer) };
310
311 status_result(status)?;
312
313 Ok(Self(
314 NonNull::new(buffer).expect(
315 "AHardwareBuffer_readFromParcel returned success but didn't allocate buffer",
316 ),
317 ))
Andrew Walbran43bddb62023-09-01 16:43:09 +0100318 }
319}
320
Andrew Walbrane9573af2024-01-11 16:34:16 +0000321impl_deserialize_for_unstructured_parcelable!(HardwareBuffer);
322impl_serialize_for_unstructured_parcelable!(HardwareBuffer);
Andrew Walbran43bddb62023-09-01 16:43:09 +0100323
Jim Shargob69c6ef2023-10-05 22:54:51 +0000324// SAFETY: The underlying *AHardwareBuffers can be moved between threads.
325unsafe impl Send for HardwareBuffer {}
326
327// SAFETY: The underlying *AHardwareBuffers can be used from multiple threads.
328//
329// AHardwareBuffers are backed by C++ GraphicBuffers, which are mostly immutable. The only cases
330// where they are not immutable are:
331//
332// - reallocation (which is never actually done across the codebase and requires special
333// privileges/platform code access to do)
334// - "locking" for reading/writing (which is explicitly allowed to be done across multiple threads
335// according to the docs on the underlying gralloc calls)
336unsafe impl Sync for HardwareBuffer {}
337
Jim Shargo7df9f752023-07-18 20:33:45 +0000338#[cfg(test)]
Jim Shargob69c6ef2023-10-05 22:54:51 +0000339mod test {
Jim Shargo7df9f752023-07-18 20:33:45 +0000340 use super::*;
341
342 #[test]
343 fn create_valid_buffer_returns_ok() {
Andrew Walbranabc932e2024-08-30 14:10:29 +0100344 let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
Jim Shargo7df9f752023-07-18 20:33:45 +0000345 512,
346 512,
347 1,
348 AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
349 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
Andrew Walbranabc932e2024-08-30 14:10:29 +0100350 0,
351 ));
Jim Shargo7df9f752023-07-18 20:33:45 +0000352 assert!(buffer.is_some());
353 }
354
355 #[test]
356 fn create_invalid_buffer_returns_err() {
Andrew Walbranabc932e2024-08-30 14:10:29 +0100357 let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
358 512,
359 512,
360 1,
361 0,
362 AHardwareBuffer_UsageFlags(0),
363 0,
364 ));
Jim Shargo7df9f752023-07-18 20:33:45 +0000365 assert!(buffer.is_none());
366 }
367
368 #[test]
Jim Shargob69c6ef2023-10-05 22:54:51 +0000369 fn from_raw_allows_getters() {
Jim Shargo7df9f752023-07-18 20:33:45 +0000370 let buffer_desc = ffi::AHardwareBuffer_Desc {
371 width: 1024,
372 height: 512,
373 layers: 1,
374 format: AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
375 usage: AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN.0,
376 stride: 0,
377 rfu0: 0,
378 rfu1: 0,
379 };
380 let mut raw_buffer_ptr = ptr::null_mut();
381
Andrew Walbran03350bc2023-08-03 16:02:51 +0000382 // SAFETY: The pointers are valid because they come from references, and
383 // `AHardwareBuffer_allocate` doesn't retain them after it returns.
Jim Shargo7df9f752023-07-18 20:33:45 +0000384 let status = unsafe { ffi::AHardwareBuffer_allocate(&buffer_desc, &mut raw_buffer_ptr) };
385 assert_eq!(status, 0);
386
Andrew Walbran03350bc2023-08-03 16:02:51 +0000387 // SAFETY: The pointer must be valid because it was just allocated successfully, and we
388 // don't use it after calling this.
Jim Shargob69c6ef2023-10-05 22:54:51 +0000389 let buffer = unsafe { HardwareBuffer::from_raw(NonNull::new(raw_buffer_ptr).unwrap()) };
Andrew Walbranabc932e2024-08-30 14:10:29 +0100390 assert_eq!(buffer.description().width(), 1024);
Jim Shargo7df9f752023-07-18 20:33:45 +0000391 }
392
393 #[test]
394 fn basic_getters() {
Andrew Walbranabc932e2024-08-30 14:10:29 +0100395 let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
Jim Shargo7df9f752023-07-18 20:33:45 +0000396 1024,
397 512,
398 1,
399 AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
400 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
Andrew Walbranabc932e2024-08-30 14:10:29 +0100401 0,
402 ))
Jim Shargo7df9f752023-07-18 20:33:45 +0000403 .expect("Buffer with some basic parameters was not created successfully");
404
Andrew Walbranabc932e2024-08-30 14:10:29 +0100405 let description = buffer.description();
406 assert_eq!(description.width(), 1024);
407 assert_eq!(description.height(), 512);
408 assert_eq!(description.layers(), 1);
Jim Shargo7df9f752023-07-18 20:33:45 +0000409 assert_eq!(
Andrew Walbranabc932e2024-08-30 14:10:29 +0100410 description.format(),
411 AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM
412 );
413 assert_eq!(
414 description.usage(),
Jim Shargo7df9f752023-07-18 20:33:45 +0000415 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN
416 );
417 }
418
419 #[test]
420 fn id_getter() {
Andrew Walbranabc932e2024-08-30 14:10:29 +0100421 let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
Jim Shargo7df9f752023-07-18 20:33:45 +0000422 1024,
423 512,
424 1,
425 AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
426 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
Andrew Walbranabc932e2024-08-30 14:10:29 +0100427 0,
428 ))
Jim Shargo7df9f752023-07-18 20:33:45 +0000429 .expect("Buffer with some basic parameters was not created successfully");
430
431 assert_ne!(0, buffer.id());
432 }
Jim Shargob69c6ef2023-10-05 22:54:51 +0000433
434 #[test]
435 fn clone() {
Andrew Walbranabc932e2024-08-30 14:10:29 +0100436 let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
Jim Shargob69c6ef2023-10-05 22:54:51 +0000437 1024,
438 512,
439 1,
440 AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
441 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
Andrew Walbranabc932e2024-08-30 14:10:29 +0100442 0,
443 ))
Jim Shargob69c6ef2023-10-05 22:54:51 +0000444 .expect("Buffer with some basic parameters was not created successfully");
445 let buffer2 = buffer.clone();
446
447 assert_eq!(buffer, buffer2);
448 }
449
450 #[test]
451 fn into_raw() {
Andrew Walbranabc932e2024-08-30 14:10:29 +0100452 let buffer = HardwareBuffer::new(&HardwareBufferDescription::new(
Jim Shargob69c6ef2023-10-05 22:54:51 +0000453 1024,
454 512,
455 1,
456 AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
457 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
Andrew Walbranabc932e2024-08-30 14:10:29 +0100458 0,
459 ))
Jim Shargob69c6ef2023-10-05 22:54:51 +0000460 .expect("Buffer with some basic parameters was not created successfully");
461 let buffer2 = buffer.clone();
462
463 let raw_buffer = buffer.into_raw();
464 // SAFETY: This is the same pointer we had before.
465 let remade_buffer = unsafe { HardwareBuffer::from_raw(raw_buffer) };
466
467 assert_eq!(remade_buffer, buffer2);
468 }
Andrew Walbrana73d62c2024-08-20 17:20:56 +0100469
470 #[test]
471 fn native_handle_and_back() {
Andrew Walbranabc932e2024-08-30 14:10:29 +0100472 let buffer_description = HardwareBufferDescription::new(
Andrew Walbrana73d62c2024-08-20 17:20:56 +0100473 1024,
474 512,
475 1,
476 AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM,
477 AHardwareBuffer_UsageFlags::AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN,
Andrew Walbranabc932e2024-08-30 14:10:29 +0100478 1024,
479 );
480 let buffer = HardwareBuffer::new(&buffer_description)
481 .expect("Buffer with some basic parameters was not created successfully");
Andrew Walbrana73d62c2024-08-20 17:20:56 +0100482
483 let native_handle =
484 buffer.cloned_native_handle().expect("Failed to get native handle for buffer");
Andrew Walbranabc932e2024-08-30 14:10:29 +0100485 let buffer2 = HardwareBuffer::create_from_handle(&native_handle, &buffer_description)
Andrew Walbrana73d62c2024-08-20 17:20:56 +0100486 .expect("Failed to create buffer from native handle");
487
Andrew Walbranabc932e2024-08-30 14:10:29 +0100488 assert_eq!(buffer.description(), buffer_description);
489 assert_eq!(buffer2.description(), buffer_description);
Andrew Walbrana73d62c2024-08-20 17:20:56 +0100490 }
Jim Shargo7df9f752023-07-18 20:33:45 +0000491}