Xterm.js: Терминал не отображает истинный цвет

Созданный на 16 янв. 2017  ·  20Комментарии  ·  Источник: xtermjs/xterm.js

Самый полезный комментарий

Привет. Есть обновления по этому поводу? Не могу дождаться, когда это заработает 😃

Все 20 Комментарий

Не могу дождаться этого. Я взламывал hterm, пытаясь получить поддержку truecolor, но мне кажется, что это лучший вариант.

Реализовать это нужно здесь 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://gist.github.com/XVilka/8346728
Кстати, это частично указано в стандарте 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
  • Конечное решение должно быть компактным для памяти, а также быстрым для доступа, использование массива, двоичных флагов и сдвига битов для данных, вероятно, является лучшей идеей.

@Tyriar
Да, использование памяти резко возрастет, если она не будет оптимизирована для низкого потребления. Может быть, его можно упаковать вместе с width , это поле вряд ли станет больше 16, занимая только 4 байта (обычно вкладка по умолчанию 4 или 8). Это оставляет место для одного определения RGB * (при условии, что width - 32-битное целое число). Не уверен, сколько битов свободно в attribute , может быть, подойдет второе определение RGB .

Похоже, что атрибуты в настоящее время занимают 9 байтов для bg, 9 байтов для bg и 5 байтов для флагов, оставляя много, чтобы сжать ширину в конце. Для каждого определения RGB требуется 24 байта (8 * 3).

Вот (немного сложный) подход к экономии места, который, я думаю, вы предлагаете:

[char, attr1, attr2]

Где attr1 (29 бит):

  • ширина: 4 бита
  • 256 цветов или флаг истинного цвета: 1 бит
  • цвет bg: 24 бита

А attr2 (30 бит):

  • флаги: 5 бит
  • 256 цветов или флаг истинного цвета: 1 бит
  • цвет fg: 24 бита

Более простой подход будет использовать число специально для атрибутов:

[char, attr, truecolorBg, truecolorFg]

Где attr:

  • ширина: 4 байта
  • флаги: 5 байтов
  • 256 байт, цвет: 9 байт
  • 256 fg цвет: 9 байт

Я так сильно хочу инкапсулировать эти детали, поскольку они действительно усложняют ситуацию, мне интересно, позволит ли машинописный текст каким-то образом помещать геттеры в массив. Использование объекта было в 20 раз медленнее, чем массив на основе микротеста, который я провел на jsperf, я знаю, что они не всегда надежны, но это то, что я ожидал в качестве накладных расходов при создании объекта на основе прототипа.

Что бы мы ни делали, формат нужно очень хорошо задокументировать. Прямо сейчас вам нужно выяснить это самостоятельно, посмотрев на InputHandler.charAttributes .

Еще несколько мыслей по экономии памяти:

  • Если символ имеет ширину> 1, нам вообще не нужно хранить какие-либо данные для следующих символов. «Пустые символы» используются в качестве обходного пути и, вероятно, будут работать нормально при null .
  • Обычно набор символов оформлен в стиле, что означает, что атрибуты могут быть разделены между последовательностью символов.
  • Атрибуты могут быть кэшированы, и каждый символ использует указатель на одно из кешированных значений,

Да, я думаю, что на большинстве JS-движков массивы с доступом к индексу все еще быстрее, чем объекты и их свойства. Тем не менее, V8 получил некоторые дополнительные оптимизации для объектов. Построение и сборка мусора в массиве происходит быстрее из-за гораздо более простой структуры памяти (этот недостаток можно избежать, повторно используя существующие объекты).

Я понятия не имею о правильном макете здесь, проблема в том, что любой сильно упакованный материал приведет к увеличению времени выполнения из-за необходимых преобразований. (Это одна из причин не использовать битовые поля в C, если память не вызывает беспокойства - необходимые операции сдвига будут загрязнять кеш инструкций, что приведет к промахам кеша - код работает намного медленнее).
Имхо только тесты покажут, что здесь лучше всего работает.

@jerch интересно, у меня сейчас для простоты 4-х https://github.com/sourcelair/xterm.js/pull/756.

Таким образом, память здесь должна быть около: 5 * (1000 прокрутки) * (8 байт на 64-битной машине) * 80 = 3,2 МБ (до накладных расходов на массив js). Фактическая ширина типичного терминала VS Code увидит это вдвое, если мы сохраним текущий формат. Теперь, когда я смотрю на это, это кажется довольно крутым, особенно с учетом того, что у пользователей часто будет более 1000 прокрутки назад и несколько активных терминалов. Конечный пробел, который на самом деле ничего не добавляет, может быть также нулевым, что, вероятно, будет довольно большой победой.

Идея кеширования атрибутов / наборов цветов также кажется многообещающей, если есть хороший способ быстрого доступа. Легкая расширяемая древовидная структура была бы идеальной (быстрый доступ к атрибутам, которые используются наиболее часто).

Также, возможно, стоит подумать о повторном использовании массивов строковых данных, когда они обрезаны, вместо того, чтобы просто отбрасывать их ( например, здесь ).

