-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Terminal does not render true color #484
Comments
Can't wait for this. I've been hacking away at hterm trying to get truecolor support but I feel like this is a way better option. |
Implementing this will need to be done here https://github.com/sourcelair/xterm.js/blob/365a9f949cc1acfb6c4649ee1d85da3bbc60f928/src/InputHandler.ts#L1276 The tricky part is determining how we store the colors against the character(s) and then how to render it (probably inline |
I may take a look at it when I get some time, but I can't say I'm too familiar with control sequences. I took a look at http://invisible-island.net/xterm/ctlseqs/ctlseqs.html but couldn't seem to find anything about true color or 24-bit color. Am I missing something, or is there some other resource that covers this? |
@cnsumner xterm currently cant display true color but has support for one of the proposed escape sequences. You can read more about this here: https://gist.github.com/XVilka/8346728 |
Put together a messy proof of concept to get a better idea of what we need to do here https://github.com/Tyriar/xterm.js/tree/484_truecolor Things that need to be done:
|
@Tyriar |
It looks like attributes currently consumed 9 bytes for bg, 9 bytes for bg and 5 bytes for flags, leaving plenty to squeeze width in at the end. The RGB definitions need 24 bytes (8*3) each. Here's the (slightly complicated) space saving approach I think you're suggesting:
Where attr1 is (29 bits):
And attr2 is (30 bits):
A simpler approach would use a number specifically for attributes:
Where attr is:
I want so badly to encapsulate these details as they really complicate things, I wonder if typescript will let us put getters on an array somehow. Using an object was 20x slower than an array based on a micro benchmark I did on jsperf, I know they're not always reliable but this is kind of what I expected as overhead to create an object based on a prototype. Whatever we do, the format needs to be documented very well. Right now you have to figure it out yourself by looking at |
Some more thoughts on memory saving:
|
Yes I think on most JS engines arrays with index access are still faster than objects and their property resolving. V8 got some extra optimizations for objects though. Construction and GC wise an array is faster due to the much simpler memory layout (this disadvantage can be omitted by reutilizing existing objects). I have no clue about the right layout here, problem is that any higly packed stuff will raise runtime penalty due to the needed transformations. (This is one reason not to use bitfields in C if memory is no concern - the needed shift operations will pollute the instruction cache leading to cache misses - the code runs much slower). |
@jerch interesting, I have 4 number version for simplicity right now in #756. So memory here is expected to be around: 5 * (1000 scrollback) * (8 bytes on 64-bit machine) * 80 = 3.2mb (before overhead of js array). The actual width of a typical VS Code terminal would see that double if we keep the current format. Seems pretty steep now that I look at it, especially since users will often have higher than 1000 scrollback and multiple active terminals. The trailing whitespace which really doesn't add much at all and could just as easily be null which would probably be a pretty huge win. The attribute/color set cache idea also seems promising, as long as there's a good way for fast access. A lightweight splay tree-like structure would be ideal (fast access for attributes uses most frequently). It might also be worth looking into reusing line data arrays when they're trimmed instead of just discarding them (eg. here). |
Yeah and with the engine overhead in mind it grows even bigger - everything in an array or object is stored as a reference, basically a pointer to the content. Dense js-arrays have a slight advantage here, they are formed as a C like array somewhere down the path (well actually ArrayLists). Sparse arrays and others objects are build with some tree magic to solve the property resolution. Maybe a TypedArray can solve this. There the integer stuff can reside directly at the index position in memory without an additional indirection. asm.js basically operates only on those. |
Here is a quick micro benchmark to compare TypedArray and js-Array for creation and data insertion: http://jsbench.github.io/#af3ea1056a70df2aa6775699d174df0d The TypedArray runs 10 times faster with FF and Chrome on my machine. This might be due to the preallocation, have not tested this with js-Array since it is discouraged. Not sure if the JITs spot the fact, that the value just increases by 1 every 8 bytes and even optimize this out. Then the benchmark is useless at all. The access is slightly worse for a TypedArray (maybe due to Downside of a TypedArray is the static block of memory when it comes to spare data (tricks to avoid data at all wont work here, the memory is "lost" anyways) or resizing with content wrapping. It is hard to get it right and likely to involve copying big chunks of data over and over. |
Hello. Any updates on this? Can't wait to get this working 😃 |
Is anyone actively working this issue? Is it being discussed anywhere else? @chabou @Tyriar? Is Microsoft helping given the usage in VS Code? This is the last lagging issue for using hyper in WSL on Windows 10 to provide a decent dev CLI workflow supporting tmux and vim/neovim. Other terminal emulators available to use with WSL just aren't pleasant to look at, wsltty is close, but tab support and plugin support is missing... |
@vastbinderj Why the missing true color support doesn't give you a decent dev CLI workflow? Honest question. |
@szmarczak and @vastbinderj |
@rfgamaral simple - I work across many many different unix/linux servers a day on very large enterprise systems with many microservices and not having decent color support in the main host is disruptive. To deal with the colors not being the same whether I'm on rhel or centos or debian, is painful. Also, sitting down to help a jr or peer developer on windows means I have to context switch if things don't work uniformly. However, I am super impressed how far wsl has come so quickly with improvements released on an almost monthly basis and the same with VS Code, it is outstanding. @jerch Thanks for the update, will wait patiently for #791 to be worked out... |
Greatly looking forward to this as well. |
It is worth remembering that JavaScript numbers can represent exact integers up to 53 bits. So you have 21 bits in addition to the 32 "convenient" bits. You can "or" in a bit by simple addition, if it is not set already. To read the high-order bits, just divide by a suitable power-of-two integer, and then use the regular bit operations. Of course there is a little more overhead working with the higher-order bits, but on modern CPUs division by power-or-two is relatively cheap - cheaper than memory accesses. I suggest using a single number with 50 bits: 25 bits each for foreground and background. One bit if set indicates we're using a 24-bit "true" color; if not set we're using "logical" (themeable) or 8-bit colors. The indicator bits should be the 2 lower-order bits; if unset the logical/8-bit colors could be in the next 30 bits, so we only use bits 32-50 if we're actually using true-color. |
@PerBothner We decided to go with a Uint32Array for the new buffer, and for convenience to put the colors into that array as well. This is not done yet as we want to sanitize the new impl first before supporting truecolor. Also I did some tests/calculations about possible layouts (see https://gist.github.com/jerch/27c2cf91ad313a25415873e4047b2900). Long story short - the ideas are about the tradeoff mem saving vs. runtime penalty. The transition to typed array already gave huge mem saving (currently implements the second idea from above, though the true color values are not applied yet). |
See microsoft/vscode#18544
The text was updated successfully, but these errors were encountered: