Skip to content

Commit 83fbdf2

Browse files
committed
fixup! performer
1 parent 3100789 commit 83fbdf2

File tree

5 files changed

+65
-207
lines changed

5 files changed

+65
-207
lines changed

frontends/rioterm/src/application.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,12 +1302,16 @@ impl ApplicationHandler<EventPayload> for Application<'_> {
13021302
.pending_update
13031303
.is_dirty()
13041304
{
1305-
route.schedule_redraw(
1306-
&mut self.scheduler,
1307-
route.window.screen.ctx().current_route(),
1308-
);
1305+
route.request_redraw();
13091306
}
13101307

1308+
// route.request_redraw();
1309+
1310+
// route.schedule_redraw(
1311+
// &mut self.scheduler,
1312+
// route.window.screen.ctx().current_route(),
1313+
// );
1314+
13111315
event_loop.set_control_flow(ControlFlow::Wait);
13121316
}
13131317
_ => {}

frontends/rioterm/src/context/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ impl<T: EventListener + Clone + std::marker::Send + 'static> ContextManager<T> {
284284
}
285285

286286
let machine =
287-
Machine::new(Arc::clone(&terminal), pty, event_proxy.clone(), window_id)?;
287+
Machine::new(Arc::clone(&terminal), pty, event_proxy.clone(), window_id, route_id)?;
288288
let channel = machine.channel();
289289
let io_thread = if config.spawn_performer {
290290
Some(machine.spawn())

frontends/rioterm/src/context/renderable.rs

Lines changed: 10 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,6 @@ pub struct TerminalSnapshot {
9999
pub struct PendingUpdate {
100100
/// Whether there's any pending update that needs rendering
101101
dirty: bool,
102-
/// The terminal snapshot with accumulated damage (primarily for synchronized updates)
103-
snapshot: Option<TerminalSnapshot>,
104-
/// Whether this update came from a Wakeup event (needs damage check at render time)
105-
wakeup: bool,
106102
}
107103

108104
impl PendingUpdate {
@@ -116,177 +112,37 @@ impl PendingUpdate {
116112
/// This is used by Wakeup events to defer damage calculation
117113
pub fn mark_for_damage_check(&mut self) {
118114
self.dirty = true;
119-
self.wakeup = true;
120-
// Don't create a snapshot yet - let the renderer do it when needed
121115
}
122116

123-
/// Clear the dirty flag without taking the snapshot
124-
/// Used when we manually process the damage in the renderer
117+
/// Clear the dirty flag
125118
pub fn clear_dirty(&mut self) {
126119
self.dirty = false;
127-
self.wakeup = false;
128120
}
129121

130-
/// Mark as needing update with the given damage.
131-
///
132-
/// For synchronized updates, this creates a snapshot immediately to capture the
133-
/// terminal state at the time of damage. For wakeup-based updates, this just
134-
/// marks as dirty and defers the actual damage check to render time to avoid
135-
/// lock contention.
122+
/// Mark as needing update.
123+
/// The actual snapshot will be computed at render time.
136124
pub fn invalidate<U: rio_backend::event::EventListener>(
137125
&mut self,
138-
damage: TerminalDamage,
139-
terminal: &FairMutex<Crosswords<U>>,
126+
_damage: TerminalDamage,
127+
_terminal: &FairMutex<Crosswords<U>>,
140128
) {
141129
self.dirty = true;
142-
143-
// If we're in wakeup mode, skip the snapshot creation to avoid lock contention
144-
// The damage will be retrieved at render time instead
145-
if self.wakeup {
146-
// Keep the wakeup flag set - damage will be checked at render time
147-
return;
148-
}
149-
150-
// let lock_start = std::time::Instant::now();
151-
let mut terminal = terminal.lock();
152-
// let lock_duration = lock_start.elapsed();
153-
// if lock_duration > std::time::Duration::from_millis(5) {
154-
// tracing::warn!("PendingUpdate::invalidate: Lock acquisition took {:?}", lock_duration);
155-
// }
156-
157-
// match &damage {
158-
// TerminalDamage::Full => tracing::trace!("PendingUpdate: Full damage"),
159-
// TerminalDamage::Partial(ranges) => tracing::trace!("PendingUpdate: {} partial ranges damaged", ranges.len()),
160-
// TerminalDamage::CursorOnly => tracing::trace!("PendingUpdate: Cursor-only damage"),
161-
// }
162-
163-
// Get the terminal's current damage
164-
let terminal_damage = terminal.peek_damage_event();
165-
166-
// Create or update the snapshot
167-
match &mut self.snapshot {
168-
None => {
169-
// Create new snapshot with merged terminal and incoming damage
170-
let initial_damage = match (terminal_damage, &damage) {
171-
(None, damage) => damage.clone(),
172-
(Some(term_damage), damage) => {
173-
Self::merge_damages(&term_damage, damage)
174-
}
175-
};
176-
177-
self.snapshot = Some(TerminalSnapshot {
178-
colors: terminal.colors,
179-
display_offset: terminal.display_offset(),
180-
blinking_cursor: terminal.blinking_cursor,
181-
visible_rows: terminal.visible_rows(),
182-
cursor: terminal.cursor(),
183-
damage: initial_damage,
184-
columns: terminal.columns(),
185-
screen_lines: terminal.screen_lines(),
186-
});
187-
}
188-
Some(existing_snapshot) => {
189-
// Update existing snapshot with fresh terminal state
190-
existing_snapshot.colors = terminal.colors;
191-
existing_snapshot.display_offset = terminal.display_offset();
192-
existing_snapshot.blinking_cursor = terminal.blinking_cursor;
193-
existing_snapshot.visible_rows = terminal.visible_rows();
194-
existing_snapshot.cursor = terminal.cursor();
195-
existing_snapshot.columns = terminal.columns();
196-
existing_snapshot.screen_lines = terminal.screen_lines();
197-
198-
// Merge existing snapshot damage with incoming damage
199-
existing_snapshot.damage =
200-
Self::merge_damages(&existing_snapshot.damage, &damage);
201-
202-
// Also merge with terminal damage if present
203-
if let Some(term_damage) = terminal_damage {
204-
existing_snapshot.damage =
205-
Self::merge_damages(&existing_snapshot.damage, &term_damage);
206-
}
207-
}
208-
}
209-
210-
// Reset terminal damage since we've captured it in the snapshot
211-
terminal.reset_damage();
212-
213-
// Log final damage state only for significant updates
214-
if let Some(ref snapshot) = self.snapshot {
215-
match &snapshot.damage {
216-
TerminalDamage::Full => {
217-
tracing::trace!("PendingUpdate: Snapshot has full damage")
218-
}
219-
TerminalDamage::Partial(ranges) if ranges.len() > 50 => {
220-
tracing::debug!(
221-
"PendingUpdate: Large snapshot with {} damaged ranges",
222-
ranges.len()
223-
);
224-
}
225-
TerminalDamage::Partial(ranges) if ranges.len() > 10 => {
226-
tracing::trace!(
227-
"PendingUpdate: Snapshot has {} damaged ranges",
228-
ranges.len()
229-
);
230-
}
231-
_ => {}
232-
}
233-
}
234130
}
235131

236132
/// Mark as needing full update
237133
pub fn invalidate_full<U: rio_backend::event::EventListener>(
238134
&mut self,
239-
terminal: &FairMutex<Crosswords<U>>,
135+
_terminal: &FairMutex<Crosswords<U>>,
240136
) {
241-
// If we're in wakeup mode, just mark as dirty
242-
if self.wakeup {
243-
self.dirty = true;
244-
return;
245-
}
246-
self.invalidate(TerminalDamage::Full, terminal);
137+
self.dirty = true;
247138
}
248139

249-
/// Take the snapshot and reset dirty flag
250-
/// This should only be called when actually rendering!
251-
pub fn take_snapshot(&mut self) -> (Option<TerminalSnapshot>, bool) {
252-
let was_wakeup = self.wakeup;
140+
/// Reset the dirty flag after rendering
141+
pub fn reset(&mut self) {
253142
self.dirty = false;
254-
self.wakeup = false;
255-
(self.snapshot.take(), was_wakeup)
256143
}
257144

258-
/// Merge two damages into one - this is critical for correctness
259-
fn merge_damages(existing: &TerminalDamage, new: &TerminalDamage) -> TerminalDamage {
260-
use std::collections::BTreeSet;
261-
262-
match (existing, new) {
263-
// Any damage + Full = Full
264-
(_, TerminalDamage::Full) | (TerminalDamage::Full, _) => TerminalDamage::Full,
265-
// Partial damages: merge the line lists efficiently using BTreeSet
266-
(TerminalDamage::Partial(lines1), TerminalDamage::Partial(lines2)) => {
267-
let mut line_set = BTreeSet::new();
268-
269-
// Add all damaged lines from both sets
270-
for damage in lines1.iter().chain(lines2.iter()) {
271-
if damage.damaged {
272-
line_set.insert(*damage);
273-
}
274-
}
275-
276-
TerminalDamage::Partial(line_set)
277-
}
278-
// CursorOnly damages need special handling
279-
(TerminalDamage::CursorOnly, TerminalDamage::Partial(lines)) => {
280-
TerminalDamage::Partial(lines.clone())
281-
}
282-
(TerminalDamage::Partial(lines), TerminalDamage::CursorOnly) => {
283-
TerminalDamage::Partial(lines.clone())
284-
}
285-
(TerminalDamage::CursorOnly, TerminalDamage::CursorOnly) => {
286-
TerminalDamage::CursorOnly
287-
}
288-
}
289-
}
145+
290146
}
291147

292148
#[cfg(test)]

frontends/rioterm/src/renderer/mod.rs

Lines changed: 41 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -846,43 +846,44 @@ impl Renderer {
846846
let force_full_damage = has_active_changed || self.is_game_mode_enabled;
847847

848848
// Check if we need to render
849-
if !context.renderable_content.pending_update.is_dirty() && !force_full_damage
850-
{
851-
// No updates pending, skip rendering
852-
continue;
853-
}
849+
// if !context.renderable_content.pending_update.is_dirty() && !force_full_damage
850+
// {
851+
// println!("NAUM tem");
852+
// // No updates pending, skip rendering
853+
// continue;
854+
// }
854855

855856
// Take the pending snapshot
856857
let terminal_snapshot =
857-
match context.renderable_content.pending_update.take_snapshot() {
858-
(Some(snapshot), _) => snapshot,
859-
(None, was_wakeup) if was_wakeup => {
860-
// This was a Wakeup event - check the terminal for damage
861-
let mut terminal = context.terminal.lock();
862-
863-
// Get the damage from the terminal
864-
if let Some(damage) = terminal.peek_damage_event() {
865-
let snapshot = TerminalSnapshot {
866-
colors: terminal.colors,
867-
display_offset: terminal.display_offset(),
868-
blinking_cursor: terminal.blinking_cursor,
869-
visible_rows: terminal.visible_rows(),
870-
cursor: terminal.cursor(),
871-
damage: damage.clone(),
872-
columns: terminal.columns(),
873-
screen_lines: terminal.screen_lines(),
874-
};
875-
terminal.reset_damage();
876-
drop(terminal);
877-
878-
snapshot
879-
} else {
880-
// No damage found, skip rendering
881-
drop(terminal);
882-
continue;
883-
}
884-
}
885-
(None, _) if force_full_damage => {
858+
// match context.renderable_content.pending_update.take_snapshot() {
859+
// (Some(snapshot), _) => snapshot,
860+
// (None, was_wakeup) if was_wakeup => {
861+
// // This was a Wakeup event - check the terminal for damage
862+
// let mut terminal = context.terminal.lock();
863+
864+
// // Get the damage from the terminal
865+
// if let Some(damage) = terminal.peek_damage_event() {
866+
// let snapshot = TerminalSnapshot {
867+
// colors: terminal.colors,
868+
// display_offset: terminal.display_offset(),
869+
// blinking_cursor: terminal.blinking_cursor,
870+
// visible_rows: terminal.visible_rows(),
871+
// cursor: terminal.cursor(),
872+
// damage: damage.clone(),
873+
// columns: terminal.columns(),
874+
// screen_lines: terminal.screen_lines(),
875+
// };
876+
// terminal.reset_damage();
877+
// drop(terminal);
878+
879+
// snapshot
880+
// } else {
881+
// // No damage found, skip rendering
882+
// drop(terminal);
883+
// continue;
884+
// }
885+
// }
886+
{
886887
// Force full damage case - create a fresh snapshot
887888
let mut terminal = context.terminal.lock();
888889
let snapshot = TerminalSnapshot {
@@ -898,12 +899,12 @@ impl Renderer {
898899
terminal.reset_damage();
899900
drop(terminal);
900901
snapshot
901-
}
902-
(None, _) => {
903-
// No pending update and not forcing
904-
continue;
905-
}
906-
};
902+
};
903+
// (None, _) => {
904+
// // No pending update and not forcing
905+
// continue;
906+
// }
907+
// };
907908

908909
// Get hint matches from renderable content
909910
let hint_matches = context.renderable_content.hint_matches.as_deref();

rio-backend/src/performer/mod.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ pub struct Machine<T: teletypewriter::EventedPty, U: EventListener> {
6868
terminal: Arc<FairMutex<Crosswords<U>>>,
6969
event_proxy: U,
7070
window_id: WindowId,
71+
route_id: usize
7172
}
7273

7374
#[derive(Default)]
@@ -146,6 +147,7 @@ where
146147
pty: T,
147148
event_proxy: U,
148149
window_id: WindowId,
150+
route_id: usize,
149151
) -> Result<Machine<T, U>, Box<dyn std::error::Error>> {
150152
let (sender, receiver) = channel::channel();
151153
let poll = corcovado::Poll::new()?;
@@ -158,6 +160,7 @@ where
158160
terminal,
159161
event_proxy,
160162
window_id,
163+
route_id,
161164
})
162165
}
163166

@@ -217,19 +220,16 @@ where
217220
// multiple rapid updates into a single render pass.
218221
if state.parser.sync_bytes_count() < processed && processed > 0 {
219222
// Check if there's any damage to process
220-
if let Some(ref terminal) = terminal {
221223
// if terminal.peek_damage_event().is_some() {
222224
// terminal.emit_damage_event();
223225
tracing::trace!(
224226
"PTY read: Sending Wakeup event for {} bytes of non-sync data",
225227
processed
226228
);
227229
// Send a Wakeup event to coalesce renders
228-
let route_id = terminal.route_id;
229230
self.event_proxy
230-
.send_event(RioEvent::Wakeup(route_id), self.window_id);
231+
.send_event(RioEvent::Wakeup(self.route_id), self.window_id);
231232
// }
232-
}
233233
}
234234

235235
Ok(())
@@ -358,10 +358,7 @@ where
358358
state.parser.stop_sync(&mut *terminal);
359359

360360
// Emit damage event if there's any damage after processing sync buffer
361-
if terminal.peek_damage_event().is_some() {
362-
terminal.emit_damage_event();
363-
}
364-
drop(terminal);
361+
self.event_proxy.send_event(RioEvent::Wakeup(self.route_id), self.window_id);
365362

366363
continue;
367364
}

0 commit comments

Comments
 (0)