Skip to content

Commit

Permalink
Merge pull request #276 from mahkoh/jorth/commit-timing
Browse files Browse the repository at this point in the history
wayland: implement commit-timing-v1
  • Loading branch information
mahkoh authored Oct 11, 2024
2 parents 4742c0f + fac5445 commit d75cbb8
Show file tree
Hide file tree
Showing 21 changed files with 576 additions and 50 deletions.
1 change: 1 addition & 0 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ Jay supports the following wayland protocols:
| wl_shm | 2 | |
| wl_subcompositor | 1 | |
| wp_alpha_modifier_v1 | 1 | |
| wp_commit_timing_manager_v1 | 1 | |
| wp_content_type_manager_v1 | 1 | |
| wp_cursor_shape_manager_v1 | 1 | |
| wp_drm_lease_device_v1 | 1 | |
Expand Down
1 change: 1 addition & 0 deletions release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Implement screencast session restoration.
- Fix screen sharing in zoom.
- Implement wp-fifo-v1.
- Implement wp-commit-timing-v1.

# 1.6.0 (2024-09-25)

Expand Down
9 changes: 9 additions & 0 deletions src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ pub struct Mode {
pub refresh_rate_millihz: u32,
}

impl Mode {
pub fn refresh_nsec(&self) -> u64 {
match self.refresh_rate_millihz {
0 => u64::MAX,
n => 1_000_000_000_000 / (n as u64),
}
}
}

