notcurses icon indicating copy to clipboard operation
notcurses copied to clipboard

use DECFRA to update glyphs underneath transparent graphic

Open dankamongmen opened this issue 3 years ago • 62 comments

DEC420+ supports DECFRA (CSI Pc ; Pt ; Pl ; Pb ; Pr $ x):

CSI Pc ; Pt ; Pl ; Pb ; Pr $ x
          Fill Rectangular Area (DECFRA), VT420 and up.
            Pc is the character to use.
            Pt ; Pl ; Pb ; Pr denotes the rectangle.

see #1619 for why this might be expected to work better than P2=0. there appears to be no terminfo capability corresponding to this escape sequence, alas.

also, what the hell is defbi "define_bit_image_region" as mentioned in terminfo(5)?

dankamongmen avatar Jun 09 '21 05:06 dankamongmen

there's also DECERA

CSI Pt ; Pl ; Pb ; Pr $ z
          Erase Rectangular Area (DECERA), VT400 and up.
            Pt ; Pl ; Pb ; Pr denotes the rectangle.

dankamongmen avatar Jun 09 '21 05:06 dankamongmen

CSI Pt ; Pl ; Pb ; Pr $ {
          Selective Erase Rectangular Area (DECSERA), VT400 and up.
            Pt ; Pl ; Pb ; Pr denotes the rectangle.

when you wish to selectively nuke from orbit

dankamongmen avatar Jun 09 '21 05:06 dankamongmen

CSI Pt ; Pl ; Pb ; Pr $ {
          Selective Erase Rectangular Area (DECSERA), VT400 and up.
            Pt ; Pl ; Pb ; Pr denotes the rectangle.

when you wish to selectively nuke from orbit

it looks like this plays with DECSCA (select character protection attribute)

dankamongmen avatar Jun 09 '21 05:06 dankamongmen

Most interesting i still think is DECCRA. That should also help improve performance and latency. It could be used to rerender moved parts on the screen in a single VT sequence.

christianparpart avatar Jun 21 '21 04:06 christianparpart

oooh DECCRA looks useful indeed, assuming it's actually widely implemented. with that said, it would be difficult for me to use it in my current model, except for sprixels without background glyphs, since everything else gets mixed down to a single layer during rendering. i could theoretically tag plane movements, and watch for interactions with other planes, and use DECCRA if there are none of the latter, but that's a fair amount of effort to avoid some glyph writes, especially if support is thin. for sixel, it could be useful indeed.

@ThomasDickey's observation here points out that styling/colors aren't copied over, which indeed looks to be the case:

The copied text takes on the line attributes of the destination area.

which is definitely the final nail in the coffin in terms of it being useful to me. the vast majority of non-bitmap bandwidth is going to styling escapes, not glyphs, so this wouldn't actually save me much bandwidth. and who knows whether it works on sixels?

nuking rectangular regions from orbit remains desirable.

dankamongmen avatar Jun 21 '21 17:06 dankamongmen

@dknl has some useful comments back in #1619:

It's hard to say though. Erasing a large sixel line-by-line can be really slow too, since the sixel may have to be copied and truncated over and over again. You definitely want to use escape sequences that erase a swat of cells in one go, rather than, say, printing spaces. There are escapes to do "rectangular editing" (and among them, a rectangular erase). Unfortunately they're not widely supported. Technically, they're only available on VT400 and newer (many terminals don't implement 400 features, or any 300 features for that matter). But, "rectangular editing" has it's own feature number in the primary DA response: 28. So, what I'm thinking is you can look for 28 in the DA response, ignore the VT level, and use DECERA (rectangular erase) if available. And fall back to ECH, ED, EL or whatever.... except that XTerm includes 28 in its DA response even in e.g VT220 mode, where it doesn't support rectangular erase. Unsure if this is a bug or if it's intentional.

his analysis of performance (and why P2=0 would likely be a miss) corresponds to a reply from @ThomasDickey a few weeks back when i reported what i thought a bug in XTerm performance.

dankamongmen avatar Jun 21 '21 17:06 dankamongmen

@ThomasDickey's observation here points out that styling/colors aren't copied over, which indeed looks to be the case:

He is wrong as much as the spec is concerned at least. Quote from the spec: "The copied text retains its character values and attributes."

There may have been buggy implementations though. - or at least it differs from my interpretation of the spec. See below.

The copied text takes on the line attributes of the destination area.

which is definitely the final nail in the coffin in terms of it being useful to me.

Check https://vt100.net/docs/tp83/appendixb.html and search for "line attributes". Line attributes are those that apply to the whole line and not those in the cell level (such as SGR attributes) unless i am completely drunk (nothing is impossible). ;-)

I hope this text is free of topys as i am writing from the phone :)

P.s. VT >= 400 for those who care

christianparpart avatar Jun 22 '21 05:06 christianparpart

perhaps! your reading seems reasonable, but i am still no expert in such things.

