mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2024-11-25 05:03:05 +00:00
rutabaga: change how MinigbmDevice finds the render node
Let minigbm decide which randernode to use. In this case, we don't need `rendernode.rs` anymore, and don't have to keep `_fd` in struct `MinigbmDeviceInner`, `fd` can get by calling `gbm_bo_get_fd` BUG=b:265199561 TEST=./tools/presubmit TEST=emerge-board crosvm, and deploy to dut TEST=CQ Change-Id: I294d6f7f0dcdf075ac85671561dbeeb1eef8edd2 Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5038006 Commit-Queue: Dawn Han <dawnhan@google.com> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-by: Ryan Neph <ryanneph@google.com>
This commit is contained in:
parent
cdfa1f0a5c
commit
89ba72800c
4 changed files with 29 additions and 141 deletions
|
@ -13,6 +13,7 @@ use std::fs::File;
|
|||
use std::io::Error;
|
||||
use std::io::Seek;
|
||||
use std::io::SeekFrom;
|
||||
use std::os::fd::FromRawFd;
|
||||
use std::os::raw::c_char;
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -21,8 +22,6 @@ use crate::rutabaga_gralloc::gralloc::Gralloc;
|
|||
use crate::rutabaga_gralloc::gralloc::ImageAllocationInfo;
|
||||
use crate::rutabaga_gralloc::gralloc::ImageMemoryRequirements;
|
||||
use crate::rutabaga_gralloc::minigbm_bindings::*;
|
||||
use crate::rutabaga_gralloc::rendernode;
|
||||
use crate::rutabaga_os::AsRawDescriptor;
|
||||
use crate::rutabaga_os::FromRawDescriptor;
|
||||
use crate::rutabaga_utils::*;
|
||||
|
||||
|
@ -60,29 +59,37 @@ impl MinigbmDevice {
|
|||
/// Returns a new `MinigbmDevice` if there is a rendernode in `/dev/dri/` that is accepted by
|
||||
/// the minigbm library.
|
||||
pub fn init() -> RutabagaResult<Box<dyn Gralloc>> {
|
||||
let undesired: &[&str] = &["vgem", "pvr"];
|
||||
let fd = rendernode::open_device(undesired)?;
|
||||
|
||||
let descriptor: File;
|
||||
let device_name: &str;
|
||||
let gbm: *mut gbm_device;
|
||||
// SAFETY:
|
||||
// gbm_create_device is safe to call with a valid fd, and we check that a valid one is
|
||||
// returned. If the fd does not refer to a DRM device, gbm_create_device will reject it.
|
||||
let gbm = unsafe { gbm_create_device(fd.as_raw_descriptor()) };
|
||||
if gbm.is_null() {
|
||||
return Err(RutabagaError::IoError(Error::last_os_error()));
|
||||
// Safe because minigbm_create_default_device is safe to call with an unused fd,
|
||||
// and fd is guaranteed to be overwritten with a valid descriptor when a non-null
|
||||
// pointer is returned.
|
||||
unsafe {
|
||||
let mut fd = -1;
|
||||
|
||||
gbm = minigbm_create_default_device(&mut fd);
|
||||
if gbm.is_null() {
|
||||
return Err(RutabagaError::IoError(Error::last_os_error()));
|
||||
}
|
||||
descriptor = File::from_raw_fd(fd);
|
||||
}
|
||||
|
||||
// SAFETY:
|
||||
// Safe because a valid minigbm device has a statically allocated string associated with
|
||||
// it, which is valid for the lifetime of the process.
|
||||
let backend_name: *const c_char = unsafe { gbm_device_get_backend_name(gbm) };
|
||||
// SAFETY:
|
||||
// Safe because a valid minigbm device has a statically allocated string associated with
|
||||
// it, which is valid for the lifetime of the process.
|
||||
let c_str: &CStr = unsafe { CStr::from_ptr(backend_name) };
|
||||
let device_name: &str = c_str.to_str()?;
|
||||
// Safe because the string returned by gbm_device_get_backend_name() exists at least
|
||||
// as long as the associated gbm_device.
|
||||
unsafe {
|
||||
let backend_name: *const c_char = gbm_device_get_backend_name(gbm);
|
||||
let c_str: &CStr = CStr::from_ptr(backend_name);
|
||||
device_name = c_str.to_str()?;
|
||||
}
|
||||
|
||||
Ok(Box::new(MinigbmDevice {
|
||||
minigbm_device: Arc::new(MinigbmDeviceInner { _fd: fd, gbm }),
|
||||
minigbm_device: Arc::new(MinigbmDeviceInner {
|
||||
_fd: descriptor,
|
||||
gbm,
|
||||
}),
|
||||
last_buffer: None,
|
||||
device_name,
|
||||
}))
|
||||
|
|
|
@ -272,3 +272,6 @@ extern "C" {
|
|||
plane: c_int,
|
||||
) -> *mut c_void;
|
||||
}
|
||||
extern "C" {
|
||||
pub fn minigbm_create_default_device(out_fd: *mut c_int) -> *mut gbm_device;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ mod formats;
|
|||
mod gralloc;
|
||||
mod minigbm;
|
||||
mod minigbm_bindings;
|
||||
mod rendernode;
|
||||
mod system_gralloc;
|
||||
mod vulkano_gralloc;
|
||||
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
// Copyright 2018 The ChromiumOS Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#![cfg(feature = "minigbm")]
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::fs::File;
|
||||
use std::fs::OpenOptions;
|
||||
use std::os::raw::c_char;
|
||||
use std::os::raw::c_int;
|
||||
use std::os::raw::c_uint;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
use std::os::raw::c_ulong;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::path::Path;
|
||||
use std::ptr::null_mut;
|
||||
|
||||
use nix::ioctl_readwrite;
|
||||
|
||||
use crate::rutabaga_utils::RutabagaError;
|
||||
use crate::rutabaga_utils::RutabagaResult;
|
||||
|
||||
// Consistent with __kernel_size_t in include/uapi/asm-generic/posix_types.h.
|
||||
#[cfg(not(target_pointer_width = "64"))]
|
||||
#[allow(non_camel_case_types)]
|
||||
type __kernel_size_t = c_uint;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[allow(non_camel_case_types)]
|
||||
type __kernel_size_t = c_ulong;
|
||||
|
||||
const DRM_IOCTL_BASE: c_uint = 0x64;
|
||||
const DRM_IOCTL_VERSION: c_uint = 0x00;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct drm_version {
|
||||
version_major: c_int,
|
||||
version_minor: c_int,
|
||||
version_patchlevel: c_int,
|
||||
name_len: __kernel_size_t,
|
||||
name: *mut c_char,
|
||||
date_len: __kernel_size_t,
|
||||
date: *mut c_char,
|
||||
desc_len: __kernel_size_t,
|
||||
desc: *mut c_char,
|
||||
}
|
||||
|
||||
ioctl_readwrite!(
|
||||
drm_get_version,
|
||||
DRM_IOCTL_BASE,
|
||||
DRM_IOCTL_VERSION,
|
||||
drm_version
|
||||
);
|
||||
|
||||
fn get_drm_device_name(fd: &File) -> RutabagaResult<String> {
|
||||
let mut version = drm_version {
|
||||
version_major: 0,
|
||||
version_minor: 0,
|
||||
version_patchlevel: 0,
|
||||
name_len: 0,
|
||||
name: null_mut(),
|
||||
date_len: 0,
|
||||
date: null_mut(),
|
||||
desc_len: 0,
|
||||
desc: null_mut(),
|
||||
};
|
||||
|
||||
// TODO(b/315870313): Add safety comment
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
// Get the length of the device name.
|
||||
unsafe {
|
||||
drm_get_version(fd.as_raw_fd(), &mut version)?;
|
||||
}
|
||||
|
||||
// Enough bytes to hold the device name and terminating null character.
|
||||
let mut name_bytes: Vec<u8> = vec![0; (version.name_len + 1) as usize];
|
||||
let mut version = drm_version {
|
||||
version_major: 0,
|
||||
version_minor: 0,
|
||||
version_patchlevel: 0,
|
||||
name_len: name_bytes.len() as __kernel_size_t,
|
||||
name: name_bytes.as_mut_ptr() as *mut c_char,
|
||||
date_len: 0,
|
||||
date: null_mut(),
|
||||
desc_len: 0,
|
||||
desc: null_mut(),
|
||||
};
|
||||
|
||||
// SAFETY:
|
||||
// Safe as no more than name_len + 1 bytes will be written to name.
|
||||
unsafe {
|
||||
drm_get_version(fd.as_raw_fd(), &mut version)?;
|
||||
}
|
||||
|
||||
CString::new(&name_bytes[..(version.name_len as usize)])?
|
||||
.into_string()
|
||||
.map_err(|_| RutabagaError::SpecViolation("couldn't convert string"))
|
||||
}
|
||||
|
||||
/// Returns a `fd` for an opened rendernode device, while filtering out specified
|
||||
/// undesired drivers.
|
||||
pub fn open_device(undesired: &[&str]) -> RutabagaResult<File> {
|
||||
const DRM_DIR_NAME: &str = "/dev/dri";
|
||||
const DRM_MAX_MINOR: u32 = 15;
|
||||
const RENDER_NODE_START: u32 = 128;
|
||||
|
||||
for n in RENDER_NODE_START..=RENDER_NODE_START + DRM_MAX_MINOR {
|
||||
let path = Path::new(DRM_DIR_NAME).join(format!("renderD{}", n));
|
||||
|
||||
if let Ok(fd) = OpenOptions::new().read(true).write(true).open(path) {
|
||||
if let Ok(name) = get_drm_device_name(&fd) {
|
||||
if !undesired.iter().any(|item| *item == name) {
|
||||
return Ok(fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(RutabagaError::SpecViolation("no DRM rendernode opened"))
|
||||
}
|
Loading…
Reference in a new issue