Xterm.js: La terminal no muestra el color verdadero

Creado en 16 ene. 2017  ·  20Comentarios  ·  Fuente: xtermjs/xterm.js

Comentario más útil

Hola. ¿Alguna actualización sobre esto? No puedo esperar a que esto funcione 😃

Todos 20 comentarios

No puedo esperar por esto. He estado pirateando hterm tratando de obtener compatibilidad con truecolor, pero siento que esta es una opción mucho mejor.

La implementación de esto deberá hacerse aquí https://github.com/sourcelair/xterm.js/blob/365a9f949cc1acfb6c4649ee1d85da3bbc60f928/src/InputHandler.ts#L1276

La parte complicada es determinar cómo almacenamos los colores contra los caracteres y luego cómo renderizarlos (probablemente en línea style atributos). Algo como https://github.com/sourcelair/xterm.js/pull/450 probablemente simplificaría la adición de los atributos.

Puedo echarle un vistazo cuando tenga tiempo, pero no puedo decir que esté demasiado familiarizado con las secuencias de control.

Eché un vistazo a http://invisible-island.net/xterm/ctlseqs/ctlseqs.html pero parece que no pude encontrar nada sobre el color verdadero o el color de 24 bits. ¿Me estoy perdiendo algo o hay algún otro recurso que cubra esto?

@cnsumner xterm actualmente no puede mostrar el color verdadero, pero es compatible con una de las secuencias de escape propuestas. Puede leer más sobre esto aquí: https://gist.github.com/XVilka/8346728
Por cierto, esto se especifica en parte en el estándar ECMA-48.

Reúna una prueba de concepto desordenada para tener una mejor idea de lo que tenemos que hacer aquí https://github.com/Tyriar/xterm.js/tree/484_truecolor

image

Cosas que deben hacerse:

  • La rama actualmente agrega otro número a cada carácter que representa su 'truecolor' en el formato 0x1RRGGBB (fg) o 0x0RRGGBB (bg), que cabe en un entero de 32 bits
  • Que necesita para apoyar ambos colores fg y bg, y ser capaz de mezclar color verdadero y color regulares
  • curTrueColor es súper feo
  • Soporte inverso
  • Las marcas de color deben borrarse cuando se reutilizan las celdas
  • Puede que sea hora de repensar cómo se codifican los caracteres, el formato actual es:

    [attribute, character, width]
    
    • attribute : un entero de 32 bits que contiene ascii fg, ascii bg y banderas (negrita, subrayado, parpadeo, inverso, invisible), no se utilizan todos los bits
    • char : O la cadena vacía (para caracteres de ancho 0 que rellenan caracteres anchos) o una cadena Unicode de un solo carácter
    • width : el ancho del carácter, actualmente puede ser 0, 1 o 2, pero esto podría incluir más para admitir pestañas correctamente https://github.com/sourcelair/xterm.js/issues/734
  • La solución eventual debería ser compacta para la memoria y también de acceso rápido, quedarse con una matriz, indicadores binarios y desplazamiento de bits para los datos es probablemente la mejor idea.

@Tyriar
Sí, el uso de la memoria se disparará si no está optimizado para un bajo consumo. Tal vez se pueda empaquetar junto con width , es poco probable que este campo sea mayor que 16 consumiendo solo 4 bytes (la pestaña por defecto es 4 u 8 normalmente). Esto deja espacio para una definición RGB * (asumiendo que width es un número entero de 32 bits). No estoy seguro de cuántos bits hay libres en attribute , tal vez pueda ir la segunda definición RGB .

Parece que los atributos actualmente consumen 9 bytes para bg, 9 bytes para bg y 5 bytes para banderas, lo que deja mucho para exprimir el ancho al final. Las definiciones RGB necesitan 24 bytes (8 * 3) cada una.

Aquí está el enfoque de ahorro de espacio (un poco complicado) que creo que está sugiriendo:

[char, attr1, attr2]

Donde attr1 es (29 bits):

  • ancho: 4 bits
  • es de 256 colores o bandera de color verdadero: 1 bit
  • color bg: 24 bits

Y attr2 es (30 bits):

  • banderas: 5 bits
  • es de 256 colores o bandera de color verdadero: 1 bit
  • color fg: 24 bits

Un enfoque más simple usaría un número específicamente para atributos:

