aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2023-09-03 13:04:32 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2023-09-03 13:04:32 +0400
commit5a707c879ba9b21665d2207020fe354040b807b2 (patch)
tree5bdc370a4b3068b0878d3d85acfbd25bf23a3952
parent3bd5a012cbf15bd294e1a6290914a6e687cbcf2d (diff)
downloadniri-5a707c879ba9b21665d2207020fe354040b807b2.tar.gz
niri-5a707c879ba9b21665d2207020fe354040b807b2.tar.bz2
niri-5a707c879ba9b21665d2207020fe354040b807b2.zip
Replace Backend trait with enum
-rw-r--r--src/backend.rs57
-rw-r--r--src/main.rs23
-rw-r--r--src/niri.rs9
-rw-r--r--src/tty.rs113
-rw-r--r--src/winit.rs81
5 files changed, 154 insertions, 129 deletions
diff --git a/src/backend.rs b/src/backend.rs
index 65c8a772..12f5a0a3 100644
--- a/src/backend.rs
+++ b/src/backend.rs
@@ -2,15 +2,62 @@ use smithay::backend::renderer::gles::GlesRenderer;
use smithay::output::Output;
use crate::niri::OutputRenderElements;
+use crate::tty::Tty;
+use crate::winit::Winit;
use crate::Niri;
-pub trait Backend {
- fn seat_name(&self) -> String;
- fn renderer(&mut self) -> &mut GlesRenderer;
- fn render(
+pub enum Backend {
+ Tty(Tty),
+ Winit(Winit),
+}
+
+impl Backend {
+ pub fn init(&mut self, niri: &mut Niri) {
+ match self {
+ Backend::Tty(tty) => tty.init(niri),
+ Backend::Winit(winit) => winit.init(niri),
+ }
+ }
+
+ pub fn seat_name(&self) -> String {
+ match self {
+ Backend::Tty(tty) => tty.seat_name(),
+ Backend::Winit(winit) => winit.seat_name(),
+ }
+ }
+
+ pub fn renderer(&mut self) -> &mut GlesRenderer {
+ match self {
+ Backend::Tty(tty) => tty.renderer(),
+ Backend::Winit(winit) => winit.renderer(),
+ }
+ }
+
+ pub fn render(
&mut self,
niri: &mut Niri,
output: &Output,
elements: &[OutputRenderElements<GlesRenderer>],
- );
+ ) {
+ match self {
+ Backend::Tty(tty) => tty.render(niri, output, elements),
+ Backend::Winit(winit) => winit.render(niri, output, elements),
+ }
+ }
+
+ pub fn tty(&mut self) -> Option<&mut Tty> {
+ if let Self::Tty(v) = self {
+ Some(v)
+ } else {
+ None
+ }
+ }
+
+ pub fn winit(&mut self) -> Option<&mut Winit> {
+ if let Self::Winit(v) = self {
+ Some(v)
+ } else {
+ None
+ }
+ }
}
diff --git a/src/main.rs b/src/main.rs
index e2c42cba..216dedee 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -38,8 +38,7 @@ pub struct LoopData {
niri: Niri,
display_handle: DisplayHandle,
- tty: Option<Tty>,
- winit: Option<Winit>,
+ backend: Backend,
// Last so that it's dropped after the Smithay state in Niri and related state in Tty.
// Otherwise it will segfault on quit.
@@ -64,14 +63,10 @@ fn main() {
let has_display = env::var_os("WAYLAND_DISPLAY").is_some() || env::var_os("DISPLAY").is_some();
- let mut winit = None;
- let mut tty = None;
- let backend: &mut dyn Backend = if has_display {
- winit = Some(Winit::new(event_loop.handle()));
- winit.as_mut().unwrap()
+ let backend = if has_display {
+ Backend::Winit(Winit::new(event_loop.handle()))
} else {
- tty = Some(Tty::new(event_loop.handle()));
- tty.as_mut().unwrap()
+ Backend::Tty(Tty::new(event_loop.handle()))
};
let mut display = Display::new().unwrap();
@@ -88,16 +83,10 @@ fn main() {
display_handle,
display,
- tty,
- winit,
+ backend,
};
- if let Some(tty) = data.tty.as_mut() {
- tty.init(&mut data.niri);
- }
- if let Some(winit) = data.winit.as_mut() {
- winit.init(&mut data.niri);
- }
+ data.backend.init(&mut data.niri);
if let Some((command, args)) = cli.command.split_first() {
if let Err(err) = std::process::Command::new(command).args(args).spawn() {
diff --git a/src/niri.rs b/src/niri.rs
index 1a00915a..1a5f990a 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -512,12 +512,7 @@ impl Niri {
// Timer::immediate() adds a millisecond of delay for some reason.
// This should be fixed in calloop v0.11: https://github.com/Smithay/calloop/issues/142
let idle = self.event_loop.insert_idle(move |data| {
- let backend: &mut dyn Backend = if let Some(tty) = &mut data.tty {
- tty
- } else {
- data.winit.as_mut().unwrap()
- };
- data.niri.redraw(backend, &output);
+ data.niri.redraw(&mut data.backend, &output);
});
state.queued_redraw = Some(idle);
}
@@ -655,7 +650,7 @@ impl Niri {
elements
}
- fn redraw(&mut self, backend: &mut dyn Backend, output: &Output) {
+ fn redraw(&mut self, backend: &mut Backend, output: &Output) {
let _span = tracy_client::span!("Niri::redraw");
let state = self.output_state.get_mut(output).unwrap();
diff --git a/src/tty.rs b/src/tty.rs
index b45e456d..63256821 100644
--- a/src/tty.rs
+++ b/src/tty.rs
@@ -30,7 +30,6 @@ use smithay::utils::DeviceFd;
use smithay_drm_extras::drm_scanner::{DrmScanEvent, DrmScanner};
use smithay_drm_extras::edid::EdidInfo;
-use crate::backend::Backend;
use crate::input::{BackendAction, CompositorMod};
use crate::niri::OutputRenderElements;
use crate::{LoopData, Niri};
@@ -69,59 +68,6 @@ struct TtyOutputState {
crtc: crtc::Handle,
}
-impl Backend for Tty {
- fn seat_name(&self) -> String {
- self.session.seat()
- }
-
- fn renderer(&mut self) -> &mut GlesRenderer {
- &mut self.output_device.as_mut().unwrap().gles
- }
-
- fn render(
- &mut self,
- niri: &mut Niri,
- output: &Output,
- elements: &[OutputRenderElements<GlesRenderer>],
- ) {
- let _span = tracy_client::span!("Tty::render");
-
- let device = self.output_device.as_mut().unwrap();
- let tty_state: &TtyOutputState = output.user_data().get().unwrap();
- let drm_compositor = device.surfaces.get_mut(&tty_state.crtc).unwrap();
-
- match drm_compositor.render_frame::<_, _, GlesTexture>(
- &mut device.gles,
- elements,
- BACKGROUND_COLOR,
- ) {
- Ok(res) => {
- assert!(!res.needs_sync());
- if res.damage.is_some() {
- let presentation_feedbacks =
- niri.take_presentation_feedbacks(output, &res.states);
-
- match drm_compositor.queue_frame(presentation_feedbacks) {
- Ok(()) => {
- niri.output_state
- .get_mut(output)
- .unwrap()
- .waiting_for_vblank = true
- }
- Err(err) => {
- error!("error queueing frame: {err}");
- }
- }
- }
- }
- Err(err) => {
- // Can fail if we switched to a different TTY.
- error!("error rendering frame: {err}");
- }
- }
- }
-}
-
impl Tty {
pub fn new(event_loop: LoopHandle<'static, LoopData>) -> Self {
let (session, notifier) = LibSeatSession::new().unwrap();
@@ -130,7 +76,7 @@ impl Tty {
let udev_backend = UdevBackend::new(session.seat()).unwrap();
let udev_dispatcher =
Dispatcher::new(udev_backend, move |event, _, data: &mut LoopData| {
- let tty = data.tty.as_mut().unwrap();
+ let tty = data.backend.tty().unwrap();
let niri = &mut data.niri;
match event {
@@ -172,7 +118,7 @@ impl Tty {
let input_backend = LibinputInputBackend::new(libinput.clone());
event_loop
.insert_source(input_backend, |mut event, _, data| {
- let tty = data.tty.as_mut().unwrap();
+ let tty = data.backend.tty().unwrap();
let niri = &mut data.niri;
niri.process_libinput_event(&mut event);
@@ -207,7 +153,7 @@ impl Tty {
let udev_dispatcher_c = udev_dispatcher.clone();
event_loop
.insert_source(notifier, move |event, _, data| {
- let tty = data.tty.as_mut().unwrap();
+ let tty = data.backend.tty().unwrap();
let niri = &mut data.niri;
match event {
@@ -344,7 +290,7 @@ impl Tty {
let token = niri
.event_loop
.insert_source(drm_notifier, move |event, metadata, data| {
- let tty = data.tty.as_mut().unwrap();
+ let tty = data.backend.tty().unwrap();
match event {
DrmEvent::VBlank(crtc) => {
tracy_client::Client::running()
@@ -593,6 +539,57 @@ impl Tty {
niri.remove_output(&output);
}
+ pub fn seat_name(&self) -> String {
+ self.session.seat()
+ }
+
+ pub fn renderer(&mut self) -> &mut GlesRenderer {
+ &mut self.output_device.as_mut().unwrap().gles
+ }
+
+ pub fn render(
+ &mut self,
+ niri: &mut Niri,
+ output: &Output,
+ elements: &[OutputRenderElements<GlesRenderer>],
+ ) {
+ let _span = tracy_client::span!("Tty::render");
+
+ let device = self.output_device.as_mut().unwrap();
+ let tty_state: &TtyOutputState = output.user_data().get().unwrap();
+ let drm_compositor = device.surfaces.get_mut(&tty_state.crtc).unwrap();
+
+ match drm_compositor.render_frame::<_, _, GlesTexture>(
+ &mut device.gles,
+ elements,
+ BACKGROUND_COLOR,
+ ) {
+ Ok(res) => {
+ assert!(!res.needs_sync());
+ if res.damage.is_some() {
+ let presentation_feedbacks =
+ niri.take_presentation_feedbacks(output, &res.states);
+
+ match drm_compositor.queue_frame(presentation_feedbacks) {
+ Ok(()) => {
+ niri.output_state
+ .get_mut(output)
+ .unwrap()
+ .waiting_for_vblank = true
+ }
+ Err(err) => {
+ error!("error queueing frame: {err}");
+ }
+ }
+ }
+ }
+ Err(err) => {
+ // Can fail if we switched to a different TTY.
+ error!("error rendering frame: {err}");
+ }
+ }
+ }
+
fn change_vt(&mut self, vt: i32) {
if let Err(err) = self.session.change_vt(vt) {
error!("error changing VT: {err}");
diff --git a/src/winit.rs b/src/winit.rs
index d1253199..35bf3407 100644
--- a/src/winit.rs
+++ b/src/winit.rs
@@ -12,7 +12,6 @@ use smithay::reexports::winit::dpi::LogicalSize;
use smithay::reexports::winit::window::WindowBuilder;
use smithay::utils::Transform;
-use crate::backend::Backend;
use crate::input::{BackendAction, CompositorMod};
use crate::niri::OutputRenderElements;
use crate::utils::get_monotonic_time;
@@ -25,46 +24,6 @@ pub struct Winit {
damage_tracker: OutputDamageTracker,
}
-impl Backend for Winit {
- fn seat_name(&self) -> String {
- "winit".to_owned()
- }
-
- fn renderer(&mut self) -> &mut GlesRenderer {
- self.backend.renderer()
- }
-
- fn render(
- &mut self,
- niri: &mut Niri,
- output: &Output,
- elements: &[OutputRenderElements<GlesRenderer>],
- ) {
- let _span = tracy_client::span!("Winit::render");
-
- self.backend.bind().unwrap();
- let age = self.backend.buffer_age().unwrap();
- let res = self
- .damage_tracker
- .render_output(self.backend.renderer(), age, elements, [0.1, 0.1, 0.1, 1.0])
- .unwrap();
- if let Some(damage) = res.damage {
- self.backend.submit(Some(&damage)).unwrap();
-
- let mut presentation_feedbacks = niri.take_presentation_feedbacks(output, &res.states);
- let refresh = output.current_mode().unwrap().refresh as u32;
- presentation_feedbacks.presented::<_, smithay::utils::Monotonic>(
- get_monotonic_time(),
- refresh,
- 0,
- wp_presentation_feedback::Kind::empty(),
- );
-
- self.backend.window().request_redraw();
- }
- }
-}
-
impl Winit {
pub fn new(event_loop: LoopHandle<LoopData>) -> Self {
let builder = WindowBuilder::new()
@@ -100,7 +59,7 @@ impl Winit {
let timer = Timer::immediate();
event_loop
.insert_source(timer, move |_, _, data| {
- let winit = data.winit.as_mut().unwrap();
+ let winit = data.backend.winit().unwrap();
winit.dispatch(&mut data.niri);
TimeoutAction::ToDuration(Duration::from_micros(16667))
})
@@ -178,4 +137,42 @@ impl Winit {
Ok(()) => (),
}
}
+
+ pub fn seat_name(&self) -> String {
+ "winit".to_owned()
+ }
+
+ pub fn renderer(&mut self) -> &mut GlesRenderer {
+ self.backend.renderer()
+ }
+
+ pub fn render(
+ &mut self,
+ niri: &mut Niri,
+ output: &Output,
+ elements: &[OutputRenderElements<GlesRenderer>],
+ ) {
+ let _span = tracy_client::span!("Winit::render");
+
+ self.backend.bind().unwrap();
+ let age = self.backend.buffer_age().unwrap();
+ let res = self
+ .damage_tracker
+ .render_output(self.backend.renderer(), age, elements, [0.1, 0.1, 0.1, 1.0])
+ .unwrap();
+ if let Some(damage) = res.damage {
+ self.backend.submit(Some(&damage)).unwrap();
+
+ let mut presentation_feedbacks = niri.take_presentation_feedbacks(output, &res.states);
+ let refresh = output.current_mode().unwrap().refresh as u32;
+ presentation_feedbacks.presented::<_, smithay::utils::Monotonic>(
+ get_monotonic_time(),
+ refresh,
+ 0,
+ wp_presentation_feedback::Kind::empty(),
+ );
+
+ self.backend.window().request_redraw();
+ }
+ }
}