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

Commit 647864ac authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Add methods to convert between HardwareBuffer and native handle." into main

parents b169c759 a73d62cd
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>