either way, rectangular copy just seems very difficult to fit to my implementation, except perhaps for bitmaps (when are rasterized as a plane, as opposed to glyphs, which are all rendered down to a single common frame first). when it comes to bitmaps, with Kitty i've got true moves, and with any new graphics protocol, i would hope for the same (and even with kitty's move, i can't use it very often due to other problems, see #1803 and #1395).

but i've got big hopes for DEC[EF]RA! need to experiment.

dankamongmen avatar Jun 22 '21 05:06 dankamongmen

looks like it might be sufficient to check for 28 in the Device Primary Attributes result.

dankamongmen avatar Jun 24 '21 23:06 dankamongmen

looks like it might be sufficient to check for 28 in the Device Primary Attributes result.

Exactly, Mr.Robot.

christianparpart avatar Jun 25 '21 03:06 christianparpart

DECERA doesn't appear to erase sixels in at least XTerm =[

dankamongmen avatar Jun 25 '21 19:06 dankamongmen

ED (Erase Display) does seem to apply to sixels, but only gives us complete display, below cursor, or above cursor. EL (Erase Line) does seem to apply to sixels, but gives us only complete line, left of cursor, or right of cursor

dankamongmen avatar Jun 25 '21 19:06 dankamongmen

EA (Erase Area) would presumably be perfect, but doesn't appear implemented very widely =[

dankamongmen avatar Jun 25 '21 19:06 dankamongmen

ECH looks like it might work! it's not as good as DECERA would be, but it does appear to wipe out sixel, and do so from the cursor, and through a controllable length. yessssssssssssssssssssss

dankamongmen avatar Jun 25 '21 19:06 dankamongmen

though, i was thinking about this, and it's all irrelevant. we don't go printing a ton of spaces atop sixels to erase them; we go printing whatever was in the damage buffer. otherwise, we'd just have to draw the latter for a total of two draws per cell.

  • "but dank," we thought, "this would still work if the damage buffer just had a lot of clear cells. ought we microoptimize for that case?"
  • "bah, other dank, who cares? that's not so frequent of a case. if we at least covered strings of every glyph, then, maybe, but this is just (uncolored) spaces"
  • "but dank", we continued, "we can actually do that, right? with repeat character, from terminfo's rep"
  • "don't be a maroon, other dank, we'd need identify such regions, and by then you might as well have just written them out"
  • "at render time, dank, sure -- though the idea that saving a byte of output is multiplied in impact might say otherwise. but what about at raster time? all you need do is lookahead into data you're about to write if you don't find such a region. there's no extra cache misses, and the work will surely be hidden under the AMAT. then it's just emit once, and use CSI Ps b, Ps=N, which at 4 + logN bytes beats 6 reps or more, and stomps Sixels just fine. you can even use CSI Ps X, Ps=N to beat just 5 spaces, though i'd probably just want to rely on a single escape's support."
  • "not too shabby, dank the third, and it makes us think--"
  • "[danks 2, 3, and 4 in unison] if we did perform it at render time, we could use uplinks to find rectangular regions in O(1)"
  • "danks, c'mon, remember? no rectangular replace char support atop sixels"

that original dank, such a buzzkill!

dankamongmen avatar Jun 25 '21 20:06 dankamongmen

DECERA doesn't appear to erase sixels in at least XTerm =[

This sounds like a bug in xterm? Can it be fixed?

christianparpart avatar Jun 26 '21 06:06 christianparpart

DECERA doesn't appear to erase sixels in at least XTerm =[ This sounds like a bug in xterm? Can it be fixed?

does contour erase sixels with DECERA? i didn't test beyond XTerm. the documentation at vt100.net didn't seem to state explicitly one way or the other.

like i noted later, i don't need DECERA in any case, since i changed things up two months back or so to simply reprint the cells underneath the sixel, which annihilates it while putting up the necessary backglyphs. so it doesn't buy me anything. i could possibly make use of DECFRA in the future, but i can't yet. using it with spaces, if those knocked out the sixel, would seem functionally equivalent to DECERA, so i'd just use that for that case.

let me go take a look at the XTerm code surrounding DECFRA and see if there are any indications...

dankamongmen avatar Jun 26 '21 06:06 dankamongmen

if it was going to happen, it would presumably happen in ScrnWipeRectangle(). ScrnWriteText() calls chararea_clear_displayed_graphics(), let me see if tucking the latter into the foremost solves this problem. if so, i'll send it off as a patch to Grandmaster Dickey, and we'll see what happens.

dankamongmen avatar Jun 26 '21 06:06 dankamongmen

ScreenFillRectangle(), rather

dankamongmen avatar Jun 26 '21 06:06 dankamongmen

sweet, my patch worked immediately. i'll send it on out.

dankamongmen avatar Jun 26 '21 06:06 dankamongmen

does contour erase sixels with DECERA? i didn't test beyond XTerm. the documentation at vt100.net didn't seem to state explicitly one way or the other.

Of course it does (in contour). ED is erssing it all too without mentioning Sixel, doesn't it.

