Recientemente comencé a aprender un poco sobre cómo funciona Javascript bajo el capó y me di cuenta de que (en el contexto de Chrome) el motor v8 y las API web son diferentes. Aquí hay algunas preguntas que tengo con respecto a la API de lienzo específicamente:
getImageData() cada vez que queremos acceder a los píxeles de un lienzo determinado? Dado que el lienzo se basa en píxeles, ¿no debería haber una matriz de píxeles que la API del lienzo manipule cada vez que dibuje en él, lo que lo haría estáticamente disponible?ctx.fillRect() internamente? Intenté hacerlo manualmente cambiando colores de píxeles específicos, pero resultó ser drásticamente más lento. ¿Tal vez sea porque lo estoy haciendo en javascript y normalmente se hace internamente en c ++? ¿No hay forma de averiguarlo ya que la implementación está en sus propios códigos fuente?Podría estar confundiendo muchos conceptos ya que todavía no entiendo cómo funciona la API web o v8, por lo que se agradece cualquier aclaración.
¿Por qué necesitamos usar getImageData() cada vez que queremos acceder a los píxeles de un lienzo determinado? Dado que el lienzo se basa en píxeles, ¿no debería haber una matriz de píxeles que la API del lienzo manipule cada vez que dibuje en él, lo que lo haría estáticamente disponible?
Tiene razón, podría haberse hecho de esta manera, incluso hay discusiones activas sobre dar acceso directo al búfer de píxeles, lo que permite operaciones de lectura y escritura de copia cero.
Sin embargo, en el diseño original, se pensó que sería necesario separar completamente el búfer de píxeles de la ejecución del contexto actual. Esto permitió, por ejemplo, tener implementaciones basadas en GPU, donde todos los dibujos los realiza la GPU y donde el búfer de respaldo se almacena en la memoria de la GPU, por lo que no es accesible para los scripts.
También se debe tener en cuenta que la mayoría de las implementaciones usan almacenamiento en búfer doble, intercambiando entre un búfer frontal y un búfer posterior, para evitar el desgarro.
¿Hay alguna manera de entender cómo se implementan las API específicas? Por ejemplo, ¿cómo se hace
ctx.fillRect()internamente?
Siempre puede intentar navegar a través de las fuentes, Chrome tiene el útil https://source.chromium.org/ , Firefox tiene https://searchfox.org Sin embargo, para la API Canvas 2D, las cosas son un poco complejas en cuanto a dónde mirar de verdad. Cada navegador tiene al menos un motor de renderizado, en este motor vivirán todos los contenedores API, que luego harán llamadas a otro motor gráfico, que generará los gráficos.
En los navegadores basados en Chromium, el motor de renderizado se llama Blink , y el motor gráfico Skia , en Safari usan WebKit (del cual Blink se bifurcó) y Core Graphics, y en Firefox, IIRC Gecko usa varios motores gráficos y de renderizado, basados en el plataforma (Cairo, Core Graphics o Skia), por lo que buscar dónde se realiza la operación gráfica real en este navegador no es tan fácil.
Y para agregar algo de diversión, todos estos motores gráficos admitirán tanto una ruta de "procesamiento por software" (CPU) como una ruta "acelerada por hardware" (GPU).
Pero para ayudarlo a comenzar su viaje, la implementación de fillRect() de blink comienza aquí: https://source.chromium.org/chromium/chromium/src/+/main:third_party/blink/renderer/modules/canvas/ canvas2d/base_rendering_context_2d.cc;l=1075
Nota bene: el motor de JavaScript (por ejemplo, v8) tiene muy poco que hacer en todo este asunto.