[char, attr, truecolorBg, truecolorFg]

Donde attr es:

  • ancho: 4 bytes
  • banderas: 5 bytes
  • 256 bg color: 9 bytes
  • Color de 256 fg: 9 bytes

Tengo tantas ganas de encapsular estos detalles ya que realmente complican las cosas, me pregunto si mecanografiar nos permitirá poner getters en una matriz de alguna manera. Usar un objeto fue 20 veces más lento que una matriz basada en un micro benchmark que hice en jsperf, sé que no siempre son confiables, pero esto es algo de lo que esperaba como sobrecarga para crear un objeto basado en un prototipo.

Hagamos lo que hagamos, el formato debe estar muy bien documentado. Ahora mismo tienes que averiguarlo tú mismo mirando InputHandler.charAttributes .

Algunos pensamientos más sobre el ahorro de memoria:

  • Si un carácter tiene un ancho de> 1, realmente no necesitamos almacenar ningún dato para los siguientes caracteres. Los "caracteres vacíos" están ahí como una solución y probablemente funcionarían bien siendo null .
  • Normalmente, se aplica un estilo a un conjunto de caracteres, lo que significa que los atributos se pueden compartir entre una secuencia de caracteres.
  • Los atributos se pueden almacenar en caché y cada carácter usa un puntero a uno de los valores en caché,

Sí, creo que en la mayoría de los motores JS las matrices con acceso al índice siguen siendo más rápidas que los objetos y la resolución de sus propiedades. Sin embargo, V8 obtuvo algunas optimizaciones adicionales para los objetos. En cuanto a la construcción y la GC, una matriz es más rápida debido al diseño de memoria mucho más simple (esta desventaja se puede omitir reutilizando los objetos existentes).

No tengo ni idea del diseño correcto aquí, el problema es que cualquier material muy empaquetado aumentará la penalización del tiempo de ejecución debido a las transformaciones necesarias. (Esta es una razón para no usar campos de bits en C si la memoria no es un problema; las operaciones de cambio necesarias contaminarán la caché de instrucciones y provocarán fallos en la caché; el código se ejecuta mucho más lento).
En mi opinión, solo las pruebas mostrarán qué funciona mejor aquí.

@jerch interesante, tengo una versión de 4 números para simplificar ahora mismo en https://github.com/sourcelair/xterm.js/pull/756.

Entonces, se espera que la memoria aquí sea de alrededor de: 5 * (1000 scrollback) * (8 bytes en una máquina de 64 bits) * 80 = 3.2mb (antes de la sobrecarga de la matriz js). El ancho real de una terminal típica de VS Code se duplicaría si mantenemos el formato actual. Parece bastante empinado ahora que lo miro, especialmente porque los usuarios a menudo tienen más de 1000 scrollback y múltiples terminales activos. El espacio en blanco final que realmente no agrega mucho y podría fácilmente ser nulo, lo que probablemente sería una gran victoria.

La idea de caché de conjunto de atributos / colores también parece prometedora, siempre que haya una buena forma de acceso rápido. Una estructura liviana en forma de árbol de extensión sería ideal (acceso rápido para los usos de atributos con mayor frecuencia).

También podría valer la pena considerar la reutilización de matrices de datos de línea cuando se recortan en lugar de simplemente descartarlas ( por ejemplo, aquí ).

Sí, y con la sobrecarga del motor en mente, crece aún más: todo en una matriz u objeto se almacena como referencia, básicamente un puntero al contenido. Las matrices js densas tienen una ligera ventaja aquí, se forman como una matriz similar a C en algún lugar del camino (bueno, en realidad ArrayLists). Las matrices dispersas y otros objetos se construyen con algo de magia de árbol para resolver la resolución de la propiedad.
Entonces, para 64 bits, la referencia agrega 5 * 8 bytes más por celda (básicamente duplica su cálculo anterior: 6.4mb). El contenido puede agregar aún más bytes al lado del "contenido real", pero esto depende de la implementación real del tipo Integer y String.

Quizás un TypedArray pueda resolver esto. Allí, las cosas enteras pueden residir directamente en la posición del índice en la memoria sin una indirección adicional. asm.js básicamente opera solo en aquellos.

Aquí hay un micro benchmark rápido para comparar TypedArray y js-Array para la creación e inserción de datos: http://jsbench.github.io/#af3ea1056a70df2aa6775699d174df0d

TypedArray se ejecuta 10 veces más rápido con FF y Chrome en mi máquina. Esto podría deberse a la preasignación, no lo he probado con js-Array ya que no se recomienda. No estoy seguro si los JIT detectan el hecho de que el valor simplemente aumenta en 1 cada 8 bytes e incluso lo optimiza. Entonces el punto de referencia es inútil en absoluto.

El acceso es un poco peor para TypedArray (tal vez debido a la conversión Number ), el consumo de memoria es mucho mejor con TypedArray.

La desventaja de TypedArray es el bloque estático de memoria cuando se trata de datos de repuesto (los trucos para evitar los datos no funcionarán aquí, la memoria se "pierde" de todos modos) o el cambio de tamaño con el ajuste de contenido. Es difícil hacerlo bien y es probable que implique copiar grandes cantidades de datos una y otra vez.

Hola. ¿Alguna actualización sobre esto? No puedo esperar a que esto funcione 😃

¿Alguien está trabajando activamente en este tema? ¿Se está discutiendo en algún otro lugar? @chabou @Tyriar? ¿Microsoft está ayudando dado el uso en VS Code?

Este es el último problema rezagado del uso de Hyper en WSL en Windows 10 para proporcionar un flujo de trabajo CLI de desarrollo decente que admita tmux y vim / neovim. Otros emuladores de terminal disponibles para usar con WSL simplemente no son agradables a la vista, wsltty está cerca, pero falta el soporte de pestañas y el soporte de complementos ...

@vastbinderj ¿

@szmarczak y @vastbinderj
Este problema todavía está en la agenda, pero un poco bloqueado debido al alto uso de memoria que introducirá con el diseño de búfer de terminal actual. Recibirá más atención cuando el # 791 nos haya traído un diseño de búfer más eficiente.

@rfgamaral simple: trabajo en muchos servidores unix / linux diferentes al día en sistemas empresariales muy grandes con muchos microservicios y no tener un soporte de color decente en el host principal es disruptivo. Tratar de que los colores no sean los mismos ya sea que esté en rhel, centos o debian, es doloroso. Además, sentarme para ayudar a un desarrollador jr o par en Windows significa que tengo que cambiar de contexto si las cosas no funcionan de manera uniforme. Sin embargo, estoy muy impresionado de lo lejos que ha llegado wsl tan rápido con las mejoras lanzadas casi mensualmente y lo mismo con VS Code, es sobresaliente.

@jerch Gracias por la actualización, esperaré pacientemente a que se resuelva el # 791 ...

Espero con ansias esto también.

Vale la pena recordar que los números de JavaScript pueden representar números enteros exactos de hasta 53 bits. Así que tiene 21 bits además de los 32 bits "convenientes". Puede "o" en un momento mediante una simple adición, si aún no está configurado. Para leer los bits de orden superior, simplemente divídalos por un número entero de potencia de dos adecuado y luego use las operaciones de bits normales.

Por supuesto, hay un poco más de sobrecarga trabajando con los bits de orden superior, pero en las CPU modernas, la división entre potencia o dos es relativamente barata, más barata que los accesos a la memoria.

Sugiero usar un solo número con 50 bits: 25 bits cada uno para el primer plano y el fondo. Un bit si está establecido indica que estamos usando un color "verdadero" de 24 bits; si no se establece, estamos usando colores "lógicos" (temáticos) o de 8 bits. Los bits indicadores deben ser los 2 bits de orden inferior; si no se establece, los colores lógicos / de 8 bits podrían estar en los siguientes 30 bits, por lo que solo usamos los bits 32-50 si en realidad estamos usando color verdadero.

@PerBothner Decidimos

También hice algunas pruebas / cálculos sobre posibles diseños (ver https://gist.github.com/jerch/27c2cf91ad313a25415873e4047b2900). En pocas palabras: las ideas son sobre la compensación entre ahorro de memoria y penalización por tiempo de ejecución. La transición a la matriz con tipo ya dio un gran ahorro de memoria (actualmente implementa la segunda idea de arriba, aunque los valores de color verdadero aún no se han aplicado).

¿Fue útil esta página
0 / 5 - 0 calificaciones