drm: Check for valid encoder
This commit is contained in:
parent
660080c45d
commit
ab77a87725
|
@ -42,4 +42,4 @@ renderer_glium = ["glium"]
|
||||||
"wayland-server:0.9.9" = { git = "https://github.com/Drakulix/wayland-rs", branch = "raw_handler_access"}
|
"wayland-server:0.9.9" = { git = "https://github.com/Drakulix/wayland-rs", branch = "raw_handler_access"}
|
||||||
"wayland-protocols:0.9.9" = { git = "https://github.com/Drakulix/wayland-rs", branch = "raw_handler_access"}
|
"wayland-protocols:0.9.9" = { git = "https://github.com/Drakulix/wayland-rs", branch = "raw_handler_access"}
|
||||||
"wayland-client:0.9.9" = { git = "https://github.com/Drakulix/wayland-rs", branch = "raw_handler_access"}
|
"wayland-client:0.9.9" = { git = "https://github.com/Drakulix/wayland-rs", branch = "raw_handler_access"}
|
||||||
"drm:0.2.1" = { git = "https://github.com/Drakulix/drm-rs", branch = "fix/userdata" }
|
"drm:0.2.1" = { git = "https://github.com/Drakulix/drm-rs", branch = "future" }
|
||||||
|
|
|
@ -154,6 +154,8 @@ impl error::Error for ModeError {
|
||||||
pub enum CrtcError {
|
pub enum CrtcError {
|
||||||
/// Selected crtc is already in use by another `DrmBackend`
|
/// Selected crtc is already in use by another `DrmBackend`
|
||||||
AlreadyInUse,
|
AlreadyInUse,
|
||||||
|
/// For the selected crtc no encoder exists that supports all connectors
|
||||||
|
NoSuitableEncoder,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for CrtcError {
|
impl fmt::Display for CrtcError {
|
||||||
|
@ -170,6 +172,7 @@ impl error::Error for CrtcError {
|
||||||
fn description(&self) -> &str {
|
fn description(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
&CrtcError::AlreadyInUse => "Crtc is already in use by another DrmBackend",
|
&CrtcError::AlreadyInUse => "Crtc is already in use by another DrmBackend",
|
||||||
|
&CrtcError::NoSuitableEncoder => "Crtc has no supported encoder that can drive all connectors",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -142,7 +142,7 @@
|
||||||
|
|
||||||
use backend::graphics::egl::{EGLContext, GlAttributes, PixelFormatRequirements};
|
use backend::graphics::egl::{EGLContext, GlAttributes, PixelFormatRequirements};
|
||||||
use drm::Device as BasicDevice;
|
use drm::Device as BasicDevice;
|
||||||
use drm::control::{connector, crtc, Mode};
|
use drm::control::{connector, crtc, encoder, Mode, ResourceInfo};
|
||||||
use drm::control::Device as ControlDevice;
|
use drm::control::Device as ControlDevice;
|
||||||
|
|
||||||
use gbm::Device as GbmDevice;
|
use gbm::Device as GbmDevice;
|
||||||
|
@ -353,6 +353,8 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
|
||||||
where
|
where
|
||||||
I: Into<Vec<connector::Handle>>,
|
I: Into<Vec<connector::Handle>>,
|
||||||
{
|
{
|
||||||
|
use std::collections::hash_set::HashSet;
|
||||||
|
|
||||||
for backend in self.backends.iter() {
|
for backend in self.backends.iter() {
|
||||||
if let Some(backend) = backend.upgrade() {
|
if let Some(backend) = backend.upgrade() {
|
||||||
if backend.borrow().is_crtc(crtc) {
|
if backend.borrow().is_crtc(crtc) {
|
||||||
|
@ -361,6 +363,26 @@ impl<H: DrmHandler + 'static> DrmDevice<H> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if the given connectors and crtc match
|
||||||
|
let connectors = connectors.into();
|
||||||
|
// get all encoders supported by this device
|
||||||
|
let mut set = self.context.head().head().resource_handles()?.encoders().iter().cloned().collect::<HashSet<encoder::Handle>>();
|
||||||
|
for connector in connectors.iter() {
|
||||||
|
let info = connector::Info::load_from_device(self.context.head().head(), *connector)?;
|
||||||
|
// then check for every connector which encoders it does support
|
||||||
|
let conn_set = info.encoders().iter().cloned().collect::<HashSet<encoder::Handle>>();
|
||||||
|
// and update the list of supported encoders for this combination
|
||||||
|
set = set.intersection(&conn_set).cloned().collect::<HashSet<encoder::Handle>>();
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if there is any encoder left that can be connected to the crtc
|
||||||
|
let encoders: Vec<encoder::Info> = set.iter().map(|handle| encoder::Info::load_from_device(self.context.head().head(), *handle).map_err(DrmError::from)).collect::<Result<Vec<encoder::Info>, DrmError>>()?;
|
||||||
|
if !encoders.iter().any(|enc| enc.supports_crtc(crtc)) {
|
||||||
|
return Err(DrmError::Crtc(CrtcError::NoSuitableEncoder));
|
||||||
|
}
|
||||||
|
|
||||||
|
// configuration is valid, the kernel will figure out the rest
|
||||||
|
|
||||||
let own_id = self.backends.len();
|
let own_id = self.backends.len();
|
||||||
let logger = self.logger
|
let logger = self.logger
|
||||||
.new(o!("id" => format!("{}", own_id), "crtc" => format!("{:?}", crtc)));
|
.new(o!("id" => format!("{}", own_id), "crtc" => format!("{:?}", crtc)));
|
||||||
|
|
Loading…
Reference in New Issue