Commit 3b5d351
authored
Fix high CPU usage from cursor position request feedback loop (#1310)
* Fix high CPU usage from cursor position request feedback loop (#1302)
In non-alternate-screen modes, every Draw() sends a \x1b[6n cursor
position request. Two compounding bugs turned this into a permanent
~60fps redraw loop, pegging both the app and the terminal emulator
(most visibly tmux):
1. ThrottledRequest::Send() never updated last_request_time_, so the
intended 500ms throttle never engaged: a new request was sent as
soon as the previous reply arrived.
2. The terminal input parser sink requested an animation frame for
every parsed event, including cursor position reports, which are
internal replies to our own request. The armed animation frame
invalidated the frame, triggering a full redraw that sent the next
request, whose reply armed the next frame, and so on.
Fix: record last_request_time_ in Send(), and stop requesting
animation frames for cursor position reports (they are still delivered
to the event buffer and consumed as before).
Measured with the gallery example idling inside tmux: the app drops
from ~24% CPU to ~0.4%, the tmux server from ~8% (detached; ~100% of
a core with an attached client) to ~0%.
Fixes #1302
* Request animation frames when handling events, not when receiving them
Move RequestAnimationFrame() from the two event producers (the
TerminalInputParser callback and App::PostEvent) to the Event branch of
App::Internal::HandleTask, below the internal-reply early-returns.
A single place now decides which events grant an animation frame, next
to the code discriminating event kinds. As a result, every internal
terminal reply (cursor shape, terminal capabilities, name/version,
emulator) stops arming animation frames: previously only cursor
position reports were exempted, and only on the parser path. This also
moves the animation_requested_ write onto the main loop thread,
removing an unsynchronized write when PostEvent is called from another
thread.
Add a test covering the event -> animation tick pipeline. See #1302.
* Only produce animation frames when requested
Restore the FTXUI 6 behavior: animation frames are produced only when
requested via animation::RequestAnimationFrame(), typically by an
animation::Animator which arms it on construction and re-arms it from
OnAnimation until the transition completes.
Handling an event no longer implicitly grants an animation tick. That
behavior was introduced accidentally by the v7 event loop rework
(33a40ee) and is what made the #1302 feedback loop possible in the
first place: internal terminal replies are events too.1 parent 8bf276b commit 3b5d351
3 files changed
Lines changed: 75 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
7 | 16 | | |
8 | 17 | | |
9 | 18 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| 6 | + | |
6 | 7 | | |
| 8 | + | |
7 | 9 | | |
8 | 10 | | |
9 | 11 | | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
10 | 18 | | |
11 | 19 | | |
12 | 20 | | |
| |||
35 | 43 | | |
36 | 44 | | |
37 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
38 | 103 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
228 | 228 | | |
229 | 229 | | |
230 | 230 | | |
| 231 | + | |
231 | 232 | | |
232 | 233 | | |
233 | 234 | | |
| |||
556 | 557 | | |
557 | 558 | | |
558 | 559 | | |
559 | | - | |
560 | 560 | | |
561 | 561 | | |
562 | 562 | | |
| |||
1533 | 1533 | | |
1534 | 1534 | | |
1535 | 1535 | | |
1536 | | - | |
1537 | 1536 | | |
1538 | 1537 | | |
1539 | 1538 | | |
| |||
0 commit comments