Управляйте байтами холста непосредственно из WebAssembly - PullRequest
2 голосов
/ 10 февраля 2020

Я абсолютный новичок в Rust и WebAssembly. Я пытался найти способ рисовать на элементе canvas с учетом производительности.

Чтобы рисовать на canvas с помощью Rust и WebAssembly, я обычно нахожу примеры, в которых они будут использовать браузер CanvasRenderingContext2D интерфейс и черпать данные на нем они получат от WASM

const canvasContext = canvasElement.getContext("2d");
const canvasImageData = canvasContext.createImageData(width, height);
const imageDataArray = getWasmImageDataArray()
canvasImageData.data.set(imageDataArray);
canvasContext.clearRect(0, 0, width, height);
canvasContext.putImageData(canvasImageData, 0, 0);

Источник: https://wasmbyexample.dev/examples/reading-and-writing-graphics/reading-and-writing-graphics.rust.en-us.html

Существуют варианты этого, где они будут связывать canvas API для Rust и выполнения операций в Rust / WebAssembly, но, тем не менее, они всегда будут использовать API CanvasRenderingContext2D для рисования на холсте.

Это, конечно, означает, что от Rust / WebAssembly есть обходной путь canvas API браузера в буфер отображения холста, что означает снижение производительности.

Мне интересно, есть ли другой способ: можно ли связать буфер для пикселей, которые холст отображает непосредственно Руст и напрямую манипулировать этим буфером, чтобы изменить то, что показывает холст? Вроде как (псевдокод)

Rust Псевдокод:

// Makes whole canvas black
drawOnCanvasDisplayBuffer(displayBuffer) {
  for(i = 0; i < displayBuffer.width; i++) {
    for(j = 0; j < displayBuffer.height; j++) {
      displayBuffer[i][j] = COLOR_BLACK
    }
  }
}

1 Ответ

2 голосов
/ 10 февраля 2020

WebAssembly имеет очень ограниченные возможности ввода / вывода. Единственный способ, которым он может взаимодействовать со своей хост-средой (обычно браузером), напрямую через импортируемые / экспортируемые функции или косвенно через линейную память.

В приведенном вами примере имеется модуль WebAssembly, в котором его линейная память используется совместно с хостом, что позволяет читать и записывать его как модулю WebAssembly, так и хосту JavaScript. Это идеальный подход для создания буфера изображения для операций с холстом.

Мне интересно, есть ли другой способ: возможно ли привязать буфер для пикселей, которые холст отображает непосредственно к Rust и напрямую манипулировать этим буфером, чтобы изменить то, что показывает холст?

Нет, это не так. Экземпляр общей памяти должен иметь тип WebAssembly.Memory , это не может быть произвольный буфер.

Обратите внимание, что в вашем примере кода операция clearRect не требуется:

canvasContext.clearRect(0, 0, width, height); // ***
canvasContext.putImageData(canvasImageData, 0, 0)
...