Skip to content

Commit

Permalink
WIP DPMS with wlr-output-power-management-unstable-v1 protocol
Browse files Browse the repository at this point in the history
  • Loading branch information
ids1024 committed Oct 10, 2024
1 parent a4d875e commit 4e823fa
Show file tree
Hide file tree
Showing 9 changed files with 327 additions and 6 deletions.
23 changes: 22 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ profiling = { version = "1.0" }
rustix = { version = "0.38.32", features = ["process"] }
smallvec = "1.13.2"
rand = "0.8.5"
drm-ffi = "0.8.0"

[dependencies.id_tree]
branch = "feature/copy_clone"
Expand Down Expand Up @@ -117,4 +118,5 @@ inherits = "release"
lto = "fat"

[patch."https://github.com/Smithay/smithay.git"]
smithay = { git = "https://github.com/smithay//smithay", rev = "df79eeb" }
#smithay = { git = "https://github.com/smithay//smithay", rev = "df79eeb" }
smithay = { git = "https://github.com/ids1024/smithay", branch = "dpms" }
3 changes: 2 additions & 1 deletion src/backend/kms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ use std::{
};

mod device;
mod drm_helpers;
pub(crate) mod drm_helpers;
pub mod render;
mod socket;
mod surface;
pub(crate) use surface::Surface;

use device::*;
pub use surface::Timings;
Expand Down
51 changes: 48 additions & 3 deletions src/backend/kms/surface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,9 @@ static NVIDIA_LOGO: &'static [u8] = include_bytes!("../../../../resources/icons/

#[derive(Debug)]
pub struct Surface {
pub(super) connector: connector::Handle,
pub(crate) connector: connector::Handle,
pub(super) crtc: crtc::Handle,
pub(super) output: Output,
pub(crate) output: Output,
known_nodes: HashSet<DrmNode>,

active: Arc<AtomicBool>,
Expand All @@ -114,6 +114,8 @@ pub struct Surface {
loop_handle: LoopHandle<'static, State>,
thread_command: Sender<ThreadCommand>,
thread_token: RegistrationToken,

dpms: bool,
}

pub struct SurfaceThreadState {
Expand Down Expand Up @@ -238,6 +240,7 @@ pub enum ThreadCommand {
ScheduleRender,
SetMode(Mode, SyncSender<Result<()>>),
End,
DpmsOff,
}

#[derive(Debug)]
Expand Down Expand Up @@ -350,6 +353,7 @@ impl Surface {
loop_handle: evlh.clone(),
thread_command: tx,
thread_token,
dpms: true,
})
}

Expand Down Expand Up @@ -380,7 +384,9 @@ impl Surface {
}

pub fn schedule_render(&self) {
let _ = self.thread_command.send(ThreadCommand::ScheduleRender);
if self.dpms {
let _ = self.thread_command.send(ThreadCommand::ScheduleRender);
}
}

pub fn set_mirroring(&mut self, output: Option<Output>) {
Expand Down Expand Up @@ -431,6 +437,21 @@ impl Surface {

rx.recv().context("Surface thread died")?
}

pub fn get_dpms(&mut self) -> bool {
self.dpms
}

pub fn set_dpms(&mut self, on: bool) {
if self.dpms != on {
self.dpms = on;
if on {
self.schedule_render();
} else {
let _ = self.thread_command.send(ThreadCommand::DpmsOff);
}
}
}
}

