Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2b81220f authored by Treehugger Robot's avatar Treehugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add methods to convert between HardwareBuffer and native handle." into main am: 647864ac

parents 3a3e2849 647864ac
Loading
Loading
Loading
Loading
+74 −0
Original line number Diff line number Diff line
@@ -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
@@ -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);
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -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>