Also, i am not sure the spec mentions that char writes are replacing image cells do they?

christianparpart avatar Jun 26 '21 06:06 christianparpart

xterm-368-decerasixels.diff.txt

godspeed little diff

dankamongmen avatar Jun 26 '21 06:06 dankamongmen

xterm-368-decerasixels.diff.txt

godspeed little diff

Are you living with a cable plugged into the powerplant?

christianparpart avatar Jun 26 '21 06:06 christianparpart

Date: Sat, 26 Jun 2021 02:55:24 -0400
From: nick black [email protected]
To: [email protected]
Subject: [PATCH] apply DECERA/DECFRA to sixels
Bcc: [email protected]

[-- Attachment #1 --]
[-- Type: text/plain, Encoding: 7bit, Size: 1.6K --]

Grandmaster Dickey,

I have found that DECERA/DECFRA do not apply to Sixel within the
specified rectangular region. The documentation I've read
doesn't seem explicit one way or the other:

https://vt100.net/docs/vt510-rm/DECERA.html
https://vt100.net/docs/vt510-rm/DECFRA.html

but perhaps you have documentation beyond this that locks things
down. Alternatively, perhaps the six-row nature of sixel isn't
immediately amenable to rectangular erasure, since it might end
mid-cell? But the possibility remains that this was merely an
oversight, in which case the attached patch ought at least be a
starting point for remedying the issue.

This probably ought apply to DECSERA, DECSEL, etc. If so, the
attached patch ought be easily enough generalized.

It seems to me intuitive and expected that these control sequences
would obliterate all (non-protected) content. Erase Display,
Erase Character, and Erase Line do (by test and visual
inspection) apply to Sixel, which seems correct (I've been
unable to get Erase Area working in any capacity, and assume
it's an aixterm-only deal).

This came up in the following Notcurses issue, if you're interested:

https://github.com/dankamongmen/notcurses/issues/1740

Please feel free to use this patch however you see fit, or to
reject it if inappropriate.

BTW, thanks for fixing up the TIOCGWINSZ-on-font-change issue in
Patch 368! I updated the historical reference at

https://nick-black.com/dankwiki/index.php?title=Theory_and_Practice_of_Sprixels#Other_people.27s_bugs

Hack on!

--nick

dankamongmen avatar Jun 26 '21 06:06 dankamongmen

Are you living with a cable plugged into the powerplant?

bah, patching well-written c is easy. now enriching uranium to weapons-grade using TEA carbon lasers, some Raman filters, and reverse-engineered SILEX, that takes talent.

dankamongmen avatar Jun 26 '21 06:06 dankamongmen

now that i think about it, it might be good to keep the current behavior. like i said, i have a way to wipe out sixels that works just fine, with only one write per cell. what i don't have is a way to update the glyphs under a partially-transparent sixel cell (sprixcell) without repainting the whole goddamn thing. if DECFRA works under transparent sixels, that could be very advantageous!!

tested and IT DOES WORK. holy shit, this could be a major win!

dankamongmen avatar Jun 26 '21 07:06 dankamongmen

2021-06-26-035046_884x556_scrot 2021-06-26-035127_884x556_scrot

dankamongmen avatar Jun 26 '21 07:06 dankamongmen

oh this is very very exciting indeed, hot shit goddamn. alright, it is imperative that that patch not be applied, and that the current behavior be preserved. i can pick up a big win from this.

dankamongmen avatar Jun 26 '21 07:06 dankamongmen

Date: Sat, 26 Jun 2021 03:56:28 -0400
From: nick black [email protected]
To: [email protected]
Subject: Re: [PATCH] apply DECERA/DECFRA to sixels

nick black left as an exercise for the reader:

Grandmaster Dickey,
I have found that DECERA/DECFRA do not apply to Sixel within the
specified rectangular region. The documentation I've read
doesn't seem explicit one way or the other:

Please withdraw this patch and suggestion, at least for DECFRA.
I just discovered that DECFRA replaces glyphs underneath a
partially-transparent Sixel without damaging the Sixel, which
ought allow me a tremendous speedup when I need perform such an
update.

Currently, if I have a glyph underneath a partially-transparent
Sixel, and I want to update it, I have to do so, and then redraw
at least the damaged part of the Sixel. Since "redrawing" such a
partially-transparent Sixel means first touching every glyph it
covers, I'm effectively drawing the entire affected region twice
to change any single glyph underneath it. With DECFRA working as
it currently does, I can just emit those as single-cell DECFRAs,
and avoid the entire redraw. That's great. That's a huge win.

--
nick black -=- https://www.nick-black.com
to make an apple pie from scratch,
you need first invent a universe.

dankamongmen avatar Jun 26 '21 07:06 dankamongmen

Now i am feeling confused about what the exact semantics of the VT sequences with respect to Sixel graphics is.

If ICH is splitting the sixel vertically in half then DECERA should also erase affecting cells respectively. Analogous all the oth r VT sequences.

christianparpart avatar Jun 26 '21 11:06 christianparpart