Да, и с учетом накладных расходов движка, он становится еще больше - все в массиве или объекте хранится как ссылка, в основном указатель на контент. Плотные js-массивы имеют здесь небольшое преимущество, они формируются как C-подобный массив где-то по пути (ну, собственно, ArrayLists). Редкие массивы и другие объекты строятся с помощью некоторой древовидной магии для решения разрешения свойств.
Таким образом, для 64-битной эталонной вещи на ячейку добавляется еще 5 * 8 байтов (это в основном удваивает ваш расчет выше - 6,4 МБ). К содержимому можно добавить еще больше байтов помимо «реального содержимого», но это зависит от фактической реализации типов Integer и String.

Возможно, TypedArray может решить эту проблему. Здесь целочисленный материал может находиться непосредственно в позиции индекса в памяти без дополнительного косвенного обращения. asm.js в основном работает только с ними.

Вот небольшой тест для сравнения TypedArray и js-Array для создания и вставки данных: http://jsbench.github.io/#af3ea1056a70df2aa6775699d174df0d

TypedArray работает в 10 раз быстрее с FF и Chrome на моем компьютере. Это может быть связано с предварительным распределением, не тестировал это с помощью js-Array, так как это не рекомендуется. Не уверен, заметят ли JIT тот факт, что значение просто увеличивается на 1 каждые 8 ​​байтов, и даже оптимизируют его. Тогда бенчмарк вообще бесполезен.

Доступ немного хуже для TypedArray (возможно, из-за преобразования Number ), потребление памяти намного лучше с TypedArray.

Обратной стороной TypedArray является статический блок памяти, когда дело доходит до резервных данных (уловки, позволяющие избежать данных вообще, здесь не работают, память в любом случае «теряется») или изменение размера с переносом содержимого. Трудно сделать это правильно и, вероятно, придется копировать большие фрагменты данных снова и снова.

Привет. Есть обновления по этому поводу? Не могу дождаться, когда это заработает 😃

Кто-нибудь активно работает над этим вопросом? Обсуждается ли это где-нибудь еще? @chabou @Tyriar? Помогает ли Microsoft использовать в VS Code?

Это последняя проблема, связанная с использованием Hyper в WSL в Windows 10, чтобы обеспечить достойный рабочий процесс CLI для разработчиков, поддерживающий tmux и vim / neovim. Другие эмуляторы терминала, доступные для использования с WSL, просто не приятно смотреть, wsltty близок, но поддержка вкладок и плагинов отсутствует ...

@vastbinderj Почему отсутствие поддержки истинного цвета не дает вам достойного рабочего процесса CLI разработчика? Честный вопрос.

@szmarczak и @vastbinderj
Этот вопрос все еще стоит на повестке дня, но он блокируется из-за высокого использования памяти, которое он представит с текущим дизайном буфера терминала. Это привлечет больше внимания, когда # 791 предоставит нам более эффективную компоновку буфера.

@rfgamaral simple - я работаю на множестве разных серверов unix / linux в день на очень больших корпоративных системах с множеством микросервисов и отсутствие достойной поддержки цвета на главном хосте - это разрушительно. Больно иметь дело с разными цветами, независимо от того, использую ли я rhel, centos или debian. Кроме того, если я сижу, чтобы помочь младшему или коллеге-разработчику по Windows, мне нужно переключать контекст, если что-то не работает единообразно. Тем не менее, я очень впечатлен тем, насколько быстро wsl продвинулся с улучшениями, выпускаемыми почти ежемесячно, и то же самое с VS Code, он выдающийся.

@jerch Спасибо за обновление, буду терпеливо ждать, пока проработает # 791 ...

С нетерпением жду этого.

Стоит помнить, что числа JavaScript могут представлять точные целые числа до 53 бит. Таким образом, у вас есть 21 бит в дополнение к 32 «удобным» битам. Вы можете добавить немного «или» простым добавлением, если оно еще не установлено. Чтобы прочитать старшие биты, просто разделите на подходящее целое число степени двойки, а затем используйте обычные битовые операции.

Конечно, при работе с битами более высокого порядка накладные расходы немного выше, но на современных процессорах деление на мощность или два относительно дешево - дешевле, чем доступ к памяти.

Я предлагаю использовать одно число с 50 битами: по 25 бит для переднего и заднего плана. Один бит, если установлен, означает, что мы используем 24-битный «истинный» цвет; если не установлен, мы используем «логические» (тематические) или 8-битные цвета. Биты индикатора должны быть двумя младшими битами; если не задано, логические / 8-битные цвета могут быть в следующих 30 битах, поэтому мы используем биты 32-50, только если мы действительно используем истинный цвет.

@PerBothner Мы решили использовать Uint32Array для нового буфера, а также для удобства помещать цвета в этот массив. Это еще не сделано, так как мы хотим сначала очистить новый impl, прежде чем поддерживать truecolor.

Также я провел несколько тестов / вычислений о возможных макетах (см. Https://gist.github.com/jerch/27c2cf91ad313a25415873e4047b2900). Короче говоря, идеи заключаются в компромиссе между сохранением памяти и штрафом во время выполнения. Переход к типизированному массиву уже дал огромную экономию памяти (в настоящее время реализуется вторая идея сверху, хотя истинные значения цвета еще не применяются).

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

johnpoth picture johnpoth  ·  3Комментарии

Mlocik97-issues picture Mlocik97-issues  ·  3Комментарии

jerch picture jerch  ·  3Комментарии

parisk picture parisk  ·  3Комментарии

fabiospampinato picture fabiospampinato  ·  4Комментарии