I noticed when running the notcurses demo that we're spending a
decent amount of time decoding png data whenever we need to
re-do the texture atlas.
Let's avoid that by allowing for ImageData at the termwiz layer
to represent both the image file format and decoded rgba8 data.
This commit is a bit muddy and also includes some stuff to try
to delete placements from the model. It's not perfect by any
means--more expensive than I want, and there's something funky
that causes a large number of images to build up during some
phases of the demo.
refs: #986
OpenGL will silently let us allocate a texture larger than the GPU can
bind to a sampler, reporting the error status out of band and leaving
the display in a perma-broken state.
This commit deliberately checks against the max texture size and raises
an error in that case.
The recovery story isn't perfect, but at least the texture remains
usable, so the user can clear the screen and still be able to see glyphs
afterwards.
refs: https://github.com/wez/wezterm/issues/879
Previously, we'd use a 1MB buffer both to read the output from the
associated pty (blocking), and the same size buffer again to do the
non-blocking read on top of that.
For pathological cases (eg: cat 100MB+ files), we could build a
resulting `Vec<Action>` with over 1mm entries and it could take as much
as 100ms to apply those actions to the terminal model.
This meant that the output could stutter/lag and appear to be processed
more slowly.
This commit introduces a configuration value for the buffer size for the
second stage, and makes it 10KB in size. This helps to constrain the
size of the Action vec and keeps the incremental processing costs down,
while still managing the same throughput.
Taking further advantage of dynamic quad allocation, we can now
remove the multiple render passes in favor of allocating the quads
and painting them from back to front.
In turn, this means that we can reduce the amount of data that we
store in the vertex, which simplifies the shaders a bit, at the
expense of making the render code in rust a bit more complex.
However, we can take advantage of stretching runs of cells with
background colors in to a single quad.
refs: #986
This was added in 365a68dfb8 to free the
orca from its cage. With the recent dynamic quad allocation changes, we
don't need a distinct 4th pass any more and can simply layer a separate
quad on top of the glyph quad.
refs: #986
This removes the pre-allocated (at resize) number of quads
and replaces it with a dynamic mechanism that tracks how many
quads are needed for a frame and then will re-allocate and
re-render when there weren't enough.
We start with 1024 quads and try to allocate in multiples
of 1024 quads.
refs: #986
This commit removes the `Quads` struct which maintained pre-defined quad
indices for each of the cells, the background image and scrollbar thumb.
In its place, we now "dynamically" hand out quads to meet the needs of
what is being rendered. There are some efficiency gains here with
things like the selection (which can now be a single stretched quad,
rather than `n` quads in width).
This isn't a fully dynamic allocation scheme, as we still allocate the
current worst case number of quads when resizing.
A following commit will adjust that so that we allocate a ballpark and
then employ a mechanism similar to OutOfTextureSpace to grow and retry a
render pass when we need more quads.
Futhermore, this dynamic approach may allow reducing the amount of stuff
we have in the Vertex and "simply" render some quads before others so
that we don't have to have so many draw() passes to build up the
complete scene.
refs: #986
This isn't complete; many of the placement options are not supported,
and the status reporting is missing in a number of cases, including
querying/probing, and shared memory objects are not supported yet.
However, this commit is sufficient to allow the kitty-png.py script
(that was copied from
https://sw.kovidgoyal.net/kitty/graphics-protocol/#a-minimal-example)
to render a PNG in the terminal.
This implementation routes the basic image display via the same
code that we use for iterm2 and sixel protocols, but it isn't
sufficient to support the rest of the placement options allowed
by the spec.
Notably, we'll need to add the concept of image placements to
the data model maintained by the terminal state and find a way
to efficiently manage placements both by id and by a viewport
range.
The renderer will need to manage separate quads for placements
and order them by z-index, and adjust the render phases so that
images can appear in the correct plane.
refs: #986
This teaches termwiz to recognize and encode the APC
sequences used by the kitty image protocol.
This doesn't include support for animations, just the
transmit, placement and delete requests.
refs: #986
These were parsed but swallowed. This commit expands the transitions
to be able to track the APC start, data and end and then adds
an `apc_dispatch` method to allow capturing APC sequences.
APC sequences are used in the kitty image protocol.
refs: #986
In the case where the cells vec is shorter than the line width,
we need to ensure that we render the inverse video background
color if that mode is in effect.
refs: #133
Also fixes an issue where only the first frame schedule would
take effect! Surprised this didn't bubble up as a bug with
animated gifs already.
refs: #133