drm: Add error for multi-use of a single crtc

This commit is contained in:
Drakulix 2017-09-14 18:47:19 +02:00
parent f2bff6172b
commit 7bf4105050
3 changed files with 54 additions and 3 deletions

View File

@ -196,6 +196,10 @@ impl DrmBackendInternal {
}) })
}); });
} }
pub(crate) fn is_crtc(&self, crtc: crtc::Handle) -> bool {
crtc == self.crtc
}
} }
impl DrmBackend { impl DrmBackend {

View File

@ -23,6 +23,8 @@ pub enum Error {
Io(IoError), Io(IoError),
/// Selected an invalid Mode /// Selected an invalid Mode
Mode(ModeError), Mode(ModeError),
/// Error related to the selected crtc
Crtc(CrtcError),
} }
impl fmt::Display for Error { impl fmt::Display for Error {
@ -37,6 +39,7 @@ impl fmt::Display for Error {
&Error::Gbm(ref x) => x as &error::Error, &Error::Gbm(ref x) => x as &error::Error,
&Error::Io(ref x) => x as &error::Error, &Error::Io(ref x) => x as &error::Error,
&Error::Mode(ref x) => x as &error::Error, &Error::Mode(ref x) => x as &error::Error,
&Error::Crtc(ref x) => x as &error::Error,
} }
) )
} }
@ -55,6 +58,7 @@ impl error::Error for Error {
&Error::Gbm(ref x) => Some(x as &error::Error), &Error::Gbm(ref x) => Some(x as &error::Error),
&Error::Io(ref x) => Some(x as &error::Error), &Error::Io(ref x) => Some(x as &error::Error),
&Error::Mode(ref x) => Some(x as &error::Error), &Error::Mode(ref x) => Some(x as &error::Error),
&Error::Crtc(ref x) => Some(x as &error::Error),
} }
} }
} }
@ -98,6 +102,12 @@ impl From<ModeError> for Error {
} }
} }
impl From<CrtcError> for Error {
fn from(err: CrtcError) -> Error {
Error::Crtc(err)
}
}
impl<H> From<TryNewError<Error, H>> for Error { impl<H> From<TryNewError<Error, H>> for Error {
fn from(err: TryNewError<Error, H>) -> Error { fn from(err: TryNewError<Error, H>) -> Error {
err.0 err.0
@ -138,3 +148,34 @@ impl error::Error for ModeError {
} }
} }
} }
/// Errors related to the selected crtc
#[derive(Debug)]
pub enum CrtcError {
/// Selected crtc is already in use by another `DrmBackend`
AlreadyInUse
}
impl fmt::Display for CrtcError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description())?;
if let Some(cause) = self.cause() {
write!(f, "\tCause: {}", cause)?;
}
Ok(())
}
}
impl error::Error for CrtcError {
fn description(&self) -> &str {
match self {
&CrtcError::AlreadyInUse => "Crtc is already in use by another DrmBackend",
}
}
fn cause(&self) -> Option<&error::Error> {
match self {
_ => None,
}
}
}

View File

@ -164,7 +164,7 @@ mod error;
pub use self::backend::{DrmBackend, Id}; pub use self::backend::{DrmBackend, Id};
use self::backend::DrmBackendInternal; use self::backend::DrmBackendInternal;
pub use self::error::{Error as DrmError, ModeError}; pub use self::error::{Error as DrmError, ModeError, CrtcError};
/// Internal struct as required by the drm crate /// Internal struct as required by the drm crate
#[derive(Debug)] #[derive(Debug)]
@ -349,12 +349,18 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
where where
I: Into<Vec<connector::Handle>>, I: Into<Vec<connector::Handle>>,
{ {
for backend in self.backends.iter() {
if let Some(backend) = backend.upgrade() {
if backend.borrow().is_crtc(crtc) {
return Err(DrmError::Crtc(CrtcError::AlreadyInUse));
}
}
}
let logger = self.logger let logger = self.logger
.new(o!("drm" => "backend", "crtc" => format!("{:?}", crtc))); .new(o!("drm" => "backend", "crtc" => format!("{:?}", crtc)));
let own_id = self.backends.len(); let own_id = self.backends.len();
// TODO: Make sure we do not initialize the same crtc multiple times
// (check weak pointers and return an error otherwise)
let backend = Rc::new(RefCell::new(DrmBackendInternal::new( let backend = Rc::new(RefCell::new(DrmBackendInternal::new(
self.context.clone(), self.context.clone(),
crtc, crtc,