Repository: alacritty/alacritty
File: alacritty/src/display/mod.rs (Rust)

Code before:
    pub fn new() -> Self {
        Self {
            swap_timeout: Duration::ZERO,
            previous_error: 0,
            frame_timestamp: Instant::now(),
            refresh_interval: Duration::ZERO,
        }
    }

    /// Compute the delay that we should use to achieve the target frame
    /// rate.
    pub fn compute_timeout(&mut self, refresh_interval: Duration) -> Duration {
        // Handle refresh rate change.
        if self.refresh_interval != refresh_interval {
            self.refresh_interval = refresh_interval;
            self.frame_timestamp = Instant::now();
            self.swap_timeout = refresh_interval;
            return refresh_interval;
        }

        // Compute the error.
        let error = self.refresh_interval.as_micros() as i64
            - self.frame_timestamp.elapsed().as_micros() as i64;

        // Don't update error and swap timeout if we've waited for too long.
        if error < self.refresh_interval.as_micros() as i64 {
            // Average previously used error with the current one to reduce momentum from the
            // error sign changes.
            self.previous_error = (self.previous_error + error) / 2;

            let new_swap_timeout = self.swap_timeout.as_micros() as i64 + self.previous_error;
            let new_swap_timeout =
                Duration::from_micros(u64::try_from(new_swap_timeout).unwrap_or_default());
            self.swap_timeout = new_swap_timeout;
        }

        self.frame_timestamp = Instant::now();
        self.swap_timeout
    }
}

/// Calculate the cell dimensions based on font metrics.
///
/// This will return a tuple of the cell width and height.
#[inline]
fn compute_cell_size(config: &UiConfig, metrics: &crossfont::Metrics) -> (f32, f32) {
    let offset_x = f64::from(config.font.offset.x);
    let offset_y = f64::from(config.font.offset.y);
    (
        (metrics.average_advance + offset_x).floor().max(1.) as f32,
        (metrics.line_height + offset_y).floor().max(1.) as f32,

Review comment (suggestion):
I'm somewhat concerned about this logic here. It will cause an immediate scheduling which I guess is fine but that will mean our "clock" gets reset. Thus the new frame is not in line with our previous frames.

Shouldn't we aim to render at the next "modulo frame interval" time, so that our rendering stays on track and keeps its consistent clock?

Otherwise I'm afraid that if we regularly skip drawing (like every other frame this happens), we'd get very inconsistent latencies (not technically worse, just inconsistent).

Code after:
    }

    /// Compute the delay that we should use to achieve the target frame
    /// rate.
    pub fn compute_timeout(&mut self, refresh_interval: Duration) -> Duration {
        let now = Instant::now();

        // Handle refresh rate change.
        if self.refresh_interval != refresh_interval {
            self.base = now;
            self.last_synced_timestamp = now;
            self.refresh_interval = refresh_interval;
            return refresh_interval;
        }

        let next_frame = self.last_synced_timestamp + self.refresh_interval;

        if next_frame < now {
            // Redraw immediately if we haven't drawn in over `refresh_interval` microseconds.
            let elapsed_micros = (now - self.base).as_micros() as u64;
            let refresh_micros = self.refresh_interval.as_micros() as u64;
            self.last_synced_timestamp =
                now - Duration::from_micros(elapsed_micros % refresh_micros);
            Duration::ZERO
        } else {
            // Redraw on the next `refresh_interval` clock tick.
            self.last_synced_timestamp = next_frame;
            next_frame - now
        }
    }
}

/// Calculate the cell dimensions based on font metrics.
///
/// This will return a tuple of the cell width and height.
#[inline]
fn compute_cell_size(config: &UiConfig, metrics: &crossfont::Metrics) -> (f32, f32) {
    let offset_x = f64::from(config.font.offset.x);
    let offset_y = f64::from(config.font.offset.y);
    (
        (metrics.average_advance + offset_x).floor().max(1.) as f32,
        (metrics.line_height + offset_y).floor().max(1.) as f32,
    )
}

/// Calculate the size of the window given padding, terminal dimensions and cell size.
fn window_size(
    config: &UiConfig,
    dimensions: Dimensions,
    cell_width: f32,
    cell_height: f32,