metal: implement tearing
This commit is contained in:
parent
d355059ad9
commit
49f6304716
31 changed files with 726 additions and 51 deletions
|
|
@ -66,7 +66,7 @@ impl Global for JayCompositorGlobal {
|
|||
}
|
||||
|
||||
fn version(&self) -> u32 {
|
||||
2
|
||||
3
|
||||
}
|
||||
|
||||
fn required_caps(&self) -> ClientCaps {
|
||||
|
|
|
|||
|
|
@ -7,11 +7,13 @@ use {
|
|||
object::{Object, Version},
|
||||
scale::Scale,
|
||||
state::{ConnectorData, DrmDevData, OutputData},
|
||||
tree::{OutputNode, VrrMode},
|
||||
tree::{OutputNode, TearingMode, VrrMode},
|
||||
utils::{gfx_api_ext::GfxApiExt, transform_ext::TransformExt},
|
||||
wire::{jay_randr::*, JayRandrId},
|
||||
},
|
||||
jay_config::video::{GfxApi, Transform, VrrMode as ConfigVrrMode},
|
||||
jay_config::video::{
|
||||
GfxApi, TearingMode as ConfigTearingMode, Transform, VrrMode as ConfigVrrMode,
|
||||
},
|
||||
std::rc::Rc,
|
||||
thiserror::Error,
|
||||
};
|
||||
|
|
@ -24,6 +26,7 @@ pub struct JayRandr {
|
|||
}
|
||||
|
||||
const VRR_CAPABLE_SINCE: Version = Version(2);
|
||||
const TEARING_SINCE: Version = Version(3);
|
||||
|
||||
impl JayRandr {
|
||||
pub fn new(id: JayRandrId, client: &Rc<Client>, version: Version) -> Self {
|
||||
|
|
@ -116,6 +119,12 @@ impl JayRandr {
|
|||
});
|
||||
}
|
||||
}
|
||||
if self.version >= TEARING_SINCE {
|
||||
self.client.event(TearingState {
|
||||
self_id: self.id,
|
||||
mode: node.global.persistent.tearing_mode.get().to_config().0,
|
||||
});
|
||||
}
|
||||
let current_mode = global.mode.get();
|
||||
for mode in &global.modes {
|
||||
self.client.event(Mode {
|
||||
|
|
@ -325,7 +334,7 @@ impl JayRandrRequestHandler for JayRandr {
|
|||
return Ok(());
|
||||
};
|
||||
c.global.persistent.vrr_mode.set(mode);
|
||||
c.update_vrr_state();
|
||||
c.update_presentation_type();
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
@ -340,6 +349,22 @@ impl JayRandrRequestHandler for JayRandr {
|
|||
c.schedule.set_cursor_hz(req.hz);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_tearing_mode(
|
||||
&self,
|
||||
req: SetTearingMode<'_>,
|
||||
_slf: &Rc<Self>,
|
||||
) -> Result<(), Self::Error> {
|
||||
let Some(mode) = TearingMode::from_config(ConfigTearingMode(req.mode)) else {
|
||||
return Err(JayRandrError::UnknownTearingMode(req.mode));
|
||||
};
|
||||
let Some(c) = self.get_output_node(req.output) else {
|
||||
return Ok(());
|
||||
};
|
||||
c.global.persistent.tearing_mode.set(mode);
|
||||
c.update_presentation_type();
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
object_base! {
|
||||
|
|
@ -357,5 +382,7 @@ pub enum JayRandrError {
|
|||
ClientError(Box<ClientError>),
|
||||
#[error("Unknown VRR mode {0}")]
|
||||
UnknownVrrMode(u32),
|
||||
#[error("Unknown tearing mode {0}")]
|
||||
UnknownTearingMode(u32),
|
||||
}
|
||||
efrom!(JayRandrError, ClientError);
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use {
|
|||
object::{Object, Version},
|
||||
rect::Rect,
|
||||
state::{ConnectorData, State},
|
||||
tree::{calculate_logical_size, OutputNode, VrrMode},
|
||||
tree::{calculate_logical_size, OutputNode, TearingMode, VrrMode},
|
||||
utils::{clonecell::CloneCell, copyhashmap::CopyHashMap, transform_ext::TransformExt},
|
||||
wire::{wl_output::*, WlOutputId, ZxdgOutputV1Id},
|
||||
},
|
||||
|
|
@ -93,6 +93,7 @@ pub struct PersistentOutputState {
|
|||
pub pos: Cell<(i32, i32)>,
|
||||
pub vrr_mode: Cell<&'static VrrMode>,
|
||||
pub vrr_cursor_hz: Cell<Option<f64>>,
|
||||
pub tearing_mode: Cell<&'static TearingMode>,
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Hash)]
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ pub struct WlSurface {
|
|||
pub constraints: SmallMap<SeatId, Rc<SeatConstraint>, 1>,
|
||||
xwayland_serial: Cell<Option<u64>>,
|
||||
tearing_control: CloneCell<Option<Rc<WpTearingControlV1>>>,
|
||||
tearing: Cell<bool>,
|
||||
pub tearing: Cell<bool>,
|
||||
version: Version,
|
||||
pub has_content_type_manager: Cell<bool>,
|
||||
pub content_type: Cell<Option<ContentType>>,
|
||||
|
|
@ -1235,8 +1235,11 @@ impl WlSurface {
|
|||
self.opaque_region.set(region);
|
||||
}
|
||||
}
|
||||
let mut tearing_changed = false;
|
||||
if let Some(tearing) = pending.tearing.take() {
|
||||
self.tearing.set(tearing);
|
||||
if self.tearing.replace(tearing) != tearing {
|
||||
tearing_changed = true;
|
||||
}
|
||||
}
|
||||
if let Some(content_type) = pending.content_type.take() {
|
||||
self.content_type.set(content_type);
|
||||
|
|
@ -1305,6 +1308,13 @@ impl WlSurface {
|
|||
pending.buffer_damage.clear();
|
||||
pending.surface_damage.clear();
|
||||
pending.damage_full = false;
|
||||
if tearing_changed {
|
||||
if let Some(tl) = self.toplevel.get() {
|
||||
if tl.tl_data().is_fullscreen.get() {
|
||||
self.output.get().update_presentation_type();
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue