fix: nescope presentation handling, add mold to rootfs builds, update

mesa rev
This commit is contained in:
DatCaptainHorse
2026-09-30 14:07:03 +03:00
parent c283a3ea60
commit a493157d41
4 changed files with 19 additions and 51 deletions
+1 -1
View File
@@ -115,7 +115,7 @@ impl CompositorHandler for NescopeState {
window.on_commit();
self.game_frame_count += 1;
self.on_surface_committed(&root, &window);
self.present_now(&root, &window);
}
fn destroyed(&mut self, surface: &WlSurface) {
+2 -8
View File
@@ -416,16 +416,10 @@ fn main() {
}
// ── Input dispatch timer ────────────────────────────────────────────────
// Just input and cursor. High rate so a 1000 Hz mouse isn't coalesced;
// Just input and cursor. High rate so a 500 Hz (2 ms) mouse isn't coalesced;
// cursor piggybacks on the same tick because it is change-gated
// internally and costs nothing when idle.
//
// There is deliberately no frame-callback timer. Frame callbacks and
// presentation feedback are driven by commits — see
// NescopeState::on_surface_committed. A timer at any rate would pace
// the client against something other than its own submit loop, which
// is what produces the periodic hitches.
let tick_interval = Duration::from_millis(1);
let tick_interval = Duration::from_millis(2);
loop_handle
.insert_source(Timer::from_duration(tick_interval), move |_, _, data| {
if let Some(ref mut li) = data.libinput {
+12 -39
View File
@@ -190,6 +190,8 @@ pub struct NescopeState {
/// Timestamp of the last non-keyboard pointer event (for inactivity hiding).
pub last_pointer_activity: std::time::Instant,
pub presentation_seq: u64,
// ── Dimensions + frame rate ───────────────────────────────────────────
pub width: u32,
pub height: u32,
@@ -323,6 +325,7 @@ impl NescopeState {
last_sent_cursor_pos: Point::from((-1.0f64, -1.0f64)),
last_sent_cursor_status: 0xFF,
last_pointer_activity: std::time::Instant::now(),
presentation_seq: 0,
width,
height,
fps,
@@ -732,55 +735,25 @@ impl NescopeState {
}
}
// -----------------------------------------------------------------------
// Commit-driven frame signals
//
// Called from CompositorHandler::commit for every non-sync commit that
// belongs to a mapped window. Fires the wl_surface.frame callbacks the
// client asked for and resolves the wp_presentation_feedback for the
// frame that just arrived.
//
// NOT driven by a timer. A frame callback means "the compositor is ready
// for your next frame"; for a headless capture compositor that is true
// the moment the commit lands, because there is no renderer and no
// scan-out between us and the client. A timer at any rate decouples the
// client's submit loop from the signal it is pacing itself with — too
// early for a slow client (over-submits), too late for a fast one
// (throttles), and when the two rates are close but not equal the phase
// slips and produces periodic hitches. The client's own rate is the
// correct rate; that is the whole point of the callback.
// -----------------------------------------------------------------------
pub(crate) fn on_surface_committed(&mut self, root: &WlSurface, window: &Window) {
pub(crate) fn present_now(&mut self, root: &WlSurface, window: &Window) {
let output = self.output.clone();
let now = self.clock.now();
self.presentation_seq += 1;
// Frame callbacks for the whole tree. `None` throttle: no minimum
// interval — the client decides its own cadence, we answer every
// frame it hands us.
send_frames_surface_tree(root, &output, now, None, |_, _| Some(output.clone()));
// Presentation feedback for the same frame, resolved as `presented`
// immediately. `discarded` is the wrong resolution here: it means
// "the next frame superseded this one before it reached the
// display," which is not what happened — this frame is the one the
// capture layer will see, and the client that waits on it (Vulkan
// FIFO present, VKD3D-Proton, DXVK) is waiting precisely for this.
let mut feedback = OutputPresentationFeedback::new(&output);
let mut fb = OutputPresentationFeedback::new(&output);
window.take_presentation_feedback(
&mut feedback,
&mut fb,
|_, _| Some(output.clone()),
|_, _| wp_presentation_feedback::Kind::Vsync,
);
feedback.presented(
fb.presented(
now,
output
.current_mode()
.map(|m| Refresh::fixed(Duration::from_secs_f64(1_000.0 / m.refresh as f64)))
.unwrap_or(Refresh::Unknown),
0,
Refresh::Unknown,
self.presentation_seq,
wp_presentation_feedback::Kind::Vsync,
);
send_frames_surface_tree(root, &output, now, None, |_, _| Some(output.clone()));
}
pub(crate) fn send_cursor_update(&mut self) {