Xterm.js: 终端不呈现真彩色

创建于 2017-01-16  ·  20评论  ·  资料来源: xtermjs/xterm.js

最有用的评论

你好。 有任何更新吗? 迫不及待想让这个工作😃

所有20条评论

等不及了。 我一直在尝试获得真彩色支持,但我觉得这是一个更好的选择。

实现这一点需要在这里完成https://github.com/sourcelair/xterm.js/blob/365a9f949cc1acfb6c4649ee1d85da3bbc60f928/src/InputHandler.ts#L1276

棘手的部分是确定我们如何针对字符存储颜色,然后如何渲染它(可能是内联style属性)。 像https://github.com/sourcelair/xterm.js/pull/450这样的东西可能会简化属性的添加。

有时间我可能会看一下,但我不能说我对控制序列太熟悉了。

我查看了http://invisible-island.net/xterm/ctlseqs/ctlseqs.html,但似乎找不到有关真彩色或 24 位彩色的任何信息。 我是否遗漏了什么,或者是否有其他资源可以涵盖这一点?

@cnsumner xterm 目前无法显示真彩色,但支持建议的转义序列之一。 您可以在此处阅读更多相关信息: https :
顺便说一句,这在 ECMA-48 标准中有部分规定。

把一个凌乱的概念证明放在一起,以更好地了解我们需要在这里做什么https://github.com/Tyriar/xterm.js/tree/484_truecolor

image

需要做的事情:

  • 该分支目前以0x1RRGGBB (fg) 或0x0RRGGBB (bg) 格式为每个字符添加另一个数字,表示它的“真彩色”,该数字适合 32 位整数
  • 它需要同时支持FG和BG的颜色,能够混合真彩和常色
  • curTrueColor超级丑
  • 支持逆
  • 重复使用单元格时需要清除颜色标志
  • 可能是时候重新考虑字符的编码方式了,当前的格式是:

    [attribute, character, width]
    
    • attribute :一个 32 位整数,包含 ascii fg、ascii bg 和标志(粗体、下划线、闪烁、反色、不可见),并非所有位都使用
    • char :空字符串(对于填充宽字符的 0 宽度字符)或单个字符 unicode 字符串
    • width :字符的宽度,目前可以是 0、1 或 2,但这可能包括更多以正确支持选项卡https://github.com/sourcelair/xterm.js/issues/734
  • 最终的解决方案应该是紧凑的内存并且可以快速访问,坚持使用数组、二进制标志和数据位移可能是最好的主意。

@泰瑞尔
是的,如果没有针对低消耗进行优化,内存使用量会爆炸。 也许它可以与width一起打包,这个字段不太可能超过 16 只消耗 4 个字节(选项卡默认为 4 或 8 通常)。 这为一个 RGB 定义*留下了空间(假设width是一个 32 位整数)。 不确定attribute有多少位是免费的,也许可以使用第二个 RGB 定义

看起来属性当前为 bg 消耗了 9 个字节,为 bg 消耗了 9 个字节,为标志消耗了 5 个字节,最后留下了足够的宽度。 RGB 定义每个需要 24 个字节 (8*3)。

这是我认为您建议的(稍微复杂的)节省空间的方法:

[char, attr1, attr2]

其中 attr1 是(29 位):

  • 宽度:4位
  • 是 256 色还是真彩色标志:1 位
  • 背景颜色:24 位

而 attr2 是(30 位):

  • 标志:5位
  • 是 256 色还是真彩色标志:1 位
  • fg 颜色:24 位

一种更简单的方法是使用专门用于属性的数字:

[char, attr, truecolorBg, truecolorFg]

其中 attr 是:

  • 宽度:4 字节
  • 标志:5 个字节
  • 256 bg 颜色:9 字节
  • 256 fg 颜色:9 字节

我非常想封装这些细节,因为它们确实使事情复杂化,我想知道 typescript 是否会让我们以某种方式将 getter 放在数组上。 使用对象比基于我在 jsperf 上所做的微基准测试的数组慢 20 倍,我知道它们并不总是可靠的,但这正是我所期望的基于原型创建对象的开销。

无论我们做什么,都需要很好地记录格式。 现在你必须通过查看InputHandler.charAttributes自己弄清楚。

关于内存节省的更多想法:

  • 如果一个字符的宽度 > 1,我们根本不需要为后面的字符存储任何数据。 “空字符”是一种解决方法,可能可以正常工作null
  • 通常一组字符是样式化的,这意味着属性可以在一系列字符之间共享。
  • 属性可以被缓存,每个字符使用一个指向缓存值之一的指针,

是的,我认为在大多数 JS 引擎上,具有索引访问的数组仍然比对象及其属性解析更快。 不过,V8 对对象进行了一些额外的优化。 由于更简单的内存布局,数组的构造和 GC 速度更快(可以通过重新利用现有对象来忽略此缺点)。

我不知道这里的正确布局,问题是任何高度包装的东西都会由于所需的转换而增加运行时损失。 (如果内存无关紧要,这就是不在 C 中使用位域的原因之一——所需的移位操作会污染指令缓存,导致缓存未命中——代码运行速度要慢得多)。
恕我直言,只有测试才会显示什么在这里效果最好。

@jerch有趣,为了简单起见,我现在在https://github.com/sourcelair/xterm.js/pull/756 中有 4 个数字版本

所以这里的内存预计约为:5 * (1000 回滚) * (64 位机器上的 8 字节) * 80 = 3.2mb (在 js 数组的开销之前)。 如果我们保持当前格式,典型 VS Code 终端的实际宽度会加倍。 现在我看它似乎很陡峭,特别是因为用户通常会有超过 1000 的回滚和多个活动终端。 尾随空白实际上根本没有增加太多,并且可能很容易为空,这可能是一个非常巨大的胜利。

只要有一种快速访问的好方法,属性/颜色集缓存的想法似乎也很有前途。 一个轻量级的树状结构将是理想的(快速访问最常用的属性)。

当线数据数组被修剪而不是仅仅丢弃它们时,也可能值得研究重用它们(例如here )。

是的,考虑到引擎开销,它变得更大 - 数组或对象中的所有内容都存储为引用,基本上是指向内容的指针。 密集的 js 数组在这里有一点优势,它们在路径的某处形成了一个类似 C 的数组(实际上是 ArrayLists)。 稀疏数组和其他对象是用一些树魔法构建的,以解决属性解析。
因此,对于 64 位,每个单元格的参考值增加了 5 * 8 个字节(它基本上使上面的计算翻倍 - 6.4mb)。 内容可以在“真实内容”旁边添加更多字节,但这取决于 Integer 和 String 类型的实际实现。

也许 TypedArray 可以解决这个问题。 整数内容可以直接驻留在内存中的索引位置,而无需额外的间接寻址。 asm.js 基本上只对那些进行操作。

这是一个快速的微基准,用于比较 TypedArray 和 js-Array 的创建和数据插入: http ://jsbench.github.io/#af3ea1056a70df2aa6775699d174df0d

在我的机器上使用 FF 和 Chrome 时,TypedArray 的运行速度提高了 10 倍。 这可能是由于预分配,由于不鼓励使用 js-Array,因此尚未对此进行测试。 不确定 JIT 是否发现了这个事实,即该值每 8 个字节增加 1,甚至对其进行优化。 那么基准就完全没有用了。

TypedArray 的访问稍微差一些(可能是由于Number转换),TypedArray 的内存消耗要好得多。

当涉及到备用数据(避免数据的技巧在这里根本不起作用,无论如何内存“丢失”)或通过内容包装调整大小时,TypedArray 的缺点是静态内存块。 很难做到正确,并且可能涉及一遍又一遍地复制大块数据。

你好。 有任何更新吗? 迫不及待想让这个工作😃

有没有人积极解决这个问题? 是否正在其他地方讨论? @chabou @Tyriar? 考虑到 VS Code 中的使用情况,Microsoft 是否提供帮助?

这是在 Windows 10 上使用 WSL 中的 hyper 来提供支持 tmux 和 vim/neovim 的不错的开发 CLI 工作流的最后一个滞后问题。 其他可与 WSL 一起使用的终端模拟器看起来并不令人愉快,wsltty 很接近,但缺少选项卡支持和插件支持......

@vastbinderj为什么缺少真彩色支持不能为您提供合适的开发 CLI 工作流程? 诚实的问题。

@szmarczak和 @vastbinderj
这个问题仍在议程上,但由于当前终端缓冲区设计会引入高内存使用量,因此有点受阻。 当#791 为我们带来更高效的缓冲区布局时,它会得到更多关注。

@rfgamaral simple - 我每天在许多不同的 unix/linux 服务器上工作,在具有许多微服务的非常大的企业系统上工作,并且在主主机中没有像样的颜色支持是破坏性的。 无论我是在 rhel、centos 还是 debian 上,处理颜色都不相同的问题是很痛苦的。 此外,坐下来帮助 Windows 上的 jr 或同行开发人员意味着如果事情不能一致地工作,我必须进行上下文切换。 然而,我对 wsl 几乎每个月都发布改进的速度如此之快印象深刻,VS Code 也是如此,它非常出色。

@jerch感谢您的更新,将耐心等待 #791 的制定...

对此也非常期待。

值得记住的是,JavaScript 数字可以表示最多 53 位的精确整数。 因此,除了 32 个“方便”位之外,您还有 21 个位。 如果尚未设置,您可以通过简单的加法来“或”。 要读取高位,只需除以合适的 2 的幂整数,然后使用常规位操作。

当然,使用高阶位会产生更多的开销,但在现代 CPU 上,按幂或 2 划分相对便宜 - 比内存访问便宜。

我建议使用一个 50 位的数字:前景和背景各 25 位。 如果设置了一位表示我们使用的是 24 位“真”色; 如果未设置,我们将使用“逻辑”(主题化)或 8 位颜色。 指示位应该是 2 个低位; 如果取消设置逻辑/8 位颜色可能在接下来的 30 位中,所以如果我们实际使用真彩色,我们只使用 32-50 位。

@PerBothner我们决定为新缓冲区使用 Uint32Array,并且为了方便也将颜色放入该数组中。 这还没有完成,因为我们想在支持真彩色之前先清理新的 impl。

我还对可能的布局进行了一些测试/计算(参见 https://gist.github.com/jerch/27c2cf91ad313a25415873e4047b2900)。 长话短说 - 这些想法是关于内存节省与运行时损失的权衡。 转换到类型化数组已经节省了大量内存(目前实现了上面的第二个想法,尽管尚未应用真实的颜色值)。

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

pfitzseb picture pfitzseb  ·  3评论

zhangjie2012 picture zhangjie2012  ·  3评论

jerch picture jerch  ·  3评论

parisk picture parisk  ·  3评论

tandatle picture tandatle  ·  3评论