Skip to content

Commit

Permalink
output-configuration: Support cosmic-ext v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Drakulix committed Nov 27, 2024
1 parent 80965a6 commit 81b9fb1
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 25 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

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

6 changes: 5 additions & 1 deletion src/backend/kms/device.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-3.0-only

use crate::{
config::{OutputConfig, OutputState},
config::{AdaptiveSync, OutputConfig, OutputState},
shell::Shell,
utils::prelude::*,
};
Expand Down Expand Up @@ -664,6 +664,10 @@ fn populate_modes(
max_bpc,
scale,
transform,
// Try opportunistic VRR by default,
// if not supported this will be turned off on `resume`,
// when we have the `Surface` to actually check for support.
vrr: AdaptiveSync::Enabled,
..std::mem::take(&mut *output_config)
};

Expand Down
3 changes: 3 additions & 0 deletions src/backend/kms/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,9 @@ impl KmsState {

match surface.resume(drm_surface, gbm, cursor_size) {
Ok(_) => {
surface.output.set_adaptive_sync_support(
surface.adaptive_sync_support().ok(),
);
if surface.use_adaptive_sync(vrr)? {
surface.output.set_adaptive_sync(vrr);
} else {
Expand Down
8 changes: 8 additions & 0 deletions src/backend/kms/surface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,14 @@ impl Surface {
rx.recv().context("Surface thread died")?
}

pub fn adaptive_sync_support(&self) -> Result<VrrSupport> {
let (tx, rx) = std::sync::mpsc::sync_channel(1);
let _ = self
.thread_command
.send(ThreadCommand::AdaptiveSyncAvailable(tx));
rx.recv().context("Surface thread died")?
}

pub fn use_adaptive_sync(&mut self, vrr: AdaptiveSync) -> Result<bool> {
if vrr != AdaptiveSync::Disabled {
let (tx, rx) = std::sync::mpsc::sync_channel(1);
Expand Down
31 changes: 30 additions & 1 deletion src/utils/prelude.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use smithay::{
backend::drm::VrrSupport as Support,
output::{Output, WeakOutput},
utils::{Rectangle, Transform},
};
Expand All @@ -21,6 +22,8 @@ pub trait OutputExt {
fn geometry(&self) -> Rectangle<i32, Global>;
fn adaptive_sync(&self) -> AdaptiveSync;
fn set_adaptive_sync(&self, vrr: AdaptiveSync);
fn adaptive_sync_support(&self) -> Option<Support>;
fn set_adaptive_sync_support(&self, vrr: Option<Support>);
fn mirroring(&self) -> Option<Output>;
fn set_mirroring(&self, output: Option<Output>);

Expand All @@ -30,7 +33,7 @@ pub trait OutputExt {
}

struct Vrr(AtomicU8);

struct VrrSupport(AtomicU8);
struct Mirroring(Mutex<Option<WeakOutput>>);

impl OutputExt for Output {
Expand Down Expand Up @@ -72,6 +75,32 @@ impl OutputExt for Output {
);
}

fn adaptive_sync_support(&self) -> Option<Support> {
self.user_data()
.get::<VrrSupport>()
.map(|vrr| match vrr.0.load(Ordering::SeqCst) {
0 => None,
2 => Some(Support::RequiresModeset),
3 => Some(Support::Supported),
_ => Some(Support::NotSupported),
})
.flatten()
}

fn set_adaptive_sync_support(&self, vrr: Option<Support>) {
let user_data = self.user_data();
user_data.insert_if_missing_threadsafe(|| VrrSupport(AtomicU8::new(0)));
user_data.get::<VrrSupport>().unwrap().0.store(
match vrr {
None => 0,
Some(Support::NotSupported) => 1,
Some(Support::RequiresModeset) => 2,
Some(Support::Supported) => 3,
},
Ordering::SeqCst,
);
}

fn mirroring(&self) -> Option<Output> {
self.user_data().get::<Mirroring>().and_then(|mirroring| {
mirroring
Expand Down
8 changes: 2 additions & 6 deletions src/wayland/handlers/output_configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use smithay::{output::Output, utils::Point};
use tracing::{error, warn};

use crate::{
config::{AdaptiveSync, OutputConfig, OutputState},
config::{OutputConfig, OutputState},
state::State,
wayland::protocols::output_configuration::{
delegate_output_configuration, ModeConfiguration, OutputConfiguration,
Expand Down Expand Up @@ -120,11 +120,7 @@ impl State {
current_config.position = (position.x as u32, position.y as u32);
}
if let Some(vrr) = adaptive_sync {
current_config.vrr = if *vrr {
AdaptiveSync::Force
} else {
AdaptiveSync::Disabled
};
current_config.vrr = *vrr;
}
if let Some(mirror) = mirroring {
current_config.enabled = OutputState::Mirroring(mirror.name());
Expand Down
23 changes: 23 additions & 0 deletions src/wayland/protocols/output_configuration/handlers/cosmic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,29 @@ where
}
}
}
zcosmic_output_configuration_head_v1::Request::SetAdaptiveSyncExt { state } => {
if let Ok(obj) = obj.upgrade() {
if let Some(data) = obj.data::<PendingOutputConfiguration>() {
let mut pending = data.lock().unwrap();
if pending.adaptive_sync.is_some() {
obj.post_error(
zwlr_output_configuration_head_v1::Error::AlreadySet,
format!("{:?} already had an adaptive_sync state configured", obj),
);
return;
}
pending.adaptive_sync = match state.into_result() {
Ok(zcosmic_output_head_v1::AdaptiveSyncStateExt::Always) => {
Some(AdaptiveSync::Force)
}
Ok(zcosmic_output_head_v1::AdaptiveSyncStateExt::Automatic) => {
Some(AdaptiveSync::Enabled)
}
_ => Some(AdaptiveSync::Disabled),
};
}
}
}
_ => {}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/wayland/protocols/output_configuration/handlers/wlr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -481,8 +481,8 @@ where
}
pending.adaptive_sync = Some(match state.into_result() {
Ok(state) => match state {
zwlr_output_head_v1::AdaptiveSyncState::Enabled => true,
_ => false,
zwlr_output_head_v1::AdaptiveSyncState::Enabled => AdaptiveSync::Force,
_ => AdaptiveSync::Disabled,
},
Err(err) => {
obj.post_error(
Expand Down
50 changes: 41 additions & 9 deletions src/wayland/protocols/output_configuration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
use cosmic_protocols::output_management::v1::server::{
zcosmic_output_configuration_head_v1::ZcosmicOutputConfigurationHeadV1,
zcosmic_output_configuration_v1::ZcosmicOutputConfigurationV1,
zcosmic_output_head_v1::ZcosmicOutputHeadV1, zcosmic_output_manager_v1::ZcosmicOutputManagerV1,
zcosmic_output_head_v1::{self, ZcosmicOutputHeadV1},
zcosmic_output_manager_v1::ZcosmicOutputManagerV1,
};
use smithay::{
backend::drm::VrrSupport,
output::{Mode, Output, WeakOutput},
reexports::{
wayland_protocols_wlr::output_management::v1::server::{
Expand Down Expand Up @@ -98,7 +100,7 @@ pub struct PendingOutputConfigurationInner {
position: Option<Point<i32, Logical>>,
transform: Option<Transform>,
scale: Option<f64>,
adaptive_sync: Option<bool>,
adaptive_sync: Option<AdaptiveSync>,
}
pub type PendingOutputConfiguration = Mutex<PendingOutputConfigurationInner>;

Expand All @@ -110,7 +112,7 @@ pub enum OutputConfiguration {
position: Option<Point<i32, Logical>>,
transform: Option<Transform>,
scale: Option<f64>,
adaptive_sync: Option<bool>,
adaptive_sync: Option<AdaptiveSync>,
},
Disabled,
}
Expand Down Expand Up @@ -178,7 +180,7 @@ where
);

let extension_global = dh.create_global::<D, ZcosmicOutputManagerV1, _>(
1,
2,
OutputMngrGlobalData {
filter: Box::new(client_filter),
},
Expand Down Expand Up @@ -434,11 +436,6 @@ where

let scale = output.current_scale().fractional_scale();
instance.obj.scale(scale);
if let Some(extension_obj) = instance.extension_obj.as_ref() {
extension_obj.scale_1000((scale * 1000.0).round() as i32);

extension_obj.mirroring(output.mirroring().map(|o| o.name()));
}

if instance.obj.version() >= zwlr_output_head_v1::EVT_ADAPTIVE_SYNC_SINCE {
instance
Expand All @@ -449,6 +446,41 @@ where
zwlr_output_head_v1::AdaptiveSyncState::Enabled
});
}

if let Some(extension_obj) = instance.extension_obj.as_ref() {
extension_obj.scale_1000((scale * 1000.0).round() as i32);

extension_obj.mirroring(output.mirroring().map(|o| o.name()));

if extension_obj.version() >= zcosmic_output_head_v1::EVT_ADAPTIVE_SYNC_EXT_SINCE {
extension_obj.adaptive_sync_ext(match output.adaptive_sync() {
AdaptiveSync::Disabled => {
zcosmic_output_head_v1::AdaptiveSyncStateExt::Disabled
}
AdaptiveSync::Enabled => {
zcosmic_output_head_v1::AdaptiveSyncStateExt::Automatic
}
AdaptiveSync::Force => zcosmic_output_head_v1::AdaptiveSyncStateExt::Always,
});

extension_obj.adaptive_sync_available(
match output
.adaptive_sync_support()
.unwrap_or(VrrSupport::NotSupported)
{
VrrSupport::NotSupported => {
zcosmic_output_head_v1::AdaptiveSyncAvailability::Unsupported
}
VrrSupport::RequiresModeset => {
zcosmic_output_head_v1::AdaptiveSyncAvailability::RequiresModeset
}
VrrSupport::Supported => {
zcosmic_output_head_v1::AdaptiveSyncAvailability::Supported
}
},
);
}
}
}

if instance.obj.version() >= zwlr_output_head_v1::EVT_MAKE_SINCE {
Expand Down

0 comments on commit 81b9fb1

Please sign in to comment.