aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-01-16 18:01:25 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-01-16 18:01:25 +0400
commiteb4946c3d8efb3da3b0370ed49da437007bfe165 (patch)
tree3bfa21fd151e97d6130a5cf7a18354c7144ffc6c /src/backend
parent5f440f7be3245ad2d357b49d2d2948bb931f661a (diff)
downloadniri-eb4946c3d8efb3da3b0370ed49da437007bfe165.tar.gz
niri-eb4946c3d8efb3da3b0370ed49da437007bfe165.tar.bz2
niri-eb4946c3d8efb3da3b0370ed49da437007bfe165.zip
tty: Extract pick_mode()
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/tty.rs143
1 files changed, 78 insertions, 65 deletions
diff --git a/src/backend/tty.rs b/src/backend/tty.rs
index a568e625..483c45b3 100644
--- a/src/backend/tty.rs
+++ b/src/backend/tty.rs
@@ -32,7 +32,7 @@ use smithay::output::{Mode, Output, OutputModeSource, PhysicalProperties, Subpix
use smithay::reexports::calloop::timer::{TimeoutAction, Timer};
use smithay::reexports::calloop::{Dispatcher, LoopHandle, RegistrationToken};
use smithay::reexports::drm::control::{
- connector, crtc, property, Device, Mode as DrmMode, ModeFlags, ModeTypeFlags,
+ self, connector, crtc, property, Device, Mode as DrmMode, ModeFlags, ModeTypeFlags,
};
use smithay::reexports::gbm::Modifier;
use smithay::reexports::input::Libinput;
@@ -620,74 +620,26 @@ impl Tty {
trace!("{m:?}");
}
- let mut mode = None;
-
- if let Some(target) = &config.mode {
- let refresh = target.refresh.map(|r| (r * 1000.).round() as i32);
-
- for m in connector.modes() {
- if m.size() != (target.width, target.height) {
- continue;
- }
-
- if let Some(refresh) = refresh {
- // If refresh is set, only pick modes with matching refresh.
- let wl_mode = Mode::from(*m);
- if wl_mode.refresh == refresh {
- mode = Some(m);
- }
- } else if let Some(curr) = mode {
- // If refresh isn't set, pick the mode with the highest refresh.
- if curr.vrefresh() < m.vrefresh() {
- mode = Some(m);
- }
+ let (mode, fallback) =
+ pick_mode(&connector, config.mode).ok_or_else(|| anyhow!("no mode"))?;
+ if fallback {
+ let target = config.mode.unwrap();
+ warn!(
+ "configured mode {}x{}{} could not be found, falling back to preferred",
+ target.width,
+ target.height,
+ if let Some(refresh) = target.refresh {
+ format!("@{refresh}")
} else {
- mode = Some(m);
- }
- }
-
- if mode.is_none() {
- warn!(
- "configured mode {}x{}{} could not be found, falling back to preferred",
- target.width,
- target.height,
- if let Some(refresh) = target.refresh {
- format!("@{refresh}")
- } else {
- String::new()
- },
- );
- }
- }
-
- if mode.is_none() {
- // Pick a preferred mode.
- for m in connector.modes() {
- if !m.mode_type().contains(ModeTypeFlags::PREFERRED) {
- continue;
- }
-
- if let Some(curr) = mode {
- if curr.vrefresh() < m.vrefresh() {
- mode = Some(m);
- }
- } else {
- mode = Some(m);
- }
- }
- }
-
- if mode.is_none() {
- // Last attempt.
- mode = connector.modes().first();
+ String::new()
+ },
+ );
}
-
- let mode = mode.ok_or_else(|| anyhow!("no mode"))?;
debug!("picking mode: {mode:?}");
let surface = device
.drm
- .create_surface(crtc, *mode, &[connector.handle()])?;
+ .create_surface(crtc, mode, &[connector.handle()])?;
// Create GBM allocator.
let gbm_flags = GbmBufferFlags::RENDERING | GbmBufferFlags::SCANOUT;
@@ -710,7 +662,7 @@ impl Tty {
},
);
- let wl_mode = Mode::from(*mode);
+ let wl_mode = Mode::from(mode);
output.change_current_state(Some(wl_mode), None, None, None);
output.set_preferred(wl_mode);
@@ -801,7 +753,7 @@ impl Tty {
let res = device.surfaces.insert(crtc, surface);
assert!(res.is_none(), "crtc must not have already existed");
- niri.add_output(output.clone(), Some(refresh_interval(*mode)));
+ niri.add_output(output.clone(), Some(refresh_interval(mode)));
// Power on all monitors if necessary and queue a redraw on the new one.
niri.event_loop.insert_idle(move |state| {
@@ -1459,3 +1411,64 @@ fn queue_estimated_vblank_timer(
.unwrap();
output_state.redraw_state = RedrawState::WaitingForEstimatedVBlank(token);
}
+
+fn pick_mode(
+ connector: &connector::Info,
+ target: Option<niri_config::Mode>,
+) -> Option<(control::Mode, bool)> {
+ let mut mode = None;
+ let mut fallback = false;
+
+ if let Some(target) = target {
+ let refresh = target.refresh.map(|r| (r * 1000.).round() as i32);
+
+ for m in connector.modes() {
+ if m.size() != (target.width, target.height) {
+ continue;
+ }
+
+ if let Some(refresh) = refresh {
+ // If refresh is set, only pick modes with matching refresh.
+ let wl_mode = Mode::from(*m);
+ if wl_mode.refresh == refresh {
+ mode = Some(m);
+ }
+ } else if let Some(curr) = mode {
+ // If refresh isn't set, pick the mode with the highest refresh.
+ if curr.vrefresh() < m.vrefresh() {
+ mode = Some(m);
+ }
+ } else {
+ mode = Some(m);
+ }
+ }
+
+ if mode.is_none() {
+ fallback = true;
+ }
+ }
+
+ if mode.is_none() {
+ // Pick a preferred mode.
+ for m in connector.modes() {
+ if !m.mode_type().contains(ModeTypeFlags::PREFERRED) {
+ continue;
+ }
+
+ if let Some(curr) = mode {
+ if curr.vrefresh() < m.vrefresh() {
+ mode = Some(m);
+ }
+ } else {
+ mode = Some(m);
+ }
+ }
+ }
+
+ if mode.is_none() {
+ // Last attempt.
+ mode = connector.modes().first();
+ }
+
+ mode.map(|m| (*m, fallback))
+}