dankamongmen / notcurses

blingful character graphics/TUI library. definitely not curses.
https://nick-black.com/dankwiki/index.php/Notcurses
Other
3.59k stars 112 forks source link

need to wipe sixels on move #1555

Closed dankamongmen closed 3 years ago

dankamongmen commented 3 years ago

We don't bother performing an actual wipe on Sixels, since you can just write over the sprixcell directly. We mark the sprixcell as SPRIXCELL_ANNIHILATED in the TAM, which is good if we're doing multiframe media -- we wipe the annihilated cells as we construct the sixel itself, eliminating flicker (we don't have to redraw the text which annihilated the sprixcell).

If we move the sixel, though, we want to effect the wipes. Not doing so is leading to annoying flicker in intro on at least xterm, where the orca's Segway shows up for a frame atop the FPS graph, then gets erased. It ought never be displayed. The easiest way to do this is likely calling sixel_blit() afresh, just like if we had multiframe media, but it might be faster to do the change inline. We had code to do this latter, which we can resurrect and benchmark against a recreation.

that wipe code was dirty as fuck, so maybe it's best left where it lies.

this bug can be considered closed when we no longer see the flicker in xterm for intro.

dankamongmen commented 3 years ago

hrmmm, we have a lot of freedom as to when we can do this wipe, pretty much anywhere from when sprixel_movefrom() is called to the render/raster cycle, so long as it's no work when no work needs doing (otherwise, it could burn us multiple times if the plane is moved multiple times between renders). and if we can do it in the render/raster cycle, that means we can just reuse our old code directly...which has almost got to be faster than a requantization and all that, right? did we actually have that code working? i only ask because sixel_blit() takes a lot of shit to get going...OH, OH, and ALSO, we can't run it at all unless we have the source data, and since we're not bound to an ncvisual anymore, we can't rely on that. so yeah, calling sixel_blit() afresh simply will not fly. fuck me in the ass, i guess it's sixel_wipe() after all, called from paint_sprixel() just as it is for kitty, but only when being moved...no, we can't do that; we have to take the wipe in the raster cycle when it happens under this scheme. we can't postpone it.

SO, instead, we have an idempotent scrubber that walks the entirety of the sixel, checks each block against the TAM, and anything which oughtn't be there is dropped. that's actually easy enough, and nice cache-wise, and probably doesn't take much longer than a single worst-case wipe. ok, yeah, i like this! fuck, we might want to adopt this same scheme for kitty (but run it any raster cycle where there's a wipe, rather than upon a move)! yeah baby, yeah! ok!

dankamongmen commented 3 years ago

ok i fuck with this hard for sure! let's do it!

dankamongmen commented 3 years ago

last question: can we always do it in-place? like, always? i don't think so. imagine we have

!8~ (RLE of 8 pixels)

and have to cut out 4 pixels. that could very easily require

!4?!4~

which is longer than the original. in fact, this is pretty likely to happen. so let's just copy from one buffer to another rather than trying to edit truly "in-place". certainly keep it limited to a single stream, though.

dankamongmen commented 3 years ago

and let's maybe guard this whole thing with a boolean somehow. said boolean would ideally be per sprixel, but given that we only need do this when in the MOVED state, i think one global to the raster cycle is sufficient for now.

dankamongmen commented 3 years ago

We're seeing this annoyance even on the mighty foot, where pretty much everything else works wonderfully (way to go @dnkl , finally got Wayland going today, this is fast as shit).

dnkl commented 3 years ago

this is fast as shit

I do try :)

dankamongmen commented 3 years ago

just for verification, we absolutely are bringing along the SPRIXCELL_ANNIHILATED sprixcells:

Sprixel 1 (0x55dc2fe41500) 23x28 (510x300) n: 0x55dc2fe40c00 state: 1
2222222211111222222222222222
2222222110001222222222222222
2222221100001122222222222222
2222211000000112222222222222
2211110000000012222222222222
2110000000000001222222222222
1101000000000001111111111222
1111111100000000000000111122
2222211110000000000111122222
2222221110000000001122222222
2222222110000000000122222222
2222222221111000000111222222
2222222222111110000001122222
2222222222211111100000112222
2222222222221011000000011222
2222222222221000000000001122
2222222222210000000000000012
2222222222210000000000000011
3333333333333333333333333333
3333333333333333333333333333
3333333333333333333333333333
3333333333333333333333333333
3333333333333333333333333333