Tidy some things up to avoid some dead code and redundant impls.
Make it easier to select whether you want to implement the new
methods in terms of the old, or the old methods in terms of
the new in a given pane impl.
Remove the faulty cache key stuff and hang references to the cached
data directly off the underlying Line. That makes the association
between the the Line and the data O(1) plus some basic cache
invalidation checks.
Adjust the shape cache portion of this to use the same ID for the
shape, so that things that invalidate just the quads (such as cursor
movement when not composing, and selection) only need to recompute
the quads without re-shaping.
Adds Pane::for_each_logical_line_in_stable_range_mut and
Pane::with_lines_mut which allow iterating mutably over lines.
The idea is that this will allow the renderer to directly cache
data in the Line via its appdata without having to build cumbersome
external caching logic and managing cache keys.
This commit just swaps the implementation around for localpane
and sanity checks that the renderer functions.
Various overlays and the mux client don't properly implement these
yet and current warn at compile time and panic at runtime.
To follow is the logic to cache the data and make sure that it
works the way that I think before converting the other Pane
implementations.
The cache key isn't quite right, leading to some artifacts
in some cases.
I have a cunning plan, but it will take me a bit to wrap
it up, so in the meantime, disable these caches.
refs: https://github.com/wez/wezterm/issues/2455
It didn't really belong there; it was added as a bit of a hack
to propagate screen reverse video mode.
Move that to the RenderableDims struct and remove the related
bits from Line
Similar to selection_fg, setting the cursor_fg to transparent ("none")
will use the foreground color of the text behind the cursor.
refs: https://github.com/wez/wezterm/issues/1835
I broke this with the performance changes I pushed earlier today.
Poke a hole in caching for it as well, as it doesn't use the seqno
to track changes like the rest of the Line based data.
cc: @DeadlySquad13
It can have some surprising effects, so leave it at the basic logical
composition of cwd + relative rather than physical.
refs: https://github.com/wez/wezterm/issues/2449
This doesn't mean that it renders at 1fps, just that it goes through
the simpler path of scheduling on the boundaries rather than at
animation_fps through the intermediate stages, where it would be
useless.
Introduces a heap-based quad allocator that we cache on a per-line
basis, so if a line is unchanged we simply need to copy the previously
computed set of quads for it into the gpu quad buffer.
The results are encouraging wrt. constructing those quads; the
`quad_buffer_apply` is the cost of the copy operation, compare with
`render_screen_line_opengl` which is the cost of computing the quads;
it's 300x better at the p50 and >100x better at p95 for a full-screen
updating program:
full 2880x1800 screen top:
```
STAT p50 p75 p95
Key(quad_buffer_apply) 2.26µs 5.22µs 9.60µs
Key(render_screen_line_opengl) 610.30µs 905.22µs 1.33ms
Key(gui.paint.opengl) 35.39ms 37.75ms 45.88ms
```
However, the extra buffering does increase the latency of
`gui.paint.opengl` (the overall cost of painting a frame); contrast the
above with the latency in the same scenario with the current `main`
(rather than this branch):
```
Key(gui.paint.opengl) 19.14ms 21.10ms 28.18ms
```
Note that for an idle screen this latency is ~1.5ms but that is also true
of `main`.
While the overall latency in the histogram isn't a slam dunk,
running `time cat bigfile` is ~10% faster on my mac.
I'm sure there's something that can be shaved off to get a more
convincing win.
This is really a proof of concept commit; I want to be able to pass
more structured data into the shader as uniforms and the basic
macros provided by glium make that a bit awkward.
What I came up with is a slightly more dynamic uniform builder
thingy.
I'm using this to pass in a copy of the various blinking easing
functions.
Those are incomplete and unused, but it shows that the technique works.
It's not the first time that I've solved a problem by slowing things
down... in this situation, a couple of very inefficient TUI programs had
flickering outputs in wezterm because they were filling a buffer with a
bunch of spaces to erase a screen before sending the main body of their
updates in a subsequent buffer chunk. wezterm would render the
intervening partially blank frame and appear to flicker.
The resolution is to add a small delay (3ms by default) before sending
data to the terminal model. If the output is readable in that time
we'll accumulate it with the pending set of actions so that the
whole batch can be applied "more atomically".
Take care: `time cat bigfile` is sensitive to this, so we want to
keep the latency as small as possible, and we also want to avoid
accumulating actions and only flushing them at the end of the file.
We use the existing buffer size (~1MB) as a threshold: we bump
a count of the number of input bytes that resulted in the current
set of actions, and if that exceeds that buffer size we flush it.
refs: https://github.com/wez/wezterm/issues/2443