mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-28 21:32:39 +00:00
Always synchronize terminal before rendering it (#4114)
Previously, we were trying not to synchronize the terminal too often because there could be multiple layout/paint calls prior to rendering a frame. Now that we perform a single render pass per frame, we can just synchronize the terminal state. Not doing so could make it seem like we're dropping frames. Release Notes: - Improved terminal rendering performance.
This commit is contained in:
commit
194e0f3231
2 changed files with 4 additions and 33 deletions
|
@ -47,7 +47,7 @@ use std::{
|
|||
os::unix::prelude::AsRawFd,
|
||||
path::PathBuf,
|
||||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
time::Duration,
|
||||
};
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -385,8 +385,6 @@ impl TerminalBuilder {
|
|||
last_content: Default::default(),
|
||||
last_mouse: None,
|
||||
matches: Vec::new(),
|
||||
last_synced: Instant::now(),
|
||||
sync_task: None,
|
||||
selection_head: None,
|
||||
shell_fd: fd as u32,
|
||||
shell_pid,
|
||||
|
@ -542,8 +540,6 @@ pub struct Terminal {
|
|||
last_mouse_position: Option<Point<Pixels>>,
|
||||
pub matches: Vec<RangeInclusive<AlacPoint>>,
|
||||
pub last_content: TerminalContent,
|
||||
last_synced: Instant,
|
||||
sync_task: Option<Task<()>>,
|
||||
pub selection_head: Option<AlacPoint>,
|
||||
pub breadcrumb_text: String,
|
||||
shell_pid: u32,
|
||||
|
@ -977,40 +973,15 @@ impl Terminal {
|
|||
self.input(paste_text);
|
||||
}
|
||||
|
||||
pub fn try_sync(&mut self, cx: &mut ModelContext<Self>) {
|
||||
pub fn sync(&mut self, cx: &mut ModelContext<Self>) {
|
||||
let term = self.term.clone();
|
||||
|
||||
let mut terminal = if let Some(term) = term.try_lock_unfair() {
|
||||
term
|
||||
} else if self.last_synced.elapsed().as_secs_f32() > 0.25 {
|
||||
term.lock_unfair() // It's been too long, force block
|
||||
} else if let None = self.sync_task {
|
||||
//Skip this frame
|
||||
let delay = cx.background_executor().timer(Duration::from_millis(16));
|
||||
self.sync_task = Some(cx.spawn(|weak_handle, mut cx| async move {
|
||||
delay.await;
|
||||
if let Some(handle) = weak_handle.upgrade() {
|
||||
handle
|
||||
.update(&mut cx, |terminal, cx| {
|
||||
terminal.sync_task.take();
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}
|
||||
}));
|
||||
return;
|
||||
} else {
|
||||
//No lock and delayed rendering already scheduled, nothing to do
|
||||
return;
|
||||
};
|
||||
|
||||
let mut terminal = term.lock_unfair();
|
||||
//Note that the ordering of events matters for event processing
|
||||
while let Some(e) = self.events.pop_front() {
|
||||
self.process_terminal_event(&e, &mut terminal, cx)
|
||||
}
|
||||
|
||||
self.last_content = Self::make_content(&terminal, &self.last_content);
|
||||
self.last_synced = Instant::now();
|
||||
}
|
||||
|
||||
fn make_content(term: &Term<ZedListener>, last_content: &TerminalContent) -> TerminalContent {
|
||||
|
|
|
@ -446,7 +446,7 @@ impl TerminalElement {
|
|||
|
||||
let last_hovered_word = self.terminal.update(cx, |terminal, cx| {
|
||||
terminal.set_size(dimensions);
|
||||
terminal.try_sync(cx);
|
||||
terminal.sync(cx);
|
||||
if self.can_navigate_to_selected_word && terminal.can_navigate_to_selected_word() {
|
||||
terminal.last_content.last_hovered_word.clone()
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue