A casualty of b8dcfba9a4 was that
the decoded gif would get reset each time the texture filled up.
Take care to move that cached into the newly minted glyphcache.
Continuing along the same lines as the prior commit, the goal
of this commit is to remove the buffer transformation that was
part of uploading the texture to the GPU provided surface.
In order to do so:
* The sense of our local textures needs to change from bgra32 to rgba32.
bgra32 was a hangover from earlier versions of our window crate that
allowed direct-to-fb writes in software mode. We had to pick bgra32
for that for the broadest OS compatibility. I believe that that
constraint has been totally removed, although there is a chance that
this will flip the colors on macos.
* There was an additional linear-to-srgb conversion inlined in that
buffer transformation. I have no idea where that is needed because
the source data is carefully constructed as SRGB. I don't yet know
how to signal that, but for now I've moved that gamma correction
into the shader when we sample the texture.
With this change, timg playback now has vtparse as the hottest
region of code.
refs: #537
Two issues highlighted by profiling:
* Clearing the texture takes a non-trivial percentage of the profile.
The docs suggest that it is better to create a new texture than
to update large portions of a texture, so add some plumbing so
that we can do that in the first texture-full case.
* Next on the list is the code that translates from linear BGRA to
SRGBA. This is present for reasons that I believe are now legacy,
but for the moment: those two primitives now have faster and
easier implementations, so simplify to those.
This improves the timg video playback performance by ~10% for me.
refs: #537
I've been meaning to do this for a while; this commit moves
the escape sequence parsing into the thread that reads the
pty output which achieves two goals:
* Large escape sequences (eg: image protocols) that span multiple
4k buffers can be processed without ping-ponging between the
reader thread and the main gui thread
* That parsing can happen in the reader thread, keeping the gui
thread more responsive.
These changes free up the CPU during intensive operations such
as timg video playback.
This is a slight layering violation, in that this processing
really belongs to local pane (or any pane that embeds Terminal),
rather than generically at the Mux layer, but it's not any
worse a violation than `advance_bytes` already was.
refs: https://github.com/wez/wezterm/issues/537
The default downscaling provided by the GPU can result in noisy
artifacts on highly detailed images.
This commit employs a cubic Catmull-Rom sampling filter for the
case where we have a single frame image that is being reduced
in size. This isn't the highest quality filter but strikes
a good balance with speed vs appearance and is strictly better
than the GPU texture sampling options that I could try.
In a couple of quick tests, this doesn't seem to break cat'ing
the emoji test data so it seems like it isn't needed anymore.
In addition, it removes a bottleneck from processing image
streams produced by timg, which tend to be very large with
new newlines.
With this change, I'm able to view a 25fps source video at
about 60fps.
refs: https://github.com/wez/wezterm/issues/537
when the size is set to auto, we'd essentially take the image as-is
and overflow the terminal.
This commit makes auto scale down the image to fit the terminal dimensions
if it is too big.
The leftmost pixel was being set to at least 1 by the scale
function.
Fix that up by computing the x coordinate without calling
the scale function.
refs: https://github.com/wez/wezterm/issues/536
Using a boxed slice means that we hold exactly the memory required
for the file data, rather than the next-power-of-two, which can
be wasteful when a large number of images are being sent to
the terminal.
This is a API breaking change for termwiz, so bump its version.
refs: #534
While adding gif support I let this become unbounded.
This commit resolves that by categorizing images as either
single frame or animations.
Single frame images are decoded and held entirely in the texture
atlas, so occupy no additional space beyond the image file contents
and their sprite region in the texture atlas.
Animations are decoded into a set of frame bitmaps. There can be
up to 16 animations (each with their full set of frames) cached.
The individual frames may also exist within the texture atlas
if space permits.
refs: #534
https://i.giphy.com/media/3owvKqP4VSydZE4pvq/200w.gif cannot
be decoded as an animated gif due to this error: `No end code in lzw stream`
Ensure that we don't completely fail to process the render phase
as a result.
Previously, invalidation for animation was driven by the cursor
blink rate, which meant that animated gifs/pngs could not play
faster than 5fps (default blink interval is 200ms).
This commit calculates the next invalidation time based on the
closes next frame time of all animated cells in the viewport.
This is first draft; the animation rate is currently tied
to the cursor_blink_rate setting, so if the gif has frames that
are intended to display more frequently than that, they will
animate more slowly.
Animation is only carried out while the window has focus.
Animation increases the load on the GPU and thus uses more power.
It's kinda fun to stick one of these animated pixel gifs in the background:
https://imgur.com/gallery/F9DAH