#[derive(Clone, Debug)]
pub struct MonitorInfo {
pub modes: Vec<Mode>,
Expand Down
20 changes: 14 additions & 6 deletions src/backends/metal/present.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,15 @@ impl MetalConnector {
if !self.can_present.get() {
continue;
}
let Some(node) = self.state.root.outputs.get(&self.connector_id) else {
continue;
};
let mut expected_sequence = self.sequence.get() + 1;
let mut start = Time::now_unchecked();
let use_frame_scheduling = !self.try_async_flip();
if use_frame_scheduling {
let next_present = self
.next_flip_nsec
.next_vblank_nsec
.get()
.saturating_sub(self.pre_commit_margin.get())
.saturating_sub(self.post_commit_margin.get());
Expand All @@ -118,7 +121,15 @@ impl MetalConnector {
}
}
frame!(frame_name);
if let Err(e) = self.present_once().await {
{
let now = start.nsec();
let flip = match self.try_async_flip() {
true => now,
false => self.next_vblank_nsec.get(),
};
node.before_latch(flip).await;
}
if let Err(e) = self.present_once(&node).await {
log::error!("Could not present: {}", ErrorFmt(e));
continue;
}
Expand All @@ -138,17 +149,14 @@ impl MetalConnector {
}
}

async fn present_once(&self) -> Result<(), MetalError> {
async fn present_once(&self, node: &Rc<OutputNode>) -> Result<(), MetalError> {
let version = self.version.get();
if !self.can_present.get() {
return Ok(());
}
if !self.backend.check_render_context(&self.dev) {
return Ok(());
}
let Some(node) = self.state.root.outputs.get(&self.connector_id) else {
return Ok(());
};
let crtc = match self.crtc.get() {
Some(crtc) => crtc,
_ => return Ok(()),
Expand Down
10 changes: 6 additions & 4 deletions src/backends/metal/video.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ pub struct MetalConnector {
pub has_damage: NumCell<u64>,
pub cursor_changed: Cell<bool>,
pub cursor_damage: Cell<bool>,
pub next_flip_nsec: Cell<u64>,
pub next_vblank_nsec: Cell<u64>,

pub display: RefCell<ConnectorDisplayData>,

Expand Down Expand Up @@ -1085,7 +1085,7 @@ fn create_connector(
active_framebuffer: Default::default(),
next_framebuffer: Default::default(),
direct_scanout_active: Cell::new(false),
next_flip_nsec: Cell::new(0),
next_vblank_nsec: Cell::new(0),
tearing_requested: Cell::new(false),
try_switch_format: Cell::new(false),
version: Default::default(),
Expand Down Expand Up @@ -1944,7 +1944,7 @@ impl MetalBackend {
self.state.vblank(connector.connector_id);
let dd = connector.display.borrow();
connector
.next_flip_nsec
.next_vblank_nsec
.set(time_ns as u64 + dd.refresh as u64);
}

Expand Down Expand Up @@ -1993,7 +1993,9 @@ impl MetalBackend {
{
connector.schedule_present();
}
connector.next_flip_nsec.set(time_ns + dd.refresh as u64);
if connector.presentation_is_sync.get() {
connector.next_vblank_nsec.set(time_ns + dd.refresh as u64);
}
{
let mut flags = KIND_HW_COMPLETION;
if connector.presentation_is_sync.get() {
Expand Down
3 changes: 3 additions & 0 deletions src/backends/x.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use {
gfx_api::{AcquireSync, GfxContext, GfxError, GfxFramebuffer, GfxTexture, ReleaseSync},
ifs::wl_output::OutputId,
state::State,
time::Time,
utils::{
clonecell::CloneCell, copyhashmap::CopyHashMap, errorfmt::ErrorFmt, numcell::NumCell,
queue::AsyncQueue, syncqueue::SyncQueue,
Expand Down Expand Up @@ -745,6 +746,8 @@ impl XBackend {
image.last_serial.set(serial);

if let Some(node) = self.state.root.outputs.get(&output.id) {
let now = Time::now_unchecked().nsec();
node.before_latch(now).await;
let res = self.state.present_output(
&node,
&image.fb.get(),
Expand Down
4 changes: 3 additions & 1 deletion src/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,7 @@ fn create_dummy_output(state: &Rc<State>) {
&backend::Mode {
width: 0,
height: 0,
refresh_rate_millihz: 0,
refresh_rate_millihz: 40_000,
},
0,
0,
Expand Down Expand Up @@ -582,8 +582,10 @@ fn create_dummy_output(state: &Rc<State>) {
vblank_event: Default::default(),
latch_event: Default::default(),
presentation_event: Default::default(),
render_margin_ns: Default::default(),
flip_margin_ns: Default::default(),
ext_copy_sessions: Default::default(),
before_latch_event: Default::default(),
});
let dummy_workspace = Rc::new(WorkspaceNode {
id: state.node_ids.next(),
Expand Down
2 changes: 2 additions & 0 deletions src/globals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use {
wl_subcompositor::WlSubcompositorGlobal,
wl_surface::xwayland_shell_v1::XwaylandShellV1Global,
wp_alpha_modifier_v1::WpAlphaModifierV1Global,
wp_commit_timing_manager_v1::WpCommitTimingManagerV1Global,
wp_content_type_manager_v1::WpContentTypeManagerV1Global,
wp_cursor_shape_manager_v1::WpCursorShapeManagerV1Global,
wp_fifo_manager_v1::WpFifoManagerV1Global,
Expand Down Expand Up @@ -205,6 +206,7 @@ impl Globals {
add_singleton!(ExtForeignToplevelImageCaptureSourceManagerV1Global);
add_singleton!(ExtImageCopyCaptureManagerV1Global);
add_singleton!(WpFifoManagerV1Global);
add_singleton!(WpCommitTimingManagerV1Global);
}

pub fn add_backend_singletons(&self, backend: &Rc<dyn Backend>) {
Expand Down
1 change: 1 addition & 0 deletions src/ifs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ pub mod wl_shm_pool;
pub mod wl_subcompositor;
pub mod wl_surface;
pub mod wp_alpha_modifier_v1;
pub mod wp_commit_timing_manager_v1;
pub mod wp_content_type_manager_v1;
pub mod wp_content_type_v1;
pub mod wp_cursor_shape_device_v1;
Expand Down
2 changes: 2 additions & 0 deletions src/ifs/wl_output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ pub struct WlOutputGlobal {
pub pos: Cell<Rect>,
pub output_id: Rc<OutputId>,
pub mode: Cell<backend::Mode>,
pub refresh_nsec: Cell<u64>,
pub modes: Vec<backend::Mode>,
pub formats: CloneCell<Rc<Vec<&'static Format>>>,
pub format: Cell<&'static Format>,
Expand Down Expand Up @@ -157,6 +158,7 @@ impl WlOutputGlobal {
pos: Cell::new(Rect::new_sized(x, y, width, height).unwrap()),
output_id: output_id.clone(),
mode: Cell::new(*mode),
refresh_nsec: Cell::new(mode.refresh_nsec()),
modes,
formats: CloneCell::new(Rc::new(vec![])),
format: Cell::new(XRGB8888),
Expand Down
24 changes: 21 additions & 3 deletions src/ifs/wl_surface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pub mod dnd_icon;
pub mod ext_session_lock_surface_v1;
pub mod wl_subsurface;
pub mod wp_alpha_modifier_surface_v1;
pub mod wp_commit_timer_v1;
pub mod wp_fifo_v1;
pub mod wp_fractional_scale_v1;
pub mod wp_linux_drm_syncobj_surface_v1;
Expand Down Expand Up @@ -47,6 +48,7 @@ use {
dnd_icon::DndIcon,
wl_subsurface::{PendingSubsurfaceData, SubsurfaceId, WlSubsurface},
wp_alpha_modifier_surface_v1::WpAlphaModifierSurfaceV1,
wp_commit_timer_v1::WpCommitTimerV1,
wp_fifo_v1::WpFifoV1,
wp_fractional_scale_v1::WpFractionalScaleV1,
wp_linux_drm_syncobj_surface_v1::WpLinuxDrmSyncobjSurfaceV1,
Expand All @@ -60,14 +62,15 @@ use {
wp_presentation_feedback::WpPresentationFeedback,
zwp_linux_dmabuf_feedback_v1::ZwpLinuxDmabufFeedbackV1,
},
io_uring::IoUringError,
leaks::Tracker,
object::{Object, Version},
rect::{DamageQueue, Rect, Region},
renderer::Renderer,
tree::{
ContainerNode, FindTreeResult, FoundNode, LatchListener, Node, NodeId, NodeVisitor,
NodeVisitorBase, OutputNode, PlaceholderNode, PresentationListener, ToplevelNode,
VblankListener,
BeforeLatchListener, BeforeLatchResult, ContainerNode, FindTreeResult, FoundNode,
LatchListener, Node, NodeId, NodeVisitor, NodeVisitorBase, OutputNode, PlaceholderNode,
PresentationListener, ToplevelNode, VblankListener,
},
utils::{
cell_ext::CellExt, clonecell::CloneCell, copyhashmap::CopyHashMap,
Expand Down Expand Up @@ -321,6 +324,8 @@ pub struct WlSurface {
latched_commit_version: Cell<u64>,
fifo: CloneCell<Option<Rc<WpFifoV1>>>,
clear_fifo_on_vblank: Cell<bool>,
commit_timer: CloneCell<Option<Rc<WpCommitTimerV1>>>,
before_latch_listener: EventListener<dyn BeforeLatchListener>,
}

impl Debug for WlSurface {
Expand Down Expand Up @@ -444,6 +449,7 @@ struct PendingState {
explicit_sync: bool,
fifo_barrier_set: bool,
fifo_barrier_wait: bool,
commit_time: Option<u64>,
}

struct AttachedSubsurfaceState {
Expand Down Expand Up @@ -494,6 +500,7 @@ impl PendingState {
opt!(tearing);
opt!(content_type);
opt!(alpha_multiplier);
opt!(commit_time);
{
let (dx1, dy1) = self.offset;
let (dx2, dy2) = mem::take(&mut next.offset);
Expand Down Expand Up @@ -648,6 +655,8 @@ impl WlSurface {
latched_commit_version: Default::default(),
fifo: Default::default(),
clear_fifo_on_vblank: Default::default(),
commit_timer: Default::default(),
before_latch_listener: EventListener::new(slf.clone()),
}
}

Expand Down Expand Up @@ -1657,6 +1666,7 @@ impl Object for WlSurface {
self.alpha_modifier.take();
self.text_input_connections.clear();
self.fifo.take();
self.commit_timer.take();
}
}

Expand Down Expand Up @@ -2001,6 +2011,8 @@ pub enum WlSurfaceError {
CreateAsyncShmTexture(#[source] GfxError),
#[error("Could not prepare upload to a shm texture")]
PrepareAsyncUpload(#[source] GfxError),
#[error("Could not register a commit timeout")]
RegisterCommitTimeout(#[source] IoUringError),
}
efrom!(WlSurfaceError, ClientError);
efrom!(WlSurfaceError, XdgSurfaceError);
Expand Down Expand Up @@ -2134,6 +2146,12 @@ impl VblankListener for WlSurface {
}
}

impl BeforeLatchListener for WlSurface {
fn before_latch(self: Rc<Self>, present: u64) -> BeforeLatchResult {
self.commit_timeline.before_latch(&self, present)
}
}

impl LatchListener for WlSurface {
fn after_latch(self: Rc<Self>, _on: &OutputNode, tearing: bool) {
if self.visible.get() {
Expand Down
Loading

0 comments on commit d75cbb8

Please sign in to comment.