nihed-cros-libva: allow opening display without the debug information being printed
authorKostya Shishkov <kostya.shishkov@gmail.com>
Fri, 20 Oct 2023 16:33:27 +0000 (18:33 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Fri, 20 Oct 2023 16:33:27 +0000 (18:33 +0200)
nihed-cros-libva/src/display.rs

index 171a73347b491102316ea64b25ae10f6c2abac3e..7cff18fa3ab6ab80fa182e669f04a3f3abc2eb6d 100644 (file)
@@ -56,6 +56,10 @@ impl Iterator for DrmDeviceIterator {
     }
 }
 
+unsafe extern "C" fn null_msg_cb(_ctx: *mut std::ffi::c_void, _message: *const std::ffi::c_char) {
+//    let msg = CStr::from_ptr(message).to_string_lossy();
+}
+
 /// A VADisplay opened over DRM.
 ///
 /// A Display is the starting point to using libva. This struct is essentially a safe wrapper over
@@ -78,6 +82,9 @@ impl Display {
     ///
     /// `path` is the path to a DRM device that supports VAAPI, e.g. `/dev/dri/renderD128`.
     pub fn open_drm_display<P: AsRef<Path>>(path: P) -> VAResult<Rc<Self>> {
+        Self::open_drm_display_internal(path, false)
+    }
+    fn open_drm_display_internal<P: AsRef<Path>>(path: P, silent: bool) -> VAResult<Rc<Self>> {
         let file = std::fs::File::options()
             .read(true)
             .write(true)
@@ -92,12 +99,26 @@ impl Display {
             return Err(VAError::InvalidDisplay);
         }
 
+        if silent {
+            // Safe because we ensure that the display is valid (i.e not NULL) before call.
+            unsafe {
+                bindings::vaSetInfoCallback(display, Some(null_msg_cb), std::ptr::null_mut());
+            }
+        }
+
         let mut major = 0i32;
         let mut minor = 0i32;
         // Safe because we ensure that the display is valid (i.e not NULL) before calling
         // vaInitialize. The File will close the DRM fd on drop.
         (unsafe { bindings::vaInitialize(display, &mut major, &mut minor) }).check()?;
 
+        if silent {
+            // Safe because we ensure that the display is valid (i.e not NULL) before call.
+            unsafe {
+                bindings::vaSetInfoCallback(display, None, std::ptr::null_mut());
+            }
+        }
+
         Ok(Rc::new(Self {
             handle: display,
             drm_file: file,
@@ -121,6 +142,26 @@ impl Display {
         None
     }
 
+    /// Opens the first device that succeeds and returns its `Display`.
+    ///
+    /// The only difference from ordinary `open` is that it does not print debug information
+    /// about libva version and opened driver.
+    ///
+    /// If an error occurs on a given device, it is ignored and the next one is tried until one
+    /// succeeds or we reach the end of the iterator.
+    pub fn open_silently() -> Option<Rc<Self>> {
+        let devices = DrmDeviceIterator::default();
+
+        // Try all the DRM devices until one succeeds.
+        for device in devices {
+            if let Ok(display) = Self::open_drm_display_internal(device, true) {
+                return Some(display);
+            }
+        }
+
+        None
+    }
+
     /// Returns the handle of this display.
     pub(crate) fn handle(&self) -> bindings::VADisplay {
         self.handle