diff options
| author | Michael Yang <admin@my4ng.dev> | 2024-08-22 18:58:07 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-22 11:58:07 +0300 |
| commit | f1894f6f9a7470b8b1493cf96b28a48e8a704636 (patch) | |
| tree | d70a3ab350d39dea1b8240e2a92b281b01be5d12 /src/backend/tty.rs | |
| parent | dfc2d452c55d59d6d9014c98a9da3a082c4f7379 (diff) | |
| download | niri-f1894f6f9a7470b8b1493cf96b28a48e8a704636.tar.gz niri-f1894f6f9a7470b8b1493cf96b28a48e8a704636.tar.bz2 niri-f1894f6f9a7470b8b1493cf96b28a48e8a704636.zip | |
feature: add on-demand vrr (#586)
* feature: add on-demand vrr
* Don't require connector::Info in try_to_set_vrr
* Improve VRR help message
* Rename connector_handle => connector
* Fix tracy span name
* Move on demand vrr flag set higher
* wiki: Mention on-demand VRR
---------
Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
Diffstat (limited to 'src/backend/tty.rs')
| -rw-r--r-- | src/backend/tty.rs | 88 |
1 files changed, 50 insertions, 38 deletions
diff --git a/src/backend/tty.rs b/src/backend/tty.rs index 10becafe..1d891d91 100644 --- a/src/backend/tty.rs +++ b/src/backend/tty.rs @@ -180,6 +180,7 @@ struct TtyOutputState { struct Surface { name: String, compositor: GbmDrmCompositor, + connector: connector::Handle, dmabuf_feedback: Option<SurfaceDmabufFeedback>, gamma_props: Option<GammaProps>, /// Gamma change to apply upon session resume. @@ -426,18 +427,6 @@ impl Tty { } // Restore VRR. - let Some(connector) = - surface.compositor.pending_connectors().into_iter().next() - else { - error!("surface pending connectors is empty"); - continue; - }; - let Some(connector) = device.drm_scanner.connectors().get(&connector) - else { - error!("missing enabled connector in drm_scanner"); - continue; - }; - let output = niri .global_space .outputs() @@ -457,7 +446,7 @@ impl Tty { try_to_change_vrr( &device.drm, - connector, + surface.connector, *crtc, surface, output_state, @@ -832,15 +821,13 @@ impl Tty { let mut vrr_enabled = false; if let Some(capable) = is_vrr_capable(&device.drm, connector.handle()) { if capable { - let word = if config.variable_refresh_rate { - "enabling" - } else { - "disabling" - }; + // Even if on-demand, we still disable it until later checks. + let vrr = config.is_vrr_always_on(); + let word = if vrr { "enabling" } else { "disabling" }; - match set_vrr_enabled(&device.drm, crtc, config.variable_refresh_rate) { + match set_vrr_enabled(&device.drm, crtc, vrr) { Ok(enabled) => { - if enabled != config.variable_refresh_rate { + if enabled != vrr { warn!("failed {} VRR", word); } @@ -851,13 +838,13 @@ impl Tty { } } } else { - if config.variable_refresh_rate { + if !config.is_vrr_always_off() { warn!("cannot enable VRR because connector is not vrr_capable"); } // Try to disable it anyway to work around a bug where resetting DRM state causes // vrr_capable to be reset to 0, potentially leaving VRR_ENABLED at 1. - let res = set_vrr_enabled(&device.drm, crtc, config.variable_refresh_rate); + let res = set_vrr_enabled(&device.drm, crtc, false); if matches!(res, Ok(true)) { warn!("error disabling VRR"); @@ -865,7 +852,7 @@ impl Tty { vrr_enabled = true; } } - } else if config.variable_refresh_rate { + } else if !config.is_vrr_always_off() { warn!("cannot enable VRR because connector is not vrr_capable"); } @@ -1017,6 +1004,7 @@ impl Tty { let surface = Surface { name: output_name.clone(), + connector: connector.handle(), compositor, dmabuf_feedback, gamma_props, @@ -1661,6 +1649,33 @@ impl Tty { } } + pub fn set_output_on_demand_vrr(&mut self, niri: &mut Niri, output: &Output, enable_vrr: bool) { + let _span = tracy_client::span!("Tty::set_output_on_demand_vrr"); + + let output_state = niri.output_state.get_mut(output).unwrap(); + output_state.on_demand_vrr_enabled = enable_vrr; + if output_state.frame_clock.vrr() == enable_vrr { + return; + } + for (&node, device) in self.devices.iter_mut() { + for (&crtc, surface) in device.surfaces.iter_mut() { + let tty_state: &TtyOutputState = output.user_data().get().unwrap(); + if tty_state.node == node && tty_state.crtc == crtc { + try_to_change_vrr( + &device.drm, + surface.connector, + crtc, + surface, + output_state, + enable_vrr, + ); + self.refresh_ipc_outputs(niri); + return; + } + } + } + } + pub fn on_output_config_changed(&mut self, niri: &mut Niri) { let _span = tracy_client::span!("Tty::on_output_config_changed"); @@ -1675,9 +1690,7 @@ impl Tty { let mut to_connect = vec![]; for (&node, device) in &mut self.devices { - for surface in device.surfaces.values_mut() { - let crtc = surface.compositor.crtc(); - + for (&crtc, surface) in device.surfaces.iter_mut() { let config = self .config .borrow() @@ -1691,12 +1704,8 @@ impl Tty { } // Check if we need to change the mode. - let Some(connector) = surface.compositor.pending_connectors().into_iter().next() + let Some(connector) = device.drm_scanner.connectors().get(&surface.connector) else { - error!("surface pending connectors is empty"); - continue; - }; - let Some(connector) = device.drm_scanner.connectors().get(&connector) else { error!("missing enabled connector in drm_scanner"); continue; }; @@ -1707,8 +1716,9 @@ impl Tty { }; let change_mode = surface.compositor.pending_mode() != mode; - let change_vrr = surface.vrr_enabled != config.variable_refresh_rate; - if !change_mode && !change_vrr { + let change_always_vrr = surface.vrr_enabled != config.is_vrr_always_on(); + let is_on_demand_vrr = config.is_vrr_on_demand(); + if !change_mode && !change_always_vrr && !is_on_demand_vrr { continue; } @@ -1729,14 +1739,16 @@ impl Tty { continue; }; - if change_vrr { + if (is_on_demand_vrr && surface.vrr_enabled != output_state.on_demand_vrr_enabled) + || (!is_on_demand_vrr && change_always_vrr) + { try_to_change_vrr( &device.drm, - connector, + connector.handle(), crtc, surface, output_state, - config.variable_refresh_rate, + !surface.vrr_enabled, ); } @@ -2388,7 +2400,7 @@ pub fn set_gamma_for_crtc( fn try_to_change_vrr( device: &DrmDevice, - connector: &connector::Info, + connector: connector::Handle, crtc: crtc::Handle, surface: &mut Surface, output_state: &mut crate::niri::OutputState, @@ -2396,7 +2408,7 @@ fn try_to_change_vrr( ) { let _span = tracy_client::span!("try_to_change_vrr"); - if is_vrr_capable(device, connector.handle()) == Some(true) { + if is_vrr_capable(device, connector) == Some(true) { let word = if enable_vrr { "enabling" } else { "disabling" }; match set_vrr_enabled(device, crtc, enable_vrr) { |