impl Drop for Surface {
Expand Down Expand Up @@ -540,6 +561,30 @@ fn surface_thread(
let _ = result.send(Err(anyhow::anyhow!("Set mode with inactive surface")));
}
}
Event::Msg(ThreadCommand::DpmsOff) => {
if let Some(compositor) = state.compositor.as_mut() {
if let Err(err) = compositor.disable() {
error!("Failed to set DPMS off: {:?}", err);
}
match std::mem::replace(&mut state.state, QueueState::Idle) {
QueueState::Idle => {}
QueueState::Queued(token)
| QueueState::WaitingForEstimatedVBlank(token) => {
state.loop_handle.remove(token);
}
QueueState::WaitingForVBlank { .. } => {
state.timings.discard_current_frame()
}
QueueState::WaitingForEstimatedVBlankAndQueued {
estimated_vblank,
queued_render,
} => {
state.loop_handle.remove(estimated_vblank);
state.loop_handle.remove(queued_render);
}
};
}
}
Event::Closed | Event::Msg(ThreadCommand::End) => {
signal.stop();
signal.wakeup();
Expand Down
4 changes: 4 additions & 0 deletions src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use crate::{
drm::WlDrmState,
image_source::ImageSourceState,
output_configuration::OutputConfigurationState,
output_power::OutputPowerState,
screencopy::ScreencopyState,
toplevel_info::ToplevelInfoState,
toplevel_management::{ManagementCapabilities, ToplevelManagementState},
Expand Down Expand Up @@ -198,6 +199,7 @@ pub struct Common {
pub keyboard_shortcuts_inhibit_state: KeyboardShortcutsInhibitState,
pub output_state: OutputManagerState,
pub output_configuration_state: OutputConfigurationState<State>,
pub output_power_state: OutputPowerState,
pub presentation_state: PresentationState,
pub primary_selection_state: PrimarySelectionState,
pub data_control_state: Option<DataControlState>,
Expand Down Expand Up @@ -494,6 +496,7 @@ impl State {
let keyboard_shortcuts_inhibit_state = KeyboardShortcutsInhibitState::new::<Self>(dh);
let output_state = OutputManagerState::new_with_xdg_output::<Self>(dh);
let output_configuration_state = OutputConfigurationState::new(dh, client_is_privileged);
let output_power_state = OutputPowerState::new::<Self, _>(dh, client_is_privileged);
let presentation_state = PresentationState::new::<Self>(dh, clock.id() as u32);
let primary_selection_state = PrimarySelectionState::new::<Self>(dh);
let image_source_state = ImageSourceState::new::<Self, _>(dh, client_is_privileged);
Expand Down Expand Up @@ -600,6 +603,7 @@ impl State {
keyboard_shortcuts_inhibit_state,
output_state,
output_configuration_state,
output_power_state,
presentation_state,
primary_selection_state,
data_control_state,
Expand Down
1 change: 1 addition & 0 deletions src/wayland/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub mod keyboard_shortcuts_inhibit;
pub mod layer_shell;
pub mod output;
pub mod output_configuration;
pub mod output_power;
pub mod pointer_constraints;
pub mod pointer_gestures;
pub mod presentation;
Expand Down
46 changes: 46 additions & 0 deletions src/wayland/handlers/output_power.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-License-Identifier: GPL-3.0-only

use smithay::{output::Output, reexports::wayland_server::protocol::wl_output::WlOutput};

use crate::{
backend::kms::Surface,
state::{BackendData, State},
wayland::protocols::output_power::{
delegate_output_power, OutputPowerHandler, OutputPowerState,
},
};

fn kms_surface_for_wl_output<'a>(
state: &'a mut State,
wl_output: &WlOutput,
) -> Option<&'a mut Surface> {
let output = Output::from_resource(wl_output)?;
if let BackendData::Kms(ref mut kms_state) = &mut state.backend {
kms_state
.drm_devices
.values_mut()
.flat_map(|device| device.surfaces.values_mut())
.find(|surface| surface.output == output)
} else {
None
}
}

impl OutputPowerHandler for State {
fn output_power_state(&mut self) -> &mut OutputPowerState {
&mut self.common.output_power_state
}

fn get_dpms(&mut self, wl_output: &WlOutput) -> Option<bool> {
let surface = kms_surface_for_wl_output(self, wl_output)?;
Some(surface.get_dpms())
}

fn set_dpms(&mut self, wl_output: &WlOutput, on: bool) {
if let Some(surface) = kms_surface_for_wl_output(self, wl_output) {
surface.set_dpms(on);
}
}
}

delegate_output_power!(State);
1 change: 1 addition & 0 deletions src/wayland/protocols/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
pub mod drm;
pub mod image_source;
pub mod output_configuration;
pub mod output_power;
pub mod overlap_notify;
pub mod screencopy;
pub mod toplevel_info;
Expand Down
Loading

0 comments on commit 4e823fa

Please sign in to comment.