Rework fallback for postMessage issue

Now initialise all workers with module+memory separately, and then instead of using postMessage to send thread pointers, push them into a crossbeam-deque on the Rust side.

Rayon already depends on crossbeam-dequeue, so we're not even adding another dependency, and this model allows us to push "tasks" (thread pointers) on the main thread and pop them on worker threads in arbitrary order without sacrificing correctness.
This commit is contained in:
Ingvar Stepanyan
2020-04-27 23:18:42 +01:00
committed by Ingvar Stepanyan
parent 4c658b79ef
commit 0747d2c419
12 changed files with 253 additions and 255 deletions

257
codecs/oxipng/Cargo.lock generated
View File

@ -1,10 +1,16 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "adler32"
version = "1.1.0"
name = "adler"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b077b825e468cc974f0020d4082ee6e03132512f207ef1a02fd5d00d1f32d"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
name = "adler32"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2"
[[package]]
name = "autocfg"
@ -32,9 +38,9 @@ checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
[[package]]
name = "bumpalo"
version = "3.4.0"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
[[package]]
name = "bytemuck"
@ -50,9 +56,9 @@ checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
[[package]]
name = "cc"
version = "1.0.58"
version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a06fb2e53271d7c279ec1efea6ab691c35a2ae67ec0d91d7acec0caf13b518"
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
[[package]]
name = "cfg-if"
@ -78,16 +84,6 @@ dependencies = [
"cc",
]
[[package]]
name = "console_log"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494"
dependencies = [
"log",
"web-sys",
]
[[package]]
name = "crc"
version = "1.8.1"
@ -106,6 +102,16 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "crossbeam-channel"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cced8691919c02aac3cb0a1bc2e9b73d89e832bf9a06fc579d4e71b68a2da061"
dependencies = [
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
name = "crossbeam-deque"
version = "0.7.3"
@ -132,17 +138,6 @@ dependencies = [
"scopeguard",
]
[[package]]
name = "crossbeam-queue"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570"
dependencies = [
"cfg-if",
"crossbeam-utils",
"maybe-uninit",
]
[[package]]
name = "crossbeam-utils"
version = "0.7.2"
@ -156,9 +151,9 @@ dependencies = [
[[package]]
name = "deflate"
version = "0.8.6"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174"
checksum = "050ef6de42a33903b30a7497b76b40d3d58691d4d3eec355348c122444a388f0"
dependencies = [
"adler32",
"byteorder",
@ -171,19 +166,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
[[package]]
name = "hermit-abi"
version = "0.1.15"
name = "hashbrown"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9"
checksum = "00d63df3d41950fb462ed38308eea019113ad1508da725bbedcd0fa5a85ef5f7"
[[package]]
name = "hermit-abi"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "725cf19794cf90aa94e65050cb4191ff5d8fa87a498383774c47b332e3af952e"
dependencies = [
"libc",
]
[[package]]
name = "image"
version = "0.23.7"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2397fc43bd5648b7117aabb3c5e62d0e62c194826ec77b0b4d0c41e62744635"
checksum = "9062b90712d25bc6bb165d110aa59c6b47c849246e341e7b86a98daff9d49f60"
dependencies = [
"bytemuck",
"byteorder",
@ -195,14 +196,24 @@ dependencies = [
[[package]]
name = "indexmap"
version = "1.4.0"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c398b2b113b55809ceb9ee3e753fcbac793f1956663f3c36549c1346015c2afe"
checksum = "55e2e4c765aa53a0424761bf9f41aa7a6ac1efa87238f59560640e27fca028f2"
dependencies = [
"autocfg",
"hashbrown",
"rayon",
]
[[package]]
name = "inflate"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
dependencies = [
"adler32",
]
[[package]]
name = "itertools"
version = "0.9.0"
@ -212,15 +223,6 @@ dependencies = [
"either",
]
[[package]]
name = "js-sys"
version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4b9172132a62451e56142bff9afc91c8e4a4500aa5b847da36815b63bfda916"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -229,24 +231,33 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.72"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9f8082297d534141b30c8d39e9b1773713ab50fdbe4ff30f750d063b3bfd701"
checksum = "dea0c0405123bba743ee3f91f49b1c7cfb684eef0da0a50110f758ccf24cdff0"
[[package]]
name = "libdeflater"
version = "0.2.0"
name = "libdeflate-sys"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66dca08b13369865b2f6dca1dd05f833985cbe6c12a676b04d55f78b85e80246"
checksum = "21e39efa87b84db3e13ff4e2dfac1e57220abcbd7fe8ec44d238f7f4f787cc1f"
dependencies = [
"cc",
]
[[package]]
name = "log"
version = "0.4.8"
name = "libdeflater"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
checksum = "a4810980d791f26d470e2d7d91a3d4d22aa3a4b709fb7e9c5e43ee54f83a01f2"
dependencies = [
"libdeflate-sys",
]
[[package]]
name = "log"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [
"cfg-if",
]
@ -259,27 +270,28 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
[[package]]
name = "memoffset"
version = "0.5.5"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c198b026e1bbf08a937e94c6c60f9ec4a2267f5b0d2eec9c1b21b061ce2be55f"
checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8"
dependencies = [
"autocfg",
]
[[package]]
name = "miniz_oxide"
version = "0.3.7"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435"
checksum = "c60c0dfe32c10b43a144bad8fc83538c52f58302c92300ea7ec7bf7b38d5a7b9"
dependencies = [
"adler32",
"adler",
"autocfg",
]
[[package]]
name = "num-integer"
version = "0.1.43"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba"
dependencies = [
"autocfg",
"num-traits",
@ -287,9 +299,9 @@ dependencies = [
[[package]]
name = "num-iter"
version = "0.1.41"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e6b7c748f995c4c29c5f5ae0248536e04a5739927c74ec0fa564805094b9f"
checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00"
dependencies = [
"autocfg",
"num-integer",
@ -298,9 +310,9 @@ dependencies = [
[[package]]
name = "num-rational"
version = "0.3.0"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5b4d7360f362cfb50dde8143501e6940b22f644be75a4cc90b2d81968908138"
checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
dependencies = [
"autocfg",
"num-integer",
@ -309,28 +321,34 @@ dependencies = [
[[package]]
name = "num-traits"
version = "0.2.12"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
dependencies = [
"autocfg",
]
[[package]]
name = "num_cpus"
version = "1.13.0"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
checksum = "46203554f085ff89c235cd12f7075f3233af9b11ed7c9e16dfe2560d03313ce6"
dependencies = [
"hermit-abi",
"libc",
]
[[package]]
name = "oxipng"
version = "3.0.0"
name = "once_cell"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fd695858078338d73862ff3755f820eff0bf4f3304e4b52f22aba53463183a"
checksum = "b1c601810575c99596d4afc46f78a678c80105117c379eb3650cf99b8a21ce5b"
[[package]]
name = "oxipng"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5687a277f33b5fe5ee2ff5ceab4417885a428a1a938e944aa7df9d7e58c35762"
dependencies = [
"bit-vec",
"byteorder",
@ -344,44 +362,45 @@ dependencies = [
"miniz_oxide",
"rayon",
"rgb",
"rustc_version",
"zopfli",
]
[[package]]
name = "png"
version = "0.16.6"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c150bf7479fafe3dd8740dbe48cc33b2a3efb7b0fe3483aced8bbc39f6d0238d"
checksum = "46060468187c21c00ffa2a920690b29997d7fd543f5a4d400461e4a7d4fccde8"
dependencies = [
"bitflags",
"crc32fast",
"deflate",
"miniz_oxide",
"inflate",
]
[[package]]
name = "proc-macro2"
version = "1.0.18"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "beae6331a816b1f65d04c45b078fd8e6c93e8071771f41b8163255bbd8d7c8fa"
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rayon"
version = "1.3.1"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62f02856753d04e03e26929f820d0a0a337ebe71f849801eea335d464b349080"
checksum = "cfd016f0c045ad38b5251be2c9c0ab806917f82da4d36b2a327e5166adad9270"
dependencies = [
"autocfg",
"crossbeam-deque",
@ -391,12 +410,12 @@ dependencies = [
[[package]]
name = "rayon-core"
version = "1.7.1"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e92e15d89083484e11353891f1af602cc661426deb9564c298b270c726973280"
checksum = "e8c4fec834fb6e6d2dd5eece3c7b432a52f0ba887cf40e595190c4107edc08bf"
dependencies = [
"crossbeam-channel",
"crossbeam-deque",
"crossbeam-queue",
"crossbeam-utils",
"lazy_static",
"num_cpus",
@ -404,26 +423,50 @@ dependencies = [
[[package]]
name = "rgb"
version = "0.8.20"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90ef54b45ae131327a88597e2463fee4098ad6c88ba7b6af4b3987db8aad4098"
checksum = "287f3c3f8236abb92d8b7e36797f19159df4b58f0a658cc3fb6dd3004b1f3bd3"
dependencies = [
"bytemuck",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "squoosh-oxipng"
version = "0.1.0"
dependencies = [
"console_log",
"js-sys",
"crossbeam-deque",
"log",
"once_cell",
"oxipng",
"rayon",
"wasm-bindgen",
@ -431,9 +474,9 @@ dependencies = [
[[package]]
name = "syn"
version = "1.0.34"
version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "936cae2873c940d92e697597c5eee105fb570cd5689c695806f672883653349b"
checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
dependencies = [
"proc-macro2",
"quote",
@ -448,15 +491,15 @@ checksum = "a9b2228007eba4120145f785df0f6c92ea538f5a3635a612ecf4e334c8c1446d"
[[package]]
name = "unicode-xid"
version = "0.2.1"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
[[package]]
name = "wasm-bindgen"
version = "0.2.64"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a634620115e4a229108b71bde263bb4220c483b3f07f5ba514ee8d15064c4c2"
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
@ -464,9 +507,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.64"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e53963b583d18a5aa3aaae4b4c1cb535218246131ba22a71f05b518098571df"
checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
dependencies = [
"bumpalo",
"lazy_static",
@ -479,9 +522,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.64"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fcfd5ef6eec85623b4c6e844293d4516470d8f19cd72d0d12246017eb9060b8"
checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
@ -489,9 +532,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.64"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9adff9ee0e94b926ca81b57f57f86d5545cdcb1d259e21ec9bdd95b901754c75"
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
dependencies = [
"proc-macro2",
"quote",
@ -502,19 +545,9 @@ dependencies = [
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.64"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7b90ea6c632dd06fd765d44542e234d5e63d9bb917ecd64d79778a13bd79ae"
[[package]]
name = "web-sys"
version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "863539788676619aac1a23e2df3655e96b32b0e05eb72ca34ba045ad573c625d"
dependencies = [
"js-sys",
"wasm-bindgen",
]
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
[[package]]
name = "zopfli"

View File

@ -13,9 +13,12 @@ oxipng = { version = "3.0.0", default-features = false, features = ["parallel"]
wasm-bindgen = "0.2.64"
log = { version = "0.4", features = ["release_max_level_off"] }
rayon = "1.3.0"
js-sys = "0.3.37"
console_log = "0.2.0"
crossbeam-deque = "0.7.3"
once_cell = "1.3.1"
[profile.release]
lto = true
opt-level = "s"
[package.metadata.wasm-pack.profile.release]
wasm-opt = ["-O", "--no-validation"]

View File

@ -6,6 +6,7 @@ echo "============================================="
echo "Compiling wasm"
echo "============================================="
(
rm -rf pkg
CC=/opt/wasi-sdk/bin/clang RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' rustup run nightly wasm-pack build -t web -- -Z build-std=panic_abort,std
rm pkg/.gitignore
)

View File

@ -1,27 +0,0 @@
import initOxiPNG, { start_main_thread, optimise } from './pkg/squoosh_oxipng.js';
import wasmUrl from "./pkg/squoosh_oxipng_bg.wasm";
async function startMainThread() {
await initOxiPNG(fetch(wasmUrl));
start_main_thread({
length: navigator.hardwareConcurrency,
pop: () => ({
postMessage: data => {
postMessage({ type: 'spawn', data });
}
})
});
return {
optimise
};
}
const mainThread = startMainThread();
addEventListener('message', async ({ data: { id, args } }) => {
try {
let result = (await mainThread).optimise(...args);
postMessage({ ok: true, id, result });
} catch (result) {
postMessage({ ok: false, id, result });
}
});

View File

@ -1,13 +1,16 @@
/* tslint:disable */
/* eslint-disable */
/**
* @param {Array<any>} workers
* @returns {any}
*/
export function start_main_thread(workers: Array<any>): void;
export function worker_initializer(): any;
/**
* @param {number} thread
* @param {number} num
*/
export function start_worker_thread(thread: number): void;
export function start_main_thread(num: number): void;
/**
*/
export function start_worker_thread(): void;
/**
* @param {Uint8Array} data
* @param {number} level
@ -18,8 +21,9 @@ export function optimise(data: Uint8Array, level: number): Uint8Array;
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
export interface InitOutput {
readonly worker_initializer: () => number;
readonly start_main_thread: (a: number) => void;
readonly start_worker_thread: (a: number) => void;
readonly start_worker_thread: () => void;
readonly optimise: (a: number, b: number, c: number, d: number) => void;
readonly malloc: (a: number) => number;
readonly free: (a: number) => void;

View File

@ -6,22 +6,8 @@ const heap = new Array(32).fill(undefined);
heap.push(undefined, null, true, false);
function getObject(idx) { return heap[idx]; }
let heap_next = heap.length;
function dropObject(idx) {
if (idx < 36) return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
function addHeapObject(obj) {
if (heap_next === heap.length) heap.push(heap.length + 1);
const idx = heap_next;
@ -46,18 +32,39 @@ function getUint8Memory0() {
function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
}
function getObject(idx) { return heap[idx]; }
function dropObject(idx) {
if (idx < 36) return;
heap[idx] = heap_next;
heap_next = idx;
}
function takeObject(idx) {
const ret = getObject(idx);
dropObject(idx);
return ret;
}
/**
* @param {Array<any>} workers
* @returns {any}
*/
export function start_main_thread(workers) {
wasm.start_main_thread(addHeapObject(workers));
export function worker_initializer() {
var ret = wasm.worker_initializer();
return takeObject(ret);
}
/**
* @param {number} thread
* @param {number} num
*/
export function start_worker_thread(thread) {
wasm.start_worker_thread(thread);
export function start_main_thread(num) {
wasm.start_main_thread(num);
}
/**
*/
export function start_worker_thread() {
wasm.start_worker_thread();
}
let WASM_VECTOR_LEN = 0;
@ -86,14 +93,20 @@ function getArrayU8FromWasm0(ptr, len) {
* @returns {Uint8Array}
*/
export function optimise(data, level) {
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
var len0 = WASM_VECTOR_LEN;
wasm.optimise(8, ptr0, len0, level);
var r0 = getInt32Memory0()[8 / 4 + 0];
var r1 = getInt32Memory0()[8 / 4 + 1];
var v1 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v1;
try {
const retptr = wasm.__wbindgen_export_1.value - 16;
wasm.__wbindgen_export_1.value = retptr;
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
var len0 = WASM_VECTOR_LEN;
wasm.optimise(retptr, ptr0, len0, level);
var r0 = getInt32Memory0()[retptr / 4 + 0];
var r1 = getInt32Memory0()[retptr / 4 + 1];
var v1 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v1;
} finally {
wasm.__wbindgen_export_1.value += 16;
}
}
async function load(module, imports, maybe_memory) {
@ -135,40 +148,18 @@ async function init(input, maybe_memory) {
}
const imports = {};
imports.wbg = {};
imports.wbg.__wbg_length_8dacd620a01b769a = function(arg0) {
var ret = getObject(arg0).length;
return ret;
};
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbg_pop_e063afe6cb737ed3 = function(arg0) {
var ret = getObject(arg0).pop();
return addHeapObject(ret);
};
imports.wbg.__wbg_new_891c121bc64f5c10 = function() {
var ret = new Array();
return addHeapObject(ret);
};
imports.wbg.__wbindgen_module = function() {
var ret = init.__wbindgen_wasm_module;
return addHeapObject(ret);
};
imports.wbg.__wbg_push_ffe5167b83871629 = function(arg0, arg1) {
var ret = getObject(arg0).push(getObject(arg1));
return ret;
};
imports.wbg.__wbindgen_memory = function() {
var ret = wasm.__wbindgen_export_0;
return addHeapObject(ret);
};
imports.wbg.__wbindgen_number_new = function(arg0) {
var ret = arg0;
imports.wbg.__wbg_of_6510501edc06d65e = function(arg0, arg1) {
var ret = Array.of(takeObject(arg0), takeObject(arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_postMessage_5ab140e61ca2cb42 = function(arg0, arg1) {
getObject(arg0).postMessage(takeObject(arg1));
};
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
throw new Error(getStringFromWasm0(arg0, arg1));
};

View File

@ -1,7 +1,8 @@
/* tslint:disable */
/* eslint-disable */
export function worker_initializer(): number;
export function start_main_thread(a: number): void;
export function start_worker_thread(a: number): void;
export function start_worker_thread(): void;
export function optimise(a: number, b: number, c: number, d: number): void;
export function malloc(a: number): number;
export function free(a: number): void;

View File

@ -1,32 +1,23 @@
let main = new Worker("./main.js", { type: "module" });
import initOxiPNG, { worker_initializer, start_main_thread, optimise } from './pkg/oxipng.js';
import wasmUrl from "./pkg/oxipng_bg.wasm";
let workers = Array.from(
{ length: navigator.hardwareConcurrency },
() => new Worker("./worker.js", { type: "module" })
);
main.addEventListener('message', ({ data: { type, data } }) => {
if (type === 'spawn') {
workers.pop().postMessage(data);
async function startMainThread() {
let num = navigator.hardwareConcurrency;
await initOxiPNG(fetch(wasmUrl));
let workerInit = worker_initializer();
let workers = [];
for (let i = 0; i < num; i++) {
workers.push(new Promise(resolve => {
let worker = new Worker("./worker.js", { type: "module" });
worker.postMessage(workerInit);
worker.addEventListener('message', resolve, { once: true });
}));
}
});
let ID = 0;
export function optimise(...args) {
return new Promise((resolve, reject) => {
let sendId = ID++;
main.addEventListener('message', function onMessage({ data: { ok, id, result } }) {
if (id !== sendId) return;
main.removeEventListener('message', onMessage);
if (ok) {
resolve(result);
} else {
reject(result);
}
});
main.postMessage({ id: sendId, args });
});
await Promise.all(workers);
start_main_thread(num);
return {
optimise
};
}
export default startMainThread();

View File

@ -1,42 +1,44 @@
mod malloc_shim;
use js_sys::Array;
use crossbeam_deque::Injector;
use once_cell::sync::OnceCell;
use wasm_bindgen::prelude::*;
use wasm_bindgen::{JsCast, JsValue};
use wasm_bindgen::JsValue;
use oxipng::AlphaOptim;
#[wasm_bindgen]
extern "C" {
type Worker;
#[wasm_bindgen(js_namespace = Array, js_name = of)]
fn array_of_2(a: JsValue, b: JsValue) -> JsValue;
}
#[wasm_bindgen(method, js_name = postMessage)]
fn post_message(worker: &Worker, msg: JsValue);
static TASKS: OnceCell<Injector<rayon::ThreadBuilder>> = OnceCell::new();
#[wasm_bindgen]
pub fn worker_initializer() -> JsValue {
TASKS.get_or_init(Injector::new);
array_of_2(wasm_bindgen::module(), wasm_bindgen::memory())
}
#[wasm_bindgen]
pub fn start_main_thread(workers: Array) {
// console_log::init_with_level(log::Level::Trace);
pub fn start_main_thread(num: usize) {
let tasks = TASKS.get().unwrap();
rayon::ThreadPoolBuilder::new()
.num_threads(workers.length() as _)
.spawn_handler(move |thread| {
Ok(workers.pop().unchecked_into::<Worker>().post_message({
let arr = Array::new();
arr.push(&wasm_bindgen::module());
arr.push(&wasm_bindgen::memory());
arr.push(&JsValue::from(Box::into_raw(Box::new(thread)) as u32));
arr.into()
}))
})
.num_threads(num)
.spawn_handler(|thread| Ok(tasks.push(thread)))
.build_global()
.unwrap_throw()
}
#[wasm_bindgen]
pub fn start_worker_thread(thread: *mut rayon::ThreadBuilder) {
// console_log::init_with_level(log::Level::Trace);
unsafe { Box::from_raw(thread) }.run()
pub fn start_worker_thread() {
let tasks = TASKS.get().unwrap();
loop {
if let crossbeam_deque::Steal::Success(task) = tasks.steal() {
return task.run();
}
}
}
#[wasm_bindgen(catch)]

View File

@ -1,8 +1,7 @@
import initOxiPNG, { start_worker_thread } from './pkg/squoosh_oxipng.js';
addEventListener('message', async ({ data: [module, memory, threadPtr] }) => {
// console.log([module, memory, threadPtr]);
addEventListener('message', async ({ data: [module, memory] }) => {
postMessage(null);
await initOxiPNG(module, memory);
// console.log('Starting', threadPtr);
start_worker_thread(threadPtr);
start_worker_thread();
}, { once: true });

View File

@ -1,7 +1,7 @@
// @ts-ignore
import { optimise } from '../../../codecs/oxipng/spawn.js';
import optimiser from '../../../codecs/oxipng/spawn.js';
import { EncodeOptions } from './encoder-meta';
export async function compress(data: ArrayBuffer, options: EncodeOptions): Promise<ArrayBuffer> {
return (await optimise(new Uint8Array(data), options.level)).buffer;
return (await optimiser).optimise(new Uint8Array(data), options.level).buffer;
}