¿Cómo una aplicación WebAssembly asigna sus llamadas nativas de Windows/OpenGL/Vulkan a un elemento de lienzo en DOM?

5 minutos de lectura

Avatar de usuario de Rafael Beckel
rafael beckel

Estoy leyendo sobre WebAssembly y tenía curiosidad sobre cómo trasladar la programación de gráficos como Vulkan u OpenGL a un elemento de lienzo. La documentación es larga, y creo que eventualmente resolveré esto, pero tenía curiosidad y no tuve éxito al buscar la respuesta en el acto.

Hasta ahora, sé que puede exportar funciones a JS, y JS hará el trabajo sucio de manipular el DOM como de costumbre.

Podría escribir WebGL directamente, pero ese no es mi punto. He visto juegos portados a WebAssembly y me gustaría saber cómo funciona. ¿Cómo WebAssembly puede representar algo si no tiene acceso directo al DOM? Por lo general, las aplicaciones gráficas usan un administrador de ventanas externo como GLFW o SDL para crear un contexto de ventana para dibujar tus cosas.

Si compilo un programa utilizando bibliotecas que esperan un entorno con un objeto de ventana, ¿cómo se asignan estas instrucciones al lienzo si no existe tal concepto en el DOM? ¿Necesito adaptar mi programa C++ de alguna manera?

  • @ColinE Creo que su edición es técnicamente correcta, pero cambia la intención de la pregunta. En el momento en que lo escribí, no sabía que era Emscripten el que realmente generaba el pegamento. Estaba leyendo las especificaciones y documentos de WebAssembly. Tal vez una mejor redacción sería “Cómo una aplicación WebAssembly mapea su…”

    –Rafael Beckel

    21 de enero de 2020 a las 22:47

Avatar de usuario de Rafael Beckel
rafael beckel

OK, resulta que la respuesta estaba en la misma página que estaba leyendopero un poco más abajo.

La respuesta es que es necesario tener un código de “pegamento” de Javascript para cargar .wasm y convertir las llamadas de biblioteca nativa al contexto DOM, pero no es necesario escribirlo a mano. La gente usa Emscriptenque incluye la emulación del sistema de archivos, la migración a las bibliotecas de medios más populares, como SDL, y genera tanto el código .wasm como su equivalente JS Glue.

Desde el Página de ensamblaje web de Mozilla:

La herramienta Emscripten puede tomar prácticamente cualquier código fuente de C/C++ y compilarlo en un módulo .wasm, además del código de “pegamento” de JavaScript necesario para cargar y ejecutar el módulo, y un documento HTML para mostrar los resultados del código.

En pocas palabras, el proceso funciona de la siguiente manera:

  1. Emscripten primero introduce C/C++ en clang+LLVM, una cadena de herramientas de compilación de C/C++ de código abierto madura, incluida como parte de XCode en OSX, por ejemplo.
  2. Emscripten transforma el resultado compilado de clang+LLVM en un binario .wasm.
  3. Por sí mismo, WebAssembly actualmente no puede acceder directamente al DOM; solo puede llamar a JavaScript, pasando tipos de datos primitivos enteros y de coma flotante. Por lo tanto, para acceder a cualquier API web, WebAssembly necesita llamar a JavaScript, que luego realiza la llamada a la API web. Por lo tanto, Emscripten crea el código de enlace HTML y JavaScript necesario para lograrlo.

Limitaciones:

Emscripten solo es totalmente compatible portátil código C y C++, y necesita habilitar algunas optimizaciones de acuerdo con su Pautas de portabilidad.

Además, debe tener en cuenta las limitaciones inherentes de la plataforma web y el tiempo de ejecución de JS, por lo que no tiene acceso directo al sistema de archivos y no puede realizar llamadas de red sincrónicas (de bloqueo), como se detalla en Limitaciones de la API página.

OpenGL y Vulkan:

Específicamente para OpenGL, dado que el código finalmente se traducirá a un contexto WebGL aislado, debe limitarse a lo que ofrece WebGL (es decir, OpenGL ES 2.0). De acuerdo a Optimización de WebGL página, Emscripten convertirá su código a WebGL 1 por defecto, con menos capacidades y sintaxis menos amigable, pero soportado por más plataformas. Sin embargo, también puede apuntar a WebGL 2, que ofrece una API mejor y un par de optimizaciones de hardware.

Para Vulkan, actualmente no hay soporte nativo, pero hay una discusión en curso en W3C para publicar un WebGPU especificación. Esto es su página de Github con información actualizada y la soporte actual del navegador página.

También hay un experimento Implementación de WebGPU Rust de Mozilla, por lo que ya podemos echar un vistazo al futuro.

ACTUALIZACIÓN MAYO 2023: cromo tiene acaba de lanzar WebGPU

  • ¡Gracias por la maravillosa respuesta! ¿Hay alguna actualización reciente relacionada con esto? Tengo curiosidad por saber cómo será compatible el ensamblaje web con Vulkan. ¿Está progresando webassembly hacia la creación de código js glue para cada biblioteca de vulkan, mental y d3d12? ¿O se está desarrollando en la dirección de convertir vlukan api a webgpu al convertir código nativo a webassembly?

    – Sparkleholic

    6 de agosto de 2021 a las 13:19


  • La estandarización es un proceso tedioso y largo porque afecta a todos los proveedores de navegadores y muchas personas de todos los rincones de la industria tienen algo que decir al respecto. Esta es su página de Github con trabajo en curso: github.com/gpuweb/gpuweb A día de hoy, WebGPU sigue siendo un borrador, pero están trabajando activamente en ello.

    –Rafael Beckel

    7 de agosto de 2021 a las 8:36

  • Parece que están trabajando en algún tipo de capa de abstracción. Solicitas un adaptador al navegador, y el navegador te lo devuelve. Entonces, usa el adaptador para escribir su código GPU (parece que también hay un nuevo lenguaje de sombreado wgsl) y el navegador puede elegir el backend (Vulkan / Metal / DirectX / OpenGL) dependiendo de dónde se esté ejecutando.

    –Rafael Beckel

    7 de agosto de 2021 a las 8:59

¿Ha sido útil esta solución?