mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 10:29:35 +03: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
@ -47,7 +47,7 @@ use std::{
|
|||||||
os::unix::prelude::AsRawFd,
|
os::unix::prelude::AsRawFd,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
time::{Duration, Instant},
|
time::Duration,
|
||||||
};
|
};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
@ -385,8 +385,6 @@ impl TerminalBuilder {
|
|||||||
last_content: Default::default(),
|
last_content: Default::default(),
|
||||||
last_mouse: None,
|
last_mouse: None,
|
||||||
matches: Vec::new(),
|
matches: Vec::new(),
|
||||||
last_synced: Instant::now(),
|
|
||||||
sync_task: None,
|
|
||||||
selection_head: None,
|
selection_head: None,
|
||||||
shell_fd: fd as u32,
|
shell_fd: fd as u32,
|
||||||
shell_pid,
|
shell_pid,
|
||||||
@ -542,8 +540,6 @@ pub struct Terminal {
|
|||||||
last_mouse_position: Option<Point<Pixels>>,
|
last_mouse_position: Option<Point<Pixels>>,
|
||||||
pub matches: Vec<RangeInclusive<AlacPoint>>,
|
pub matches: Vec<RangeInclusive<AlacPoint>>,
|
||||||
pub last_content: TerminalContent,
|
pub last_content: TerminalContent,
|
||||||
last_synced: Instant,
|
|
||||||
sync_task: Option<Task<()>>,
|
|
||||||
pub selection_head: Option<AlacPoint>,
|
pub selection_head: Option<AlacPoint>,
|
||||||
pub breadcrumb_text: String,
|
pub breadcrumb_text: String,
|
||||||
shell_pid: u32,
|
shell_pid: u32,
|
||||||
@ -977,40 +973,15 @@ impl Terminal {
|
|||||||
self.input(paste_text);
|
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 term = self.term.clone();
|
||||||
|
let mut terminal = term.lock_unfair();
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Note that the ordering of events matters for event processing
|
//Note that the ordering of events matters for event processing
|
||||||
while let Some(e) = self.events.pop_front() {
|
while let Some(e) = self.events.pop_front() {
|
||||||
self.process_terminal_event(&e, &mut terminal, cx)
|
self.process_terminal_event(&e, &mut terminal, cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.last_content = Self::make_content(&terminal, &self.last_content);
|
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 {
|
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| {
|
let last_hovered_word = self.terminal.update(cx, |terminal, cx| {
|
||||||
terminal.set_size(dimensions);
|
terminal.set_size(dimensions);
|
||||||
terminal.try_sync(cx);
|
terminal.sync(cx);
|
||||||
if self.can_navigate_to_selected_word && terminal.can_navigate_to_selected_word() {
|
if self.can_navigate_to_selected_word && terminal.can_navigate_to_selected_word() {
|
||||||
terminal.last_content.last_hovered_word.clone()
|
terminal.last_content.last_hovered_word.clone()
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user