mirror of
https://github.com/GoogleChromeLabs/squoosh.git
synced 2025-11-16 10:39:53 +00:00
wasm-bindgen-rayon and new OMT plugin (#1007)
* WIP: wasm-bindgen-rayon and new OMT plugin * Bump package-lock * Make OMT work again * Update year * Restore accidental change * Prevent minification of `nextDefineUri` * Delay loading external deps This gives inline `define` calls a chance to define dependencies for earlier `define` calls on the same page. * Add comment
This commit is contained in:
69
codecs/oxipng/Cargo.lock
generated
69
codecs/oxipng/Cargo.lock
generated
@@ -1,5 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "0.2.3"
|
||||
@@ -232,6 +234,15 @@ dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc9f84f9b115ce7843d60706df1422a916680bfdfcbdb0447c5614ff9d7e4d78"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
@@ -350,12 +361,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
|
||||
|
||||
[[package]]
|
||||
name = "oxipng"
|
||||
version = "4.0.3"
|
||||
@@ -401,9 +406,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.24"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
|
||||
checksum = "a152013215dca273577e18d2bf00fa862b89b24169fb78c4c95aeb07992c9cec"
|
||||
dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
@@ -484,24 +489,28 @@ dependencies = [
|
||||
"pest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spmc"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02a8428da277a8e3a15271d79943e80ccc2ef254e78813a166a08d65e4c3ece5"
|
||||
|
||||
[[package]]
|
||||
name = "squoosh-oxipng"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"libdeflater",
|
||||
"log",
|
||||
"once_cell",
|
||||
"oxipng",
|
||||
"rayon",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.58"
|
||||
version = "1.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5"
|
||||
checksum = "a1e8cdbefb79a9a5a65e0db8b47b723ee907b7c7f8496c76a1770b5c310bab82"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -522,9 +531,9 @@ checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.69"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e"
|
||||
checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"wasm-bindgen-macro",
|
||||
@@ -532,9 +541,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.69"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1114f89ab1f4106e5b55e688b828c0ab0ea593a1ea7c094b141b14cbaaec2d62"
|
||||
checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"lazy_static",
|
||||
@@ -547,9 +556,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.69"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6ac8995ead1f084a8dea1e65f194d0973800c7f571f6edd70adf06ecf77084"
|
||||
checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -557,9 +566,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.69"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5a48c72f299d80557c7c62e37e7225369ecc0c963964059509fbafe917c7549"
|
||||
checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -569,7 +578,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.69"
|
||||
name = "wasm-bindgen-rayon"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e7811dd7f9398f14cc76efd356f98f03aa30419dea46aa810d71e819fc97158"
|
||||
checksum = "3069d2a42e7a7e3bfde668f84adb5fbc35701ca2b39b27a064cbd5ede4e78194"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"rayon",
|
||||
"spmc",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489"
|
||||
|
||||
@@ -14,15 +14,13 @@ crate-type = ["cdylib"]
|
||||
[dependencies]
|
||||
oxipng = { version = "4.0.1", default-features = false, features = ["libdeflater"] }
|
||||
libdeflater = { version = "0.7.1", features = ["freestanding"] }
|
||||
wasm-bindgen = "0.2.68"
|
||||
wasm-bindgen = "0.2.73"
|
||||
log = { version = "0.4.11", features = ["release_max_level_off"] }
|
||||
rayon = { version = "1.5.0", optional = true }
|
||||
once_cell = { version = "1.5.2", optional = true }
|
||||
crossbeam-channel = { version = "0.5.0", optional = true }
|
||||
wasm-bindgen-rayon = { version = "1.0", optional = true }
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
|
||||
[features]
|
||||
parallel = ["oxipng/parallel", "rayon", "crossbeam-channel", "once_cell"]
|
||||
parallel = ["oxipng/parallel", "wasm-bindgen-rayon"]
|
||||
|
||||
@@ -6,6 +6,4 @@ rm -rf pkg,{-parallel}
|
||||
export CFLAGS="${CFLAGS} -DUNALIGNED_ACCESS_IS_FAST=1"
|
||||
wasm-pack build -t web
|
||||
RUSTFLAGS='-C target-feature=+atomics,+bulk-memory' wasm-pack build -t web -d pkg-parallel -- -Z build-std=panic_abort,std --features=parallel
|
||||
# Workaround https://github.com/rustwasm/wasm-bindgen/issues/2133:
|
||||
sed -i "s|maybe_memory:|maybe_memory?:|" pkg-parallel/squoosh_oxipng.d.ts
|
||||
rm pkg{,-parallel}/.gitignore
|
||||
|
||||
98
codecs/oxipng/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js
generated
Normal file
98
codecs/oxipng/pkg-parallel/snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js
generated
Normal file
@@ -0,0 +1,98 @@
|
||||
/**
|
||||
* Copyright 2021 Google Inc. All Rights Reserved.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// Note: we use `wasm_bindgen_worker_`-prefixed message types to make sure
|
||||
// we can handle bundling into other files, which might happen to have their
|
||||
// own `postMessage`/`onmessage` communication channels.
|
||||
//
|
||||
// If we didn't take that into the account, we could send much simpler signals
|
||||
// like just `0` or whatever, but the code would be less resilient.
|
||||
|
||||
function waitForMsgType(target, type) {
|
||||
return new Promise(resolve => {
|
||||
target.addEventListener('message', function onMsg({ data }) {
|
||||
if (data == null || data.type !== type) return;
|
||||
target.removeEventListener('message', onMsg);
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
waitForMsgType(self, 'wasm_bindgen_worker_init').then(async data => {
|
||||
// # Note 1
|
||||
// Our JS should have been generated in
|
||||
// `[out-dir]/snippets/wasm-bindgen-rayon-[hash]/workerHelpers.js`,
|
||||
// resolve the main module via `../../..`.
|
||||
//
|
||||
// This might need updating if the generated structure changes on wasm-bindgen
|
||||
// side ever in the future, but works well with bundlers today. The whole
|
||||
// point of this crate, after all, is to abstract away unstable features
|
||||
// and temporary bugs so that you don't need to deal with them in your code.
|
||||
//
|
||||
// # Note 2
|
||||
// This could be a regular import, but then some bundlers complain about
|
||||
// circular deps.
|
||||
//
|
||||
// Dynamic import could be cheap if this file was inlined into the parent,
|
||||
// which would require us just using `../../..` in `new Worker` below,
|
||||
// but that doesn't work because wasm-pack unconditionally adds
|
||||
// "sideEffects":false (see below).
|
||||
//
|
||||
// OTOH, even though it can't be inlined, it should be still reasonably
|
||||
// cheap since the requested file is already in cache (it was loaded by
|
||||
// the main thread).
|
||||
const pkg = await import('../../..');
|
||||
await pkg.default(data.module, data.memory);
|
||||
postMessage({ type: 'wasm_bindgen_worker_ready' });
|
||||
pkg.wbg_rayon_start_worker(data.receiver);
|
||||
});
|
||||
|
||||
export async function startWorkers(module, memory, builder) {
|
||||
const workerInit = {
|
||||
type: 'wasm_bindgen_worker_init',
|
||||
module,
|
||||
memory,
|
||||
receiver: builder.receiver()
|
||||
};
|
||||
|
||||
try {
|
||||
await Promise.all(
|
||||
Array.from({ length: builder.numThreads() }, () => {
|
||||
// Self-spawn into a new Worker.
|
||||
//
|
||||
// TODO: while `new URL('...', import.meta.url) becomes a semi-standard
|
||||
// way to get asset URLs relative to the module across various bundlers
|
||||
// and browser, ideally we should switch to `import.meta.resolve`
|
||||
// once it becomes a standard.
|
||||
//
|
||||
// Note: we could use `../../..` as the URL here to inline workerHelpers.js
|
||||
// into the parent entry instead of creating another split point -
|
||||
// this would be preferable from optimization perspective -
|
||||
// however, Webpack then eliminates all message handler code
|
||||
// because wasm-pack produces "sideEffects":false in package.json
|
||||
// unconditionally.
|
||||
//
|
||||
// The only way to work around that is to have side effect code
|
||||
// in an entry point such as Worker file itself.
|
||||
const worker = new Worker(new URL('./workerHelpers.js', import.meta.url), {
|
||||
type: 'module'
|
||||
});
|
||||
worker.postMessage(workerInit);
|
||||
return waitForMsgType(worker, 'wasm_bindgen_worker_ready');
|
||||
})
|
||||
);
|
||||
builder.build();
|
||||
} finally {
|
||||
builder.free();
|
||||
}
|
||||
}
|
||||
35
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
generated
vendored
35
codecs/oxipng/pkg-parallel/squoosh_oxipng.d.ts
generated
vendored
@@ -7,25 +7,43 @@
|
||||
*/
|
||||
export function optimise(data: Uint8Array, level: number): Uint8Array;
|
||||
/**
|
||||
* @param {number} num
|
||||
* @returns {any}
|
||||
* @param {number} num_threads
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
export function worker_initializer(num: number): any;
|
||||
export function initThreadPool(num_threads: number): Promise<any>;
|
||||
/**
|
||||
* @param {number} receiver
|
||||
*/
|
||||
export function wbg_rayon_start_worker(receiver: number): void;
|
||||
/**
|
||||
*/
|
||||
export function start_main_thread(): void;
|
||||
export class wbg_rayon_PoolBuilder {
|
||||
free(): void;
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
numThreads(): number;
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
receiver(): number;
|
||||
/**
|
||||
*/
|
||||
export function start_worker_thread(): void;
|
||||
build(): void;
|
||||
}
|
||||
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
readonly optimise: (a: number, b: number, c: number, d: number) => void;
|
||||
readonly worker_initializer: (a: number) => number;
|
||||
readonly start_main_thread: () => void;
|
||||
readonly start_worker_thread: () => void;
|
||||
readonly __wbg_wbg_rayon_poolbuilder_free: (a: number) => void;
|
||||
readonly wbg_rayon_poolbuilder_numThreads: (a: number) => number;
|
||||
readonly wbg_rayon_poolbuilder_receiver: (a: number) => number;
|
||||
readonly wbg_rayon_poolbuilder_build: (a: number) => void;
|
||||
readonly initThreadPool: (a: number) => number;
|
||||
readonly wbg_rayon_start_worker: (a: number) => void;
|
||||
readonly __wbindgen_export_0: WebAssembly.Memory;
|
||||
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||
readonly __wbindgen_malloc: (a: number) => number;
|
||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||
readonly __wbindgen_start: () => void;
|
||||
@@ -41,4 +59,3 @@ export interface InitOutput {
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function init (module_or_path?: InitInput | Promise<InitInput>, maybe_memory?: WebAssembly.Memory): Promise<InitOutput>;
|
||||
|
||||
111
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
generated
111
codecs/oxipng/pkg-parallel/squoosh_oxipng.js
generated
@@ -1,21 +1,6 @@
|
||||
import { startWorkers } from './snippets/wasm-bindgen-rayon-3d2df09ebec17a22/src/workerHelpers.js';
|
||||
|
||||
let wasm;
|
||||
let memory;
|
||||
|
||||
const heap = new Array(32).fill(undefined);
|
||||
|
||||
heap.push(undefined, null, true, false);
|
||||
|
||||
let heap_next = heap.length;
|
||||
|
||||
function addHeapObject(obj) {
|
||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||
const idx = heap_next;
|
||||
heap_next = heap[idx];
|
||||
|
||||
heap[idx] = obj;
|
||||
return idx;
|
||||
}
|
||||
|
||||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||
|
||||
@@ -33,6 +18,21 @@ function getStringFromWasm0(ptr, len) {
|
||||
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
|
||||
}
|
||||
|
||||
const heap = new Array(32).fill(undefined);
|
||||
|
||||
heap.push(undefined, null, true, false);
|
||||
|
||||
let heap_next = heap.length;
|
||||
|
||||
function addHeapObject(obj) {
|
||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||
const idx = heap_next;
|
||||
heap_next = heap[idx];
|
||||
|
||||
heap[idx] = obj;
|
||||
return idx;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
function passArray8ToWasm0(arg, malloc) {
|
||||
@@ -60,8 +60,7 @@ function getArrayU8FromWasm0(ptr, len) {
|
||||
*/
|
||||
export function optimise(data, level) {
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_export_1.value - 16;
|
||||
wasm.__wbindgen_export_1.value = retptr;
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.optimise(retptr, ptr0, len0, level);
|
||||
@@ -71,7 +70,7 @@ export function optimise(data, level) {
|
||||
wasm.__wbindgen_free(r0, r1 * 1);
|
||||
return v1;
|
||||
} finally {
|
||||
wasm.__wbindgen_export_1.value += 16;
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,29 +88,66 @@ function takeObject(idx) {
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* @param {number} num
|
||||
* @returns {any}
|
||||
* @param {number} num_threads
|
||||
* @returns {Promise<any>}
|
||||
*/
|
||||
export function worker_initializer(num) {
|
||||
var ret = wasm.worker_initializer(num);
|
||||
export function initThreadPool(num_threads) {
|
||||
var ret = wasm.initThreadPool(num_threads);
|
||||
return takeObject(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} receiver
|
||||
*/
|
||||
export function start_main_thread() {
|
||||
wasm.start_main_thread();
|
||||
export function wbg_rayon_start_worker(receiver) {
|
||||
wasm.wbg_rayon_start_worker(receiver);
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
export function start_worker_thread() {
|
||||
wasm.start_worker_thread();
|
||||
export class wbg_rayon_PoolBuilder {
|
||||
|
||||
static __wrap(ptr) {
|
||||
const obj = Object.create(wbg_rayon_PoolBuilder.prototype);
|
||||
obj.ptr = ptr;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
__destroy_into_raw() {
|
||||
const ptr = this.ptr;
|
||||
this.ptr = 0;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
free() {
|
||||
const ptr = this.__destroy_into_raw();
|
||||
wasm.__wbg_wbg_rayon_poolbuilder_free(ptr);
|
||||
}
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
numThreads() {
|
||||
var ret = wasm.wbg_rayon_poolbuilder_numThreads(this.ptr);
|
||||
return ret >>> 0;
|
||||
}
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
receiver() {
|
||||
var ret = wasm.wbg_rayon_poolbuilder_receiver(this.ptr);
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
*/
|
||||
build() {
|
||||
wasm.wbg_rayon_poolbuilder_build(this.ptr);
|
||||
}
|
||||
}
|
||||
|
||||
async function load(module, imports, maybe_memory) {
|
||||
async function load(module, imports) {
|
||||
if (typeof Response === 'function' && module instanceof Response) {
|
||||
memory = imports.wbg.memory = new WebAssembly.Memory({initial:17,maximum:16384,shared:true});
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
try {
|
||||
return await WebAssembly.instantiateStreaming(module, imports);
|
||||
@@ -130,7 +166,6 @@ async function load(module, imports, maybe_memory) {
|
||||
return await WebAssembly.instantiate(bytes, imports);
|
||||
|
||||
} else {
|
||||
memory = imports.wbg.memory = maybe_memory;
|
||||
const instance = await WebAssembly.instantiate(module, imports);
|
||||
|
||||
if (instance instanceof WebAssembly.Instance) {
|
||||
@@ -144,10 +179,13 @@ async function load(module, imports, maybe_memory) {
|
||||
|
||||
async function init(input, maybe_memory) {
|
||||
if (typeof input === 'undefined') {
|
||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
||||
input = new URL('squoosh_oxipng_bg.wasm', import.meta.url);
|
||||
}
|
||||
const imports = {};
|
||||
imports.wbg = {};
|
||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
imports.wbg.__wbindgen_module = function() {
|
||||
var ret = init.__wbindgen_wasm_module;
|
||||
return addHeapObject(ret);
|
||||
@@ -156,19 +194,18 @@ async function init(input, maybe_memory) {
|
||||
var ret = wasm.__wbindgen_export_0;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_of_6510501edc06d65e = function(arg0, arg1) {
|
||||
var ret = Array.of(takeObject(arg0), takeObject(arg1));
|
||||
imports.wbg.__wbg_startWorkers_914655bb4d5bb5e1 = function(arg0, arg1, arg2) {
|
||||
var ret = startWorkers(takeObject(arg0), takeObject(arg1), wbg_rayon_PoolBuilder.__wrap(arg2));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
|
||||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
const { instance, module } = await load(await input, imports, maybe_memory);
|
||||
imports.wbg.memory = maybe_memory || new WebAssembly.Memory({initial:17,maximum:16384,shared:true});
|
||||
|
||||
const { instance, module } = await load(await input, imports);
|
||||
|
||||
wasm = instance.exports;
|
||||
init.__wbindgen_wasm_module = module;
|
||||
|
||||
Binary file not shown.
10
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
10
codecs/oxipng/pkg-parallel/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
@@ -1,10 +1,14 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
export function optimise(a: number, b: number, c: number, d: number): void;
|
||||
export function worker_initializer(a: number): number;
|
||||
export function start_main_thread(): void;
|
||||
export function start_worker_thread(): void;
|
||||
export function __wbg_wbg_rayon_poolbuilder_free(a: number): void;
|
||||
export function wbg_rayon_poolbuilder_numThreads(a: number): number;
|
||||
export function wbg_rayon_poolbuilder_receiver(a: number): number;
|
||||
export function wbg_rayon_poolbuilder_build(a: number): void;
|
||||
export function initThreadPool(a: number): number;
|
||||
export function wbg_rayon_start_worker(a: number): void;
|
||||
export const __wbindgen_export_0: WebAssembly.Memory;
|
||||
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
||||
export function __wbindgen_malloc(a: number): number;
|
||||
export function __wbindgen_free(a: number, b: number): void;
|
||||
export function __wbindgen_start(): void;
|
||||
|
||||
2
codecs/oxipng/pkg/squoosh_oxipng.d.ts
generated
vendored
2
codecs/oxipng/pkg/squoosh_oxipng.d.ts
generated
vendored
@@ -12,6 +12,7 @@ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembl
|
||||
export interface InitOutput {
|
||||
readonly memory: WebAssembly.Memory;
|
||||
readonly optimise: (a: number, b: number, c: number, d: number) => void;
|
||||
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||
readonly __wbindgen_malloc: (a: number) => number;
|
||||
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||
}
|
||||
@@ -25,4 +26,3 @@ export interface InitOutput {
|
||||
* @returns {Promise<InitOutput>}
|
||||
*/
|
||||
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
||||
|
||||
11
codecs/oxipng/pkg/squoosh_oxipng.js
generated
11
codecs/oxipng/pkg/squoosh_oxipng.js
generated
@@ -44,8 +44,7 @@ function getArrayU8FromWasm0(ptr, len) {
|
||||
*/
|
||||
export function optimise(data, level) {
|
||||
try {
|
||||
const retptr = wasm.__wbindgen_export_0.value - 16;
|
||||
wasm.__wbindgen_export_0.value = retptr;
|
||||
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
||||
var ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
wasm.optimise(retptr, ptr0, len0, level);
|
||||
@@ -55,13 +54,12 @@ export function optimise(data, level) {
|
||||
wasm.__wbindgen_free(r0, r1 * 1);
|
||||
return v1;
|
||||
} finally {
|
||||
wasm.__wbindgen_export_0.value += 16;
|
||||
wasm.__wbindgen_add_to_stack_pointer(16);
|
||||
}
|
||||
}
|
||||
|
||||
async function load(module, imports) {
|
||||
if (typeof Response === 'function' && module instanceof Response) {
|
||||
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
try {
|
||||
return await WebAssembly.instantiateStreaming(module, imports);
|
||||
@@ -80,7 +78,6 @@ async function load(module, imports) {
|
||||
return await WebAssembly.instantiate(bytes, imports);
|
||||
|
||||
} else {
|
||||
|
||||
const instance = await WebAssembly.instantiate(module, imports);
|
||||
|
||||
if (instance instanceof WebAssembly.Instance) {
|
||||
@@ -94,7 +91,7 @@ async function load(module, imports) {
|
||||
|
||||
async function init(input) {
|
||||
if (typeof input === 'undefined') {
|
||||
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
|
||||
input = new URL('squoosh_oxipng_bg.wasm', import.meta.url);
|
||||
}
|
||||
const imports = {};
|
||||
imports.wbg = {};
|
||||
@@ -106,6 +103,8 @@ async function init(input) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const { instance, module } = await load(await input, imports);
|
||||
|
||||
wasm = instance.exports;
|
||||
|
||||
Binary file not shown.
1
codecs/oxipng/pkg/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
1
codecs/oxipng/pkg/squoosh_oxipng_bg.wasm.d.ts
generated
vendored
@@ -2,5 +2,6 @@
|
||||
/* eslint-disable */
|
||||
export const memory: WebAssembly.Memory;
|
||||
export function optimise(a: number, b: number, c: number, d: number): void;
|
||||
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
||||
export function __wbindgen_malloc(a: number): number;
|
||||
export function __wbindgen_free(a: number, b: number): void;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#[cfg(feature = "parallel")]
|
||||
pub use wasm_bindgen_rayon::init_thread_pool;
|
||||
|
||||
use oxipng::AlphaOptim;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[cfg(feature = "parallel")]
|
||||
pub mod parallel;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn optimise(data: &[u8], level: u8) -> Vec<u8> {
|
||||
let mut options = oxipng::Options::from_preset(level);
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
use crossbeam_channel::{bounded, Receiver, Sender};
|
||||
use once_cell::sync::OnceCell;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsValue;
|
||||
|
||||
#[wasm_bindgen]
|
||||
extern "C" {
|
||||
#[wasm_bindgen(js_namespace = Array, js_name = of)]
|
||||
fn array_of_2(a: JsValue, b: JsValue) -> JsValue;
|
||||
}
|
||||
|
||||
// This is one of the parts that work around Chromium incorrectly implementing postMessage:
|
||||
// https://bugs.chromium.org/p/chromium/issues/detail?id=1075645
|
||||
//
|
||||
// rayon::ThreadPoolBuilder (used below) executes spawn handler to populate the worker pool,
|
||||
// and then blocks the current thread until each worker unblocks its (opaque) lock.
|
||||
//
|
||||
// Normally, we could use postMessage directly inside the spawn handler to
|
||||
// post module + memory + threadPtr to each worker, and the block the current thread.
|
||||
//
|
||||
// However, that bug means that postMessage is currently delayed until the next event loop,
|
||||
// which will never spin since we block the current thread, and so the other workers will
|
||||
// never be able to unblock us.
|
||||
//
|
||||
// To work around this problem, we:
|
||||
// 1) Expose `worker_initializer` that returns module + memory pair (without threadPtr)
|
||||
// that workers can be initialised with to become native threads.
|
||||
// JavaScript can postMessage this pair in advance, and asynchronously wait for workers
|
||||
// to acknowledge the receipt.
|
||||
// 2) Create a global communication channel on the Rust side using crossbeam.
|
||||
// It will be used to send threadPtr to the pre-initialised workers
|
||||
// instead of postMessage.
|
||||
// 3) Provide a separate `start_main_thread` that expects all workers to be ready,
|
||||
// and just uses the provided channel to send `threadPtr`s using the
|
||||
// shared memory and blocks the current thread until they're all grabbed.
|
||||
// 4) Provide a `worker_initializer` that is expected to be invoked from various workers,
|
||||
// reads one `threadPtr` from the shared channel and starts running it.
|
||||
static CHANNEL: OnceCell<(Sender<rayon::ThreadBuilder>, Receiver<rayon::ThreadBuilder>)> =
|
||||
OnceCell::new();
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn worker_initializer(num: usize) -> JsValue {
|
||||
CHANNEL.get_or_init(|| bounded(num));
|
||||
array_of_2(wasm_bindgen::module(), wasm_bindgen::memory())
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn start_main_thread() {
|
||||
let (sender, _) = CHANNEL.get().unwrap();
|
||||
|
||||
rayon::ThreadPoolBuilder::new()
|
||||
.num_threads(sender.capacity().unwrap())
|
||||
.spawn_handler(|thread| Ok(sender.send(thread).unwrap_throw()))
|
||||
.build_global()
|
||||
.unwrap_throw()
|
||||
}
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn start_worker_thread() {
|
||||
let (_, receiver) = CHANNEL.get().unwrap();
|
||||
receiver.recv().unwrap_throw().run()
|
||||
}
|
||||
Reference in New Issue
Block a user