Merge pull request #77 from daxpedda/wasm-atomics
Fix multi-threaded Wasm
This commit is contained in:
commit
379910cb8e
3 changed files with 31 additions and 4 deletions
5
.github/workflows/ci.yml
vendored
5
.github/workflows/ci.yml
vendored
|
|
@ -50,11 +50,14 @@ jobs:
|
||||||
# We're using Windows rather than Ubuntu to run the wasm tests because caching cargo-web
|
# We're using Windows rather than Ubuntu to run the wasm tests because caching cargo-web
|
||||||
# doesn't currently work on Linux.
|
# doesn't currently work on Linux.
|
||||||
- { target: wasm32-unknown-unknown, os: windows-latest, }
|
- { target: wasm32-unknown-unknown, os: windows-latest, }
|
||||||
|
include:
|
||||||
|
- rust_version: nightly
|
||||||
|
- { target: wasm32-unknown-unknown, os: windows-latest, options: -Zbuild-std=panic_abort,std, rustflags: -Ctarget-feature=+atomics }
|
||||||
|
|
||||||
env:
|
env:
|
||||||
RUST_BACKTRACE: 1
|
RUST_BACKTRACE: 1
|
||||||
CARGO_INCREMENTAL: 0
|
CARGO_INCREMENTAL: 0
|
||||||
RUSTFLAGS: "-C debuginfo=0 --deny warnings"
|
RUSTFLAGS: "-C debuginfo=0 --deny warnings ${{ matrix.platform.rustflags }}"
|
||||||
OPTIONS: ${{ matrix.platform.options }}
|
OPTIONS: ${{ matrix.platform.options }}
|
||||||
FEATURES: ${{ format(',{0}', matrix.platform.features ) }}
|
FEATURES: ${{ format(',{0}', matrix.platform.features ) }}
|
||||||
CMD: ${{ matrix.platform.cmd }}
|
CMD: ${{ matrix.platform.cmd }}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,7 @@ foreign-types = "0.3.0"
|
||||||
objc = "0.2.7"
|
objc = "0.2.7"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
|
js-sys = "0.3.55"
|
||||||
wasm-bindgen = "0.2.78"
|
wasm-bindgen = "0.2.78"
|
||||||
|
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
|
[target.'cfg(target_arch = "wasm32")'.dependencies.web-sys]
|
||||||
|
|
|
||||||
29
src/web.rs
29
src/web.rs
|
|
@ -3,7 +3,6 @@
|
||||||
#![allow(clippy::uninlined_format_args)]
|
#![allow(clippy::uninlined_format_args)]
|
||||||
|
|
||||||
use raw_window_handle::WebWindowHandle;
|
use raw_window_handle::WebWindowHandle;
|
||||||
use wasm_bindgen::Clamped;
|
|
||||||
use wasm_bindgen::JsCast;
|
use wasm_bindgen::JsCast;
|
||||||
use web_sys::CanvasRenderingContext2d;
|
use web_sys::CanvasRenderingContext2d;
|
||||||
use web_sys::HtmlCanvasElement;
|
use web_sys::HtmlCanvasElement;
|
||||||
|
|
@ -142,9 +141,33 @@ impl<'a> BufferImpl<'a> {
|
||||||
.flat_map(|pixel| [(pixel >> 16) as u8, (pixel >> 8) as u8, pixel as u8, 255])
|
.flat_map(|pixel| [(pixel >> 16) as u8, (pixel >> 8) as u8, pixel as u8, 255])
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
#[cfg(target_feature = "atomics")]
|
||||||
|
let result = {
|
||||||
|
use js_sys::{Uint8Array, Uint8ClampedArray};
|
||||||
|
use wasm_bindgen::prelude::wasm_bindgen;
|
||||||
|
use wasm_bindgen::JsValue;
|
||||||
|
|
||||||
|
#[wasm_bindgen]
|
||||||
|
extern "C" {
|
||||||
|
#[wasm_bindgen(js_name = ImageData)]
|
||||||
|
type ImageDataExt;
|
||||||
|
|
||||||
|
#[wasm_bindgen(catch, constructor, js_class = ImageData)]
|
||||||
|
fn new(array: Uint8ClampedArray, sw: u32) -> Result<ImageDataExt, JsValue>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let array = Uint8Array::new_with_length(bitmap.len() as u32);
|
||||||
|
array.copy_from(&bitmap);
|
||||||
|
let array = Uint8ClampedArray::new(&array);
|
||||||
|
ImageDataExt::new(array, self.imp.width)
|
||||||
|
.map(JsValue::from)
|
||||||
|
.map(ImageData::unchecked_from_js)
|
||||||
|
};
|
||||||
|
#[cfg(not(target_feature = "atomics"))]
|
||||||
|
let result =
|
||||||
|
ImageData::new_with_u8_clamped_array(wasm_bindgen::Clamped(&bitmap), self.imp.width);
|
||||||
// This should only throw an error if the buffer we pass's size is incorrect.
|
// This should only throw an error if the buffer we pass's size is incorrect.
|
||||||
let image_data =
|
let image_data = result.unwrap();
|
||||||
ImageData::new_with_u8_clamped_array(Clamped(&bitmap), self.imp.width).unwrap();
|
|
||||||
|
|
||||||
// This can only throw an error if `data` is detached, which is impossible.
|
// This can only throw an error if `data` is detached, which is impossible.
|
||||||
self.imp.ctx.put_image_data(&image_data, 0.0, 0.0).unwrap();
|
self.imp.ctx.put_image_data(&image_data, 0.0, 0.0).unwrap();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue