Open dankamongmen opened 2 years ago
So I think the plan above will work well enough for Kitty graphics, but it's more difficult to make it work for Sixel, since we have to scrub underneath it....
so let's keep a list in the renderstate struct. when we render and the previous pile is equal to the current pile, we can blow this list away (we might reuse it, but conceptually we can blow it away). when the previous pile is not equal to the current pile, we must act on it...actually, consider this: a bitmap plane might be moved into our pile from the pile that was just rendered. so in that case, we wouldn't want to erase it, despite a different pile having been last. so we'll operate on a per-sprixel basis. that means we'll need to use the id
field to correlate them (remember, we can't touch the actual sprixel, due to threading guarantees).
this could eliminate the HIDE
state, and it almost needs to, since otherwise when the pile came back, we'd try to erase the graphic a second time. no, you wouldn't eliminate the state, but you'd change the handler code -- if we were the last pile, erase. otherwise, just free the sprixel. yes.
we also need to handle the case where cell-pixel geometry changes. so:
sprixel
objects in state SPRIXEL_HIDE
, with metadata copied from the render. create one of these whenever we draw a sprixel in the raster cycle.SPRIXEL_HIDE
ought be freed and dropped, rather than being added to the sprixelcache (as it has already been erased).so the only hitch i see is that if we kill the image, and then come back to our pile without having hidden it, we need to redraw it. that's fine with sixel and with old Kitty, but in modern kitty, we don't keep a copy of the image. if we delete with a lowercase directive, our image ought be left in cache, and thus can be summoned up with a presentation action....
but we would need to know to do that. so that's presumably another state?
track_sprixel_metadata()
now creates sprixel_metadata
objects and enqueues them into the rstate
.
i don't think we can use last_pile
as a quick litmus. consider the [xray]
case: we only ever render one pile. we render to a new pile, then reparent that plane to the standard pile, which is rendered (after killing the previous plane). the alternate pile exists only as a scratch ground. so here we're always rendering the same pile....oh nevermind, we'll have the sprixel in SPRIXEL_HIDE
state in the pile, and thus find it. ok, all good.
in any case, it turns out i can eliminate the double-draw in [xray]
without all this by simply making lplane
shared between the two threads, and killing it every cycle (previously, it was alive for two). unfortunately, it turns out this saves no time -- kitty wasn't slowed by having two on-screen, and we're smart enough not to be redrawing etc. we still need this for general correctness, but it's not going to speed up anything of ours. c'est la vie!
well man, that sucks a lot of the impetus out of implementing this =]. master
now has an [xray]
clear of residue.
this is a grody solution whichever way you cut it, and like so many other things, mosaics would render it meaningless. i'm tempted to boot it past 3.0.0, and let mosaics take care of things naturally...
Run
[xray]
in kitty, and see that we have two graphics visible at any given time. This is because when one pile replaces another, we don't kill the old graphics ([xray]
happens to work with sixel because we scrub the entire affected area, but the problem exists there, too). We somehow need to kill these. See #1948 for background information.My first thought is that all current sprixels need be duplicated (not the graphic itself, just the metadata) post-render onto a new list kept in the notcurses object. Then, if we get a new pile, we throw these copies into our sprixelcache (or just special-case them, probably easier) and they are hidden. Each raster, this list is killed off (yeah, definitely easier to special-case).
That might work?