drm: Fixup tty switching
This commit is contained in:
parent
3012e87e0e
commit
524057418e
|
@ -303,6 +303,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
context: &EGLContext,
|
context: &EGLContext,
|
||||||
display: &mut Display,
|
display: &mut Display,
|
||||||
output_map: &mut Vec<MyOutput>,
|
output_map: &mut Vec<MyOutput>,
|
||||||
|
signaler: &Signaler<SessionSignal>,
|
||||||
logger: &::slog::Logger,
|
logger: &::slog::Logger,
|
||||||
) -> HashMap<crtc::Handle, Rc<RefCell<RenderSurface>>> {
|
) -> HashMap<crtc::Handle, Rc<RefCell<RenderSurface>>> {
|
||||||
// Get a set of all modesetting resource handles (excluding planes):
|
// Get a set of all modesetting resource handles (excluding planes):
|
||||||
|
@ -360,7 +361,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let surface = match device.create_surface(
|
let mut surface = match device.create_surface(
|
||||||
crtc,
|
crtc,
|
||||||
primary,
|
primary,
|
||||||
connector_info.modes()[0],
|
connector_info.modes()[0],
|
||||||
|
@ -372,6 +373,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
surface.link(signaler.clone());
|
||||||
let renderer =
|
let renderer =
|
||||||
match DrmRenderSurface::new(surface, gbm.clone(), renderer, logger.clone()) {
|
match DrmRenderSurface::new(surface, gbm.clone(), renderer, logger.clone()) {
|
||||||
Ok(renderer) => renderer,
|
Ok(renderer) => renderer,
|
||||||
|
@ -480,6 +482,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
&context,
|
&context,
|
||||||
&mut *self.display.borrow_mut(),
|
&mut *self.display.borrow_mut(),
|
||||||
&mut *self.output_map.borrow_mut(),
|
&mut *self.output_map.borrow_mut(),
|
||||||
|
&self.signaler,
|
||||||
&self.logger,
|
&self.logger,
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
@ -562,6 +565,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
let loop_handle = self.loop_handle.clone();
|
let loop_handle = self.loop_handle.clone();
|
||||||
let mut display = self.display.borrow_mut();
|
let mut display = self.display.borrow_mut();
|
||||||
let mut output_map = self.output_map.borrow_mut();
|
let mut output_map = self.output_map.borrow_mut();
|
||||||
|
let signaler = self.signaler.clone();
|
||||||
output_map.retain(|output| output.device_id != device);
|
output_map.retain(|output| output.device_id != device);
|
||||||
self.loop_handle
|
self.loop_handle
|
||||||
.with_source(&backend_data.event_source, |source| {
|
.with_source(&backend_data.event_source, |source| {
|
||||||
|
@ -573,6 +577,7 @@ impl<Data: 'static> UdevHandlerImpl<Data> {
|
||||||
&backend_data.context,
|
&backend_data.context,
|
||||||
&mut *display,
|
&mut *display,
|
||||||
&mut *output_map,
|
&mut *output_map,
|
||||||
|
&signaler,
|
||||||
&logger,
|
&logger,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -509,10 +509,13 @@ impl<A: AsRawFd + 'static> DrmDevice<A> {
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(DrmSurface {
|
Ok(DrmSurface {
|
||||||
|
dev_id: self.dev_id,
|
||||||
crtc,
|
crtc,
|
||||||
plane,
|
plane,
|
||||||
internal: Arc::new(internal),
|
internal: Arc::new(internal),
|
||||||
formats,
|
formats,
|
||||||
|
#[cfg(feature = "backend_session")]
|
||||||
|
links: RefCell::new(Vec::new()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,15 +535,6 @@ pub struct Planes {
|
||||||
pub overlay: Option<Vec<plane::Handle>>,
|
pub overlay: Option<Vec<plane::Handle>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: AsRawFd + 'static> DrmDeviceInternal<A> {
|
|
||||||
pub(super) fn reset_state(&self) -> Result<(), Error> {
|
|
||||||
match self {
|
|
||||||
DrmDeviceInternal::Atomic(dev) => dev.reset_state(),
|
|
||||||
DrmDeviceInternal::Legacy(dev) => dev.reset_state(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Trait to receive events of a bound [`DrmDevice`]
|
/// Trait to receive events of a bound [`DrmDevice`]
|
||||||
///
|
///
|
||||||
/// See [`device_bind`]
|
/// See [`device_bind`]
|
||||||
|
|
|
@ -4,12 +4,12 @@ use std::sync::{
|
||||||
Arc, Weak,
|
Arc, Weak,
|
||||||
};
|
};
|
||||||
|
|
||||||
use drm::Device as BasicDevice;
|
use drm::{Device as BasicDevice, control::{crtc, Device as ControlDevice}};
|
||||||
use nix::libc::dev_t;
|
use nix::libc::dev_t;
|
||||||
use nix::sys::stat;
|
use nix::sys::stat;
|
||||||
|
|
||||||
use super::device::{DrmDevice, DrmDeviceInternal};
|
use super::device::{DrmDevice, DrmDeviceInternal};
|
||||||
use super::error::Error;
|
use super::surface::{DrmSurface, DrmSurfaceInternal};
|
||||||
use crate::{
|
use crate::{
|
||||||
backend::session::Signal as SessionSignal,
|
backend::session::Signal as SessionSignal,
|
||||||
signaling::{Linkable, Signaler},
|
signaling::{Linkable, Signaler},
|
||||||
|
@ -96,21 +96,74 @@ impl<A: AsRawFd + 'static> DrmDeviceObserver<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// okay, the previous session/whatever might left the drm devices in any state...
|
|
||||||
// lets fix that
|
|
||||||
if let Err(err) = self.reset_state() {
|
|
||||||
warn!(self.logger, "Unable to reset state after tty switch: {}", err);
|
|
||||||
// TODO call drm-handler::error
|
|
||||||
}
|
|
||||||
|
|
||||||
self.active.store(true, Ordering::SeqCst);
|
self.active.store(true, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn reset_state(&mut self) -> Result<(), Error> {
|
pub struct DrmSurfaceObserver<A: AsRawFd + 'static> {
|
||||||
if let Some(dev) = self.dev.upgrade() {
|
dev_id: dev_t,
|
||||||
dev.reset_state()
|
crtc: crtc::Handle,
|
||||||
} else {
|
surf: Weak<DrmSurfaceInternal<A>>,
|
||||||
Ok(())
|
logger: ::slog::Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct FdHack(RawFd);
|
||||||
|
impl AsRawFd for FdHack {
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl BasicDevice for FdHack {}
|
||||||
|
impl ControlDevice for FdHack {}
|
||||||
|
|
||||||
|
impl<A: AsRawFd + 'static> Linkable<SessionSignal> for DrmSurface<A> {
|
||||||
|
fn link(&mut self, signaler: Signaler<SessionSignal>) {
|
||||||
|
let logger = match &*self.internal {
|
||||||
|
DrmSurfaceInternal::Atomic(surf) => surf.logger.clone(),
|
||||||
|
DrmSurfaceInternal::Legacy(surf) => surf.logger.clone(),
|
||||||
|
};
|
||||||
|
let mut observer = DrmSurfaceObserver {
|
||||||
|
dev_id: self.dev_id,
|
||||||
|
crtc: self.crtc(),
|
||||||
|
surf: Arc::downgrade(&self.internal),
|
||||||
|
logger: logger.new(o!("drm_module" => "observer")),
|
||||||
|
};
|
||||||
|
|
||||||
|
let token = signaler.register(move |signal| observer.signal(*signal));
|
||||||
|
self.links.borrow_mut().push(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: AsRawFd + 'static> DrmSurfaceObserver<A> {
|
||||||
|
fn signal(&mut self, signal: SessionSignal) {
|
||||||
|
match signal {
|
||||||
|
SessionSignal::ActivateSession => self.activate(None),
|
||||||
|
SessionSignal::ActivateDevice { major, minor, new_fd } => {
|
||||||
|
self.activate(Some((major, minor, new_fd)))
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn activate(&mut self, devnum: Option<(u32, u32, Option<RawFd>)>) {
|
||||||
|
if let Some(surf) = self.surf.upgrade() {
|
||||||
|
// The device will reset the _fd, but the observer order is not deterministic,
|
||||||
|
// so we might need to use it anyway.
|
||||||
|
let fd = if let Some((major, minor, fd)) = devnum {
|
||||||
|
if major as u64 != stat::major(self.dev_id) || minor as u64 != stat::minor(self.dev_id) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fd.map(FdHack)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Err(err) = match &*surf {
|
||||||
|
DrmSurfaceInternal::Atomic(surf) => surf.reset_state(fd.as_ref()),
|
||||||
|
DrmSurfaceInternal::Legacy(surf) => surf.reset_state(fd.as_ref()),
|
||||||
|
} {
|
||||||
|
warn!(self.logger, "Failed to reset state of surface ({:?}/{:?}): {}", self.dev_id, self.crtc, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,40 +24,8 @@ pub struct State {
|
||||||
pub connectors: HashSet<connector::Handle>,
|
pub connectors: HashSet<connector::Handle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AtomicDrmSurface<A: AsRawFd + 'static> {
|
impl State {
|
||||||
pub(super) fd: Arc<DrmDeviceInternal<A>>,
|
fn current_state<A: AsRawFd + ControlDevice>(fd: &A, crtc: crtc::Handle, prop_mapping: &Mapping) -> Result<Self, Error> {
|
||||||
pub(super) active: Arc<AtomicBool>,
|
|
||||||
crtc: crtc::Handle,
|
|
||||||
plane: plane::Handle,
|
|
||||||
prop_mapping: Mapping,
|
|
||||||
state: RwLock<State>,
|
|
||||||
pending: RwLock<State>,
|
|
||||||
test_buffer: Mutex<Option<(DumbBuffer, framebuffer::Handle)>>,
|
|
||||||
pub(crate) logger: ::slog::Logger,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
|
|
||||||
#[allow(clippy::too_many_arguments)]
|
|
||||||
pub fn new(
|
|
||||||
fd: Arc<DrmDeviceInternal<A>>,
|
|
||||||
active: Arc<AtomicBool>,
|
|
||||||
crtc: crtc::Handle,
|
|
||||||
plane: plane::Handle,
|
|
||||||
prop_mapping: Mapping,
|
|
||||||
mode: Mode,
|
|
||||||
connectors: &[connector::Handle],
|
|
||||||
logger: ::slog::Logger,
|
|
||||||
) -> Result<Self, Error> {
|
|
||||||
let logger = logger.new(o!("smithay_module" => "backend_drm_atomic", "drm_module" => "surface"));
|
|
||||||
info!(
|
|
||||||
logger,
|
|
||||||
"Initializing drm surface ({:?}:{:?}) with mode {:?} and connectors {:?}",
|
|
||||||
crtc,
|
|
||||||
plane,
|
|
||||||
mode,
|
|
||||||
connectors
|
|
||||||
);
|
|
||||||
|
|
||||||
let crtc_info = fd.get_crtc(crtc).map_err(|source| Error::Access {
|
let crtc_info = fd.get_crtc(crtc).map_err(|source| Error::Access {
|
||||||
errmsg: "Error loading crtc info",
|
errmsg: "Error loading crtc info",
|
||||||
dev: fd.dev_path(),
|
dev: fd.dev_path(),
|
||||||
|
@ -78,12 +46,6 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
|
||||||
None => property::Value::Unknown(0),
|
None => property::Value::Unknown(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
let blob = fd.create_property_blob(&mode).map_err(|source| Error::Access {
|
|
||||||
errmsg: "Failed to create Property Blob for mode",
|
|
||||||
dev: fd.dev_path(),
|
|
||||||
source,
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let res_handles = fd.resource_handles().map_err(|source| Error::Access {
|
let res_handles = fd.resource_handles().map_err(|source| Error::Access {
|
||||||
errmsg: "Error loading drm resources",
|
errmsg: "Error loading drm resources",
|
||||||
dev: fd.dev_path(),
|
dev: fd.dev_path(),
|
||||||
|
@ -122,11 +84,54 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let state = State {
|
Ok(State {
|
||||||
mode: current_mode,
|
mode: current_mode,
|
||||||
blob: current_blob,
|
blob: current_blob,
|
||||||
connectors: current_connectors,
|
connectors: current_connectors,
|
||||||
};
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct AtomicDrmSurface<A: AsRawFd + 'static> {
|
||||||
|
pub(super) fd: Arc<DrmDeviceInternal<A>>,
|
||||||
|
pub(super) active: Arc<AtomicBool>,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
plane: plane::Handle,
|
||||||
|
prop_mapping: Mapping,
|
||||||
|
state: RwLock<State>,
|
||||||
|
pending: RwLock<State>,
|
||||||
|
test_buffer: Mutex<Option<(DumbBuffer, framebuffer::Handle)>>,
|
||||||
|
pub(crate) logger: ::slog::Logger,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
pub fn new(
|
||||||
|
fd: Arc<DrmDeviceInternal<A>>,
|
||||||
|
active: Arc<AtomicBool>,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
plane: plane::Handle,
|
||||||
|
prop_mapping: Mapping,
|
||||||
|
mode: Mode,
|
||||||
|
connectors: &[connector::Handle],
|
||||||
|
logger: ::slog::Logger,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let logger = logger.new(o!("smithay_module" => "backend_drm_atomic", "drm_module" => "surface"));
|
||||||
|
info!(
|
||||||
|
logger,
|
||||||
|
"Initializing drm surface ({:?}:{:?}) with mode {:?} and connectors {:?}",
|
||||||
|
crtc,
|
||||||
|
plane,
|
||||||
|
mode,
|
||||||
|
connectors
|
||||||
|
);
|
||||||
|
|
||||||
|
let state = State::current_state(&*fd, crtc, &prop_mapping)?;
|
||||||
|
let blob = fd.create_property_blob(&mode).map_err(|source| Error::Access {
|
||||||
|
errmsg: "Failed to create Property Blob for mode",
|
||||||
|
dev: fd.dev_path(),
|
||||||
|
source,
|
||||||
|
})?;
|
||||||
let pending = State {
|
let pending = State {
|
||||||
mode,
|
mode,
|
||||||
blob,
|
blob,
|
||||||
|
@ -761,6 +766,16 @@ impl<A: AsRawFd + 'static> AtomicDrmSurface<A> {
|
||||||
source,
|
source,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub(crate) fn reset_state<B: AsRawFd + ControlDevice + 'static>(&self, fd: Option<&B>) -> Result<(), Error> {
|
||||||
|
*self.state.write().unwrap() = if let Some(fd) = fd {
|
||||||
|
State::current_state(fd, self.crtc, &self.prop_mapping)?
|
||||||
|
} else {
|
||||||
|
State::current_state(&*self.fd, self.crtc, &self.prop_mapping)?
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: AsRawFd + 'static> Drop for AtomicDrmSurface<A> {
|
impl<A: AsRawFd + 'static> Drop for AtomicDrmSurface<A> {
|
||||||
|
|
|
@ -19,30 +19,8 @@ pub struct State {
|
||||||
pub connectors: HashSet<connector::Handle>,
|
pub connectors: HashSet<connector::Handle>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct LegacyDrmSurface<A: AsRawFd + 'static> {
|
impl State {
|
||||||
pub(super) fd: Arc<DrmDeviceInternal<A>>,
|
fn current_state<A: AsRawFd + ControlDevice>(fd: &A, crtc: crtc::Handle) -> Result<Self, Error> {
|
||||||
pub(super) active: Arc<AtomicBool>,
|
|
||||||
crtc: crtc::Handle,
|
|
||||||
state: RwLock<State>,
|
|
||||||
pending: RwLock<State>,
|
|
||||||
pub(crate) logger: ::slog::Logger,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
|
|
||||||
pub fn new(
|
|
||||||
fd: Arc<DrmDeviceInternal<A>>,
|
|
||||||
active: Arc<AtomicBool>,
|
|
||||||
crtc: crtc::Handle,
|
|
||||||
mode: Mode,
|
|
||||||
connectors: &[connector::Handle],
|
|
||||||
logger: ::slog::Logger,
|
|
||||||
) -> Result<Self, Error> {
|
|
||||||
let logger = logger.new(o!("smithay_module" => "backend_drm_legacy", "drm_module" => "surface"));
|
|
||||||
info!(
|
|
||||||
logger,
|
|
||||||
"Initializing drm surface with mode {:?} and connectors {:?}", mode, connectors
|
|
||||||
);
|
|
||||||
|
|
||||||
// Try to enumarate the current state to set the initial state variable correctly.
|
// Try to enumarate the current state to set the initial state variable correctly.
|
||||||
// We need an accurate state to handle `commit_pending`.
|
// We need an accurate state to handle `commit_pending`.
|
||||||
let crtc_info = fd.get_crtc(crtc).map_err(|source| Error::Access {
|
let crtc_info = fd.get_crtc(crtc).map_err(|source| Error::Access {
|
||||||
|
@ -83,10 +61,38 @@ impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
|
||||||
// A better fix would probably be making mode an `Option`, but that would mean
|
// A better fix would probably be making mode an `Option`, but that would mean
|
||||||
// we need to be sure, we require a mode to always be set without relying on the compiler.
|
// we need to be sure, we require a mode to always be set without relying on the compiler.
|
||||||
// So we cheat, because it works and is easier to handle later.
|
// So we cheat, because it works and is easier to handle later.
|
||||||
let state = State {
|
Ok(State {
|
||||||
mode: current_mode.unwrap_or_else(|| unsafe { std::mem::zeroed() }),
|
mode: current_mode.unwrap_or_else(|| unsafe { std::mem::zeroed() }),
|
||||||
connectors: current_connectors,
|
connectors: current_connectors,
|
||||||
};
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct LegacyDrmSurface<A: AsRawFd + 'static> {
|
||||||
|
pub(super) fd: Arc<DrmDeviceInternal<A>>,
|
||||||
|
pub(super) active: Arc<AtomicBool>,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
state: RwLock<State>,
|
||||||
|
pending: RwLock<State>,
|
||||||
|
pub(crate) logger: ::slog::Logger,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
|
||||||
|
pub fn new(
|
||||||
|
fd: Arc<DrmDeviceInternal<A>>,
|
||||||
|
active: Arc<AtomicBool>,
|
||||||
|
crtc: crtc::Handle,
|
||||||
|
mode: Mode,
|
||||||
|
connectors: &[connector::Handle],
|
||||||
|
logger: ::slog::Logger,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
|
let logger = logger.new(o!("smithay_module" => "backend_drm_legacy", "drm_module" => "surface"));
|
||||||
|
info!(
|
||||||
|
logger,
|
||||||
|
"Initializing drm surface with mode {:?} and connectors {:?}", mode, connectors
|
||||||
|
);
|
||||||
|
|
||||||
|
let state = State::current_state(&*fd, crtc)?;
|
||||||
let pending = State {
|
let pending = State {
|
||||||
mode,
|
mode,
|
||||||
connectors: connectors.iter().copied().collect(),
|
connectors: connectors.iter().copied().collect(),
|
||||||
|
@ -396,6 +402,15 @@ impl<A: AsRawFd + 'static> LegacyDrmSurface<A> {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn reset_state<B: AsRawFd + ControlDevice + 'static>(&self, fd: Option<&B>) -> Result<(), Error> {
|
||||||
|
*self.state.write().unwrap() = if let Some(fd) = fd {
|
||||||
|
State::current_state(fd, self.crtc)?
|
||||||
|
} else {
|
||||||
|
State::current_state(&*self.fd, self.crtc)?
|
||||||
|
};
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A: AsRawFd + 'static> Drop for LegacyDrmSurface<A> {
|
impl<A: AsRawFd + 'static> Drop for LegacyDrmSurface<A> {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::cell::RefCell;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::os::unix::io::{AsRawFd, RawFd};
|
use std::os::unix::io::{AsRawFd, RawFd};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -5,6 +6,8 @@ use std::sync::Arc;
|
||||||
use drm::control::{connector, crtc, framebuffer, plane, Device as ControlDevice, Mode};
|
use drm::control::{connector, crtc, framebuffer, plane, Device as ControlDevice, Mode};
|
||||||
use drm::Device as BasicDevice;
|
use drm::Device as BasicDevice;
|
||||||
|
|
||||||
|
use nix::libc::dev_t;
|
||||||
|
|
||||||
pub(super) mod atomic;
|
pub(super) mod atomic;
|
||||||
pub(super) mod legacy;
|
pub(super) mod legacy;
|
||||||
use super::error::Error;
|
use super::error::Error;
|
||||||
|
@ -14,10 +17,13 @@ use legacy::LegacyDrmSurface;
|
||||||
|
|
||||||
/// An open crtc + plane combination that can be used for scan-out
|
/// An open crtc + plane combination that can be used for scan-out
|
||||||
pub struct DrmSurface<A: AsRawFd + 'static> {
|
pub struct DrmSurface<A: AsRawFd + 'static> {
|
||||||
|
pub(super) dev_id: dev_t,
|
||||||
pub(super) crtc: crtc::Handle,
|
pub(super) crtc: crtc::Handle,
|
||||||
pub(super) plane: plane::Handle,
|
pub(super) plane: plane::Handle,
|
||||||
pub(super) internal: Arc<DrmSurfaceInternal<A>>,
|
pub(super) internal: Arc<DrmSurfaceInternal<A>>,
|
||||||
pub(super) formats: HashSet<Format>,
|
pub(super) formats: HashSet<Format>,
|
||||||
|
#[cfg(feature = "backend_session")]
|
||||||
|
pub(super) links: RefCell<Vec<crate::signaling::SignalToken>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum DrmSurfaceInternal<A: AsRawFd + 'static> {
|
pub enum DrmSurfaceInternal<A: AsRawFd + 'static> {
|
||||||
|
@ -211,4 +217,16 @@ impl<A: AsRawFd + 'static> DrmSurface<A> {
|
||||||
} // There is no test-commiting with the legacy interface
|
} // There is no test-commiting with the legacy interface
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Re-evaluates the current state of the crtc.
|
||||||
|
///
|
||||||
|
/// Usually you do not need to call this, but if the state of
|
||||||
|
/// the crtc is modified elsewhere and you need to reset the
|
||||||
|
/// initial state of this surface, you may call this function.
|
||||||
|
pub fn reset_state(&self) -> Result<(), Error> {
|
||||||
|
match &*self.internal {
|
||||||
|
DrmSurfaceInternal::Atomic(surf) => surf.reset_state::<Self>(None),
|
||||||
|
DrmSurfaceInternal::Legacy(surf) => surf.reset_state::<Self>(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue