Add encoder detection to runtime manipulation
This commit is contained in:
parent
174e4b9d0b
commit
a04bfcdd11
|
@ -1,19 +1,13 @@
|
||||||
use super::{DrmError, ModeError};
|
use super::{CrtcError, DrmError, ModeError};
|
||||||
|
|
||||||
use super::devices;
|
use super::devices;
|
||||||
|
|
||||||
use backend::graphics::GraphicsBackend;
|
use backend::graphics::GraphicsBackend;
|
||||||
use backend::graphics::egl::{EGLGraphicsBackend, EGLSurface, PixelFormat, SwapBuffersError};
|
use backend::graphics::egl::{EGLGraphicsBackend, EGLSurface, PixelFormat, SwapBuffersError};
|
||||||
use drm::buffer::Buffer;
|
use drm::buffer::Buffer;
|
||||||
use drm::control::{connector, crtc, framebuffer, Mode};
|
use drm::control::{connector, crtc, encoder, framebuffer, Mode};
|
||||||
use drm::control::ResourceInfo;
|
use drm::control::ResourceInfo;
|
||||||
|
|
||||||
use gbm::{BufferObject, BufferObjectFlags, Format as GbmFormat, Surface as GbmSurface, SurfaceBufferHandle};
|
use gbm::{BufferObject, BufferObjectFlags, Format as GbmFormat, Surface as GbmSurface, SurfaceBufferHandle};
|
||||||
|
|
||||||
use image::{ImageBuffer, Rgba};
|
use image::{ImageBuffer, Rgba};
|
||||||
|
|
||||||
use nix::c_void;
|
use nix::c_void;
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
|
@ -135,7 +129,8 @@ impl DrmBackendInternal {
|
||||||
&[BufferObjectFlags::Cursor, BufferObjectFlags::Write],
|
&[BufferObjectFlags::Cursor, BufferObjectFlags::Write],
|
||||||
)?
|
)?
|
||||||
},
|
},
|
||||||
surface: Surface::try_new({
|
surface: Surface::try_new(
|
||||||
|
{
|
||||||
debug!(log, "Creating GbmSurface");
|
debug!(log, "Creating GbmSurface");
|
||||||
// create a gbm surface
|
// create a gbm surface
|
||||||
Box::new(context.devices.gbm.create_surface(
|
Box::new(context.devices.gbm.create_surface(
|
||||||
|
@ -221,7 +216,7 @@ impl DrmBackend {
|
||||||
/// # Errors
|
/// # Errors
|
||||||
///
|
///
|
||||||
/// Errors if the new connector does not support the currently set `Mode`
|
/// Errors if the new connector does not support the currently set `Mode`
|
||||||
pub fn add_connector(&mut self, connector: connector::Handle) -> Result<(), ModeError> {
|
pub fn add_connector(&mut self, connector: connector::Handle) -> Result<(), DrmError> {
|
||||||
let info =
|
let info =
|
||||||
connector::Info::load_from_device(self.0.borrow().graphics.head().head().head(), connector)
|
connector::Info::load_from_device(self.0.borrow().graphics.head().head().head(), connector)
|
||||||
.map_err(|err| ModeError::FailedToLoad(err))?;
|
.map_err(|err| ModeError::FailedToLoad(err))?;
|
||||||
|
@ -229,11 +224,32 @@ impl DrmBackend {
|
||||||
// check if the connector can handle the current mode
|
// check if the connector can handle the current mode
|
||||||
let mut internal = self.0.borrow_mut();
|
let mut internal = self.0.borrow_mut();
|
||||||
if info.modes().contains(&internal.mode) {
|
if info.modes().contains(&internal.mode) {
|
||||||
info!(self.0.borrow().logger, "Adding new connector: {:?}", info.connector_type());
|
// check if there is a valid encoder
|
||||||
|
let encoders = info.encoders()
|
||||||
|
.iter()
|
||||||
|
.map(|encoder| {
|
||||||
|
encoder::Info::load_from_device(self.0.borrow().graphics.head().head().head(), *encoder)
|
||||||
|
.map_err(DrmError::from)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<encoder::Info>, DrmError>>()?;
|
||||||
|
|
||||||
|
// and if any encoder supports the selected crtc
|
||||||
|
if !encoders
|
||||||
|
.iter()
|
||||||
|
.any(|encoder| encoder.supports_crtc(self.0.borrow().crtc))
|
||||||
|
{
|
||||||
|
return Err(DrmError::Crtc(CrtcError::NoSuitableEncoder));
|
||||||
|
}
|
||||||
|
|
||||||
|
info!(
|
||||||
|
self.0.borrow().logger,
|
||||||
|
"Adding new connector: {:?}",
|
||||||
|
info.connector_type()
|
||||||
|
);
|
||||||
internal.connectors.push(connector);
|
internal.connectors.push(connector);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(ModeError::ModeNotSuitable)
|
Err(DrmError::Mode(ModeError::ModeNotSuitable))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,8 +261,14 @@ impl DrmBackend {
|
||||||
|
|
||||||
/// Removes a currently set connector
|
/// Removes a currently set connector
|
||||||
pub fn remove_connector(&mut self, connector: connector::Handle) {
|
pub fn remove_connector(&mut self, connector: connector::Handle) {
|
||||||
if let Ok(info) = connector::Info::load_from_device(self.0.borrow().graphics.head().head().head(), connector) {
|
if let Ok(info) =
|
||||||
info!(self.0.borrow().logger, "Removing connector: {:?}", info.connector_type());
|
connector::Info::load_from_device(self.0.borrow().graphics.head().head().head(), connector)
|
||||||
|
{
|
||||||
|
info!(
|
||||||
|
self.0.borrow().logger,
|
||||||
|
"Removing connector: {:?}",
|
||||||
|
info.connector_type()
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
info!(self.0.borrow().logger, "Removeing unknown connector");
|
info!(self.0.borrow().logger, "Removeing unknown connector");
|
||||||
}
|
}
|
||||||
|
@ -287,7 +309,8 @@ impl DrmBackend {
|
||||||
// Recreate the surface and the related resources to match the new
|
// Recreate the surface and the related resources to match the new
|
||||||
// resolution.
|
// resolution.
|
||||||
debug!(logger, "Reinitializing surface for new mode: {}:{}", w, h);
|
debug!(logger, "Reinitializing surface for new mode: {}:{}", w, h);
|
||||||
graphics.gbm.surface = Surface::try_new({
|
graphics.gbm.surface = Surface::try_new(
|
||||||
|
{
|
||||||
// create a new gbm surface
|
// create a new gbm surface
|
||||||
debug!(logger, "Creating GbmSurface");
|
debug!(logger, "Creating GbmSurface");
|
||||||
Box::new(graphics.context.devices.gbm.create_surface(
|
Box::new(graphics.context.devices.gbm.create_surface(
|
||||||
|
|
Loading…
Reference in New Issue