mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
This reverts commit b2a4a05683
.
This has been causing issues when rolling to flutter/packages repo. See
https://github.com/flutter/flutter/issues/165347.
This commit is contained in:
parent
b836fb2682
commit
1d954f4e96
@ -277,9 +277,9 @@ config("compiler") {
|
||||
}
|
||||
|
||||
if (is_wasm) {
|
||||
if (wasm_use_workers) {
|
||||
cflags += [ "-sWASM_WORKERS=1" ]
|
||||
ldflags += [ "-sWASM_WORKERS=1" ]
|
||||
if (wasm_use_pthreads) {
|
||||
cflags += [ "-pthread" ]
|
||||
ldflags += [ "-pthread" ]
|
||||
} if (wasm_shared_memory) {
|
||||
cflags += [ "-sSHARED_MEMORY=1" ]
|
||||
ldflags += [ "-sSHARED_MEMORY=1" ]
|
||||
@ -396,12 +396,12 @@ config("compiler") {
|
||||
# to say that it does. Define them here instead.
|
||||
defines += [ "HAVE_SYS_UIO_H" ]
|
||||
|
||||
# When Android requires new flags consider also editing the flags in
|
||||
# the following locations.
|
||||
# When Android requires new flags consider also editing the flags in
|
||||
# the following locations.
|
||||
# Framework plugin_ffi template: packages/flutter_tools/templates/plugin_ffi/src.tmpl/CMakeLists.txt.tmpl
|
||||
# Example PR: https://github.com/flutter/flutter/pull/155508
|
||||
# Dart Lang JNI package: pkgs/jni/src/CMakeLists.txt
|
||||
# Example PR: https://github.com/dart-lang/native/pull/1615
|
||||
# Dart Lang JNI package: pkgs/jni/src/CMakeLists.txt
|
||||
# Example PR: https://github.com/dart-lang/native/pull/1615
|
||||
ldflags += [
|
||||
"-Wl,--no-undefined",
|
||||
"-Wl,--exclude-libs,ALL",
|
||||
|
@ -11,7 +11,7 @@ declare_args() {
|
||||
# The location of an activated embedded emsdk.
|
||||
emsdk_dir = rebase_path("//flutter/prebuilts/emsdk")
|
||||
|
||||
wasm_use_workers = false
|
||||
wasm_use_pthreads = false
|
||||
wasm_shared_memory = false
|
||||
wasm_use_dwarf = false
|
||||
}
|
||||
|
@ -42734,6 +42734,8 @@ ORIGIN: ../../../flutter/lib/web_ui/skwasm/filters.cpp + ../../../flutter/LICENS
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/fonts.cpp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/helpers.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/image.cpp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/library_skwasm_multi_threaded.js + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/library_skwasm_single_threaded.js + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/library_skwasm_support.js + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/paint.cpp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/path.cpp + ../../../flutter/LICENSE
|
||||
@ -42743,6 +42745,8 @@ ORIGIN: ../../../flutter/lib/web_ui/skwasm/skwasm_support.h + ../../../flutter/L
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/string.cpp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/surface.cpp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/surface.h + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/surface_mt.cpp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/surface_st.cpp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/line_metrics.cpp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/paragraph.cpp + ../../../flutter/LICENSE
|
||||
ORIGIN: ../../../flutter/lib/web_ui/skwasm/text/paragraph_builder.cpp + ../../../flutter/LICENSE
|
||||
@ -45705,6 +45709,8 @@ FILE: ../../../flutter/lib/web_ui/skwasm/filters.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/fonts.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/helpers.h
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/image.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/library_skwasm_multi_threaded.js
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/library_skwasm_single_threaded.js
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/library_skwasm_support.js
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/paint.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/path.cpp
|
||||
@ -45714,6 +45720,8 @@ FILE: ../../../flutter/lib/web_ui/skwasm/skwasm_support.h
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/string.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/surface.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/surface.h
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/surface_mt.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/surface_st.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/text/line_metrics.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/text/paragraph.cpp
|
||||
FILE: ../../../flutter/lib/web_ui/skwasm/text/paragraph_builder.cpp
|
||||
|
@ -76,6 +76,7 @@ class CopyArtifactsStep implements PipelineStep {
|
||||
final String canvaskitSourceDirectory;
|
||||
final String canvaskitChromiumSourceDirectory;
|
||||
final String skwasmSourceDirectory;
|
||||
final String skwasmStSourceDirectory;
|
||||
switch (source) {
|
||||
case LocalArtifactSource(:final mode):
|
||||
final buildDirectory = getBuildDirectoryForRuntimeMode(mode).path;
|
||||
@ -83,6 +84,7 @@ class CopyArtifactsStep implements PipelineStep {
|
||||
canvaskitSourceDirectory = pathlib.join(buildDirectory, 'canvaskit');
|
||||
canvaskitChromiumSourceDirectory = pathlib.join(buildDirectory, 'canvaskit_chromium');
|
||||
skwasmSourceDirectory = pathlib.join(buildDirectory, 'skwasm');
|
||||
skwasmStSourceDirectory = pathlib.join(buildDirectory, 'skwasm_st');
|
||||
|
||||
case GcsArtifactSource(:final realm):
|
||||
final artifactsDirectory = (await _downloadArtifacts(realm)).path;
|
||||
@ -94,6 +96,7 @@ class CopyArtifactsStep implements PipelineStep {
|
||||
'chromium',
|
||||
);
|
||||
skwasmSourceDirectory = pathlib.join(artifactsDirectory, 'canvaskit');
|
||||
skwasmStSourceDirectory = pathlib.join(artifactsDirectory, 'canvaskit');
|
||||
}
|
||||
|
||||
await environment.webTestsArtifactsDir.create(recursive: true);
|
||||
@ -113,6 +116,7 @@ class CopyArtifactsStep implements PipelineStep {
|
||||
if (artifactDeps.skwasm) {
|
||||
copied.add('Skwasm');
|
||||
await copyWasmLibrary('skwasm', skwasmSourceDirectory, 'canvaskit');
|
||||
await copyWasmLibrary('skwasm_st', skwasmStSourceDirectory, 'canvaskit');
|
||||
}
|
||||
print('Copied artifacts: ${copied.join(', ')}');
|
||||
}
|
||||
|
@ -6,64 +6,24 @@ import { createWasmInstantiator } from "./instantiate_wasm.js";
|
||||
import { resolveUrlWithSegments } from "./utils.js";
|
||||
|
||||
export const loadSkwasm = async (deps, config, browserEnvironment, baseUrl) => {
|
||||
const rawSkwasmUrl = resolveUrlWithSegments(baseUrl, 'skwasm.js')
|
||||
const fileStem = (browserEnvironment.crossOriginIsolated && !config.forceSingleThreadedSkwasm) ? "skwasm" : "skwasm_st";
|
||||
const rawSkwasmUrl = resolveUrlWithSegments(baseUrl, `${fileStem}.js`)
|
||||
let skwasmUrl = rawSkwasmUrl;
|
||||
if (deps.flutterTT.policy) {
|
||||
skwasmUrl = deps.flutterTT.policy.createScriptURL(skwasmUrl);
|
||||
}
|
||||
const wasmInstantiator = createWasmInstantiator(resolveUrlWithSegments(baseUrl, 'skwasm.wasm'));
|
||||
const wasmInstantiator = createWasmInstantiator(resolveUrlWithSegments(baseUrl, `${fileStem}.wasm`));
|
||||
const skwasm = await import(skwasmUrl);
|
||||
return await skwasm.default({
|
||||
skwasmSingleThreaded: !browserEnvironment.crossOriginIsolated || config.forceSingleThreadedSkwasm,
|
||||
instantiateWasm: wasmInstantiator,
|
||||
locateFile: (filename, scriptDirectory) => {
|
||||
// The wasm workers API has a separate .ww.js file that bootstraps the
|
||||
// web worker. However, it turns out this worker bootstrapper doesn't
|
||||
// actually work with ES6 modules, which we have enabled. So we instead
|
||||
// pass our own bootstrapper that loads skwasm.js as an ES6 module, and
|
||||
// queues/flushes pending messages that were received during the
|
||||
// asynchronous load.
|
||||
if (filename.endsWith('.ww.js')) {
|
||||
const url = resolveUrlWithSegments(baseUrl, filename);
|
||||
return URL.createObjectURL(new Blob(
|
||||
[`
|
||||
"use strict";
|
||||
|
||||
let eventListener;
|
||||
eventListener = (message) => {
|
||||
const pendingMessages = [];
|
||||
const data = message.data;
|
||||
data["instantiateWasm"] = (info,receiveInstance) => {
|
||||
const instance = new WebAssembly.Instance(data["wasm"], info);
|
||||
return receiveInstance(instance, data["wasm"])
|
||||
};
|
||||
import(data.js).then(async (skwasm) => {
|
||||
await skwasm.default(data);
|
||||
|
||||
removeEventListener("message", eventListener);
|
||||
for (const message of pendingMessages) {
|
||||
dispatchEvent(message);
|
||||
}
|
||||
});
|
||||
console.log("removing initial listener");
|
||||
removeEventListener("message", eventListener);
|
||||
eventListener = (message) => {
|
||||
|
||||
pendingMessages.push(message);
|
||||
};
|
||||
|
||||
addEventListener("message", eventListener);
|
||||
};
|
||||
addEventListener("message", eventListener);
|
||||
`
|
||||
],
|
||||
{ 'type': 'application/javascript' }));
|
||||
}
|
||||
return url;
|
||||
},
|
||||
// Because of the above workaround, the worker is just a blob and
|
||||
// can't locate the main script using a relative path to itself,
|
||||
// so we pass the main script location in.
|
||||
mainScriptUrlOrBlob: rawSkwasmUrl,
|
||||
// When hosted via a CDN or some other url that is not the same
|
||||
// origin as the main script of the page, we will fail to create
|
||||
// a web worker with the bootstrapping script. This workaround will
|
||||
// make sure that the worker JS can be loaded regardless of where
|
||||
// it is hosted.
|
||||
mainScriptUrlOrBlob: new Blob(
|
||||
[`import '${skwasmUrl}'`],
|
||||
{ 'type': 'application/javascript' },
|
||||
),
|
||||
});
|
||||
}
|
||||
|
@ -4,69 +4,96 @@
|
||||
|
||||
import("//build/toolchain/wasm.gni")
|
||||
|
||||
wasm_lib("skwasm") {
|
||||
public_configs = [ "//flutter:config" ]
|
||||
template("skwasm_variant") {
|
||||
wasm_lib(target_name) {
|
||||
public_configs = [ "//flutter:config" ]
|
||||
|
||||
sources = [
|
||||
"canvas.cpp",
|
||||
"contour_measure.cpp",
|
||||
"data.cpp",
|
||||
"export.h",
|
||||
"filters.cpp",
|
||||
"fonts.cpp",
|
||||
"helpers.h",
|
||||
"image.cpp",
|
||||
"paint.cpp",
|
||||
"path.cpp",
|
||||
"picture.cpp",
|
||||
"shaders.cpp",
|
||||
"skwasm_support.h",
|
||||
"string.cpp",
|
||||
"surface.cpp",
|
||||
"text/line_metrics.cpp",
|
||||
"text/paragraph.cpp",
|
||||
"text/paragraph_builder.cpp",
|
||||
"text/paragraph_style.cpp",
|
||||
"text/strut_style.cpp",
|
||||
"text/text_style.cpp",
|
||||
"vertices.cpp",
|
||||
"wrappers.h",
|
||||
]
|
||||
|
||||
cflags = [ "-mreference-types" ]
|
||||
|
||||
ldflags = [
|
||||
"-std=c++20",
|
||||
"-lGL",
|
||||
"-sUSE_WEBGL2=1",
|
||||
"-sMAX_WEBGL_VERSION=2",
|
||||
"-sOFFSCREENCANVAS_SUPPORT",
|
||||
"-sALLOW_MEMORY_GROWTH",
|
||||
"-sALLOW_TABLE_GROWTH",
|
||||
"-lexports.js",
|
||||
"-sEXPORTED_FUNCTIONS=[stackAlloc]",
|
||||
"-sEXPORTED_RUNTIME_METHODS=[addFunction,wasmExports,wasmMemory,stackAlloc]",
|
||||
"-sINCOMING_MODULE_JS_API=[instantiateWasm,locateFile,noExitRuntime,mainScriptUrlOrBlob,wasmMemory,wasm,skwasmSingleThreaded]",
|
||||
"-sUSE_ES6_IMPORT_META=0",
|
||||
"--js-library",
|
||||
rebase_path("library_skwasm_support.js"),
|
||||
]
|
||||
|
||||
inputs = [ rebase_path("library_skwasm_support.js") ]
|
||||
|
||||
if (is_debug) {
|
||||
ldflags += [
|
||||
"-sASSERTIONS=1",
|
||||
"-sGL_ASSERTIONS=1",
|
||||
"-sSTACK_OVERFLOW_CHECK=2",
|
||||
sources = [
|
||||
"canvas.cpp",
|
||||
"contour_measure.cpp",
|
||||
"data.cpp",
|
||||
"export.h",
|
||||
"filters.cpp",
|
||||
"fonts.cpp",
|
||||
"helpers.h",
|
||||
"image.cpp",
|
||||
"paint.cpp",
|
||||
"path.cpp",
|
||||
"picture.cpp",
|
||||
"shaders.cpp",
|
||||
"skwasm_support.h",
|
||||
"string.cpp",
|
||||
"surface.cpp",
|
||||
"text/line_metrics.cpp",
|
||||
"text/paragraph.cpp",
|
||||
"text/paragraph_builder.cpp",
|
||||
"text/paragraph_style.cpp",
|
||||
"text/strut_style.cpp",
|
||||
"text/text_style.cpp",
|
||||
"vertices.cpp",
|
||||
"wrappers.h",
|
||||
]
|
||||
} else {
|
||||
ldflags += [ "--closure=1" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
"//flutter/skia",
|
||||
"//flutter/skia/modules/skparagraph",
|
||||
"//flutter/skia/modules/skunicode",
|
||||
]
|
||||
cflags = [ "-mreference-types" ]
|
||||
|
||||
ldflags = [
|
||||
"-std=c++20",
|
||||
"-lGL",
|
||||
"-sUSE_WEBGL2=1",
|
||||
"-sMAX_WEBGL_VERSION=2",
|
||||
"-sOFFSCREENCANVAS_SUPPORT",
|
||||
"-sALLOW_MEMORY_GROWTH",
|
||||
"-sALLOW_TABLE_GROWTH",
|
||||
"-lexports.js",
|
||||
"-sEXPORTED_FUNCTIONS=[stackAlloc]",
|
||||
"-sEXPORTED_RUNTIME_METHODS=[addFunction,wasmExports,wasmMemory,stackAlloc]",
|
||||
"-sINCOMING_MODULE_JS_API=[instantiateWasm,noExitRuntime,mainScriptUrlOrBlob]",
|
||||
"-sUSE_ES6_IMPORT_META=0",
|
||||
"--js-library",
|
||||
rebase_path("library_skwasm_support.js"),
|
||||
]
|
||||
|
||||
inputs = [ rebase_path("library_skwasm_support.js") ]
|
||||
|
||||
if (invoker.multi_threaded) {
|
||||
sources += [ "surface_mt.cpp" ]
|
||||
ldflags += [
|
||||
"-sPTHREAD_POOL_SIZE=1",
|
||||
"-Wno-pthreads-mem-growth",
|
||||
"--js-library",
|
||||
rebase_path("library_skwasm_multi_threaded.js"),
|
||||
]
|
||||
inputs += [ rebase_path("library_skwasm_multi_threaded.js") ]
|
||||
} else {
|
||||
sources += [ "surface_st.cpp" ]
|
||||
ldflags += [
|
||||
"--js-library",
|
||||
rebase_path("library_skwasm_single_threaded.js"),
|
||||
]
|
||||
inputs += [ rebase_path("library_skwasm_single_threaded.js") ]
|
||||
}
|
||||
|
||||
if (is_debug) {
|
||||
ldflags += [
|
||||
"-sASSERTIONS=1",
|
||||
"-sGL_ASSERTIONS=1",
|
||||
]
|
||||
} else {
|
||||
ldflags += [ "--closure=1" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
"//flutter/skia",
|
||||
"//flutter/skia/modules/skparagraph",
|
||||
"//flutter/skia/modules/skunicode",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
skwasm_variant("skwasm") {
|
||||
multi_threaded = true
|
||||
}
|
||||
|
||||
skwasm_variant("skwasm_st") {
|
||||
multi_threaded = false
|
||||
}
|
||||
|
@ -0,0 +1,57 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// This file adds JavaScript APIs that are accessible to the C++ layer.
|
||||
// See: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#implement-a-c-api-in-javascript
|
||||
|
||||
mergeInto(LibraryManager.library, {
|
||||
$skwasm_threading_setup__postset: 'skwasm_threading_setup();',
|
||||
$skwasm_threading_setup: function() {
|
||||
// This value represents the difference between the time origin of the main
|
||||
// thread and whichever web worker this code is running on. This is so that
|
||||
// when we report frame timings, that they are in the same time domain
|
||||
// regardless of whether they are captured on the main thread or the web
|
||||
// worker.
|
||||
let timeOriginDelta = 0;
|
||||
skwasm_registerMessageListener = function(threadId, listener) {
|
||||
const eventListener = function({data}) {
|
||||
const skwasmMessage = data.skwasmMessage;
|
||||
if (!skwasmMessage) {
|
||||
return;
|
||||
}
|
||||
if (skwasmMessage == 'syncTimeOrigin') {
|
||||
timeOriginDelta = performance.timeOrigin - data.timeOrigin;
|
||||
return;
|
||||
}
|
||||
listener(data);
|
||||
};
|
||||
if (!threadId) {
|
||||
addEventListener("message", eventListener);
|
||||
} else {
|
||||
PThread.pthreads[threadId].addEventListener("message", eventListener);
|
||||
PThread.pthreads[threadId].postMessage({
|
||||
skwasmMessage: 'syncTimeOrigin',
|
||||
timeOrigin: performance.timeOrigin,
|
||||
});
|
||||
}
|
||||
};
|
||||
skwasm_getCurrentTimestamp = function() {
|
||||
return performance.now() + timeOriginDelta;
|
||||
};
|
||||
skwasm_postMessage = function(message, transfers, threadId) {
|
||||
if (threadId) {
|
||||
PThread.pthreads[threadId].postMessage(message, transfers);
|
||||
} else {
|
||||
postMessage(message, transfers);
|
||||
}
|
||||
};
|
||||
},
|
||||
$skwasm_threading_setup__deps: ['$skwasm_registerMessageListener', '$skwasm_getCurrentTimestamp', '$skwasm_postMessage'],
|
||||
$skwasm_registerMessageListener: function() {},
|
||||
$skwasm_registerMessageListener__deps: ['$skwasm_threading_setup'],
|
||||
$skwasm_getCurrentTimestamp: function () {},
|
||||
$skwasm_getCurrentTimestamp__deps: ['$skwasm_threading_setup'],
|
||||
$skwasm_postMessage: function () {},
|
||||
$skwasm_postMessage__deps: ['$skwasm_threading_setup'],
|
||||
});
|
@ -0,0 +1,31 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// This file adds JavaScript APIs that are accessible to the C++ layer.
|
||||
// See: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#implement-a-c-api-in-javascript
|
||||
|
||||
mergeInto(LibraryManager.library, {
|
||||
$skwasm_threading_setup__postset: 'skwasm_threading_setup();',
|
||||
$skwasm_threading_setup: function() {
|
||||
let messageListener;
|
||||
skwasm_registerMessageListener = function(threadId, listener) {
|
||||
messageListener = listener;
|
||||
};
|
||||
skwasm_getCurrentTimestamp = function() {
|
||||
return performance.now();
|
||||
};
|
||||
skwasm_postMessage = function(message, transfers, threadId) {
|
||||
queueMicrotask(() => {
|
||||
messageListener(message);
|
||||
})
|
||||
};
|
||||
},
|
||||
$skwasm_threading_setup__deps: ['$skwasm_registerMessageListener', '$skwasm_getCurrentTimestamp', '$skwasm_postMessage'],
|
||||
$skwasm_registerMessageListener: function() {},
|
||||
$skwasm_registerMessageListener__deps: ['$skwasm_threading_setup'],
|
||||
$skwasm_getCurrentTimestamp: function () {},
|
||||
$skwasm_getCurrentTimestamp__deps: ['$skwasm_threading_setup'],
|
||||
$skwasm_postMessage: function () {},
|
||||
$skwasm_postMessage__deps: ['$skwasm_threading_setup'],
|
||||
});
|
@ -8,51 +8,9 @@
|
||||
mergeInto(LibraryManager.library, {
|
||||
$skwasm_support_setup__postset: 'skwasm_support_setup();',
|
||||
$skwasm_support_setup: function() {
|
||||
// This value represents the difference between the time origin of the main
|
||||
// thread and whichever web worker this code is running on. This is so that
|
||||
// when we report frame timings, that they are in the same time domain
|
||||
// regardless of whether they are captured on the main thread or the web
|
||||
// worker.
|
||||
let timeOriginDelta = 0;
|
||||
skwasm_registerMessageListener = function(threadId, listener) {
|
||||
const eventListener = function({data}) {
|
||||
const skwasmMessage = data.skwasmMessage;
|
||||
if (!skwasmMessage) {
|
||||
return;
|
||||
}
|
||||
if (skwasmMessage == 'syncTimeOrigin') {
|
||||
timeOriginDelta = performance.timeOrigin - data.timeOrigin;
|
||||
return;
|
||||
}
|
||||
listener(data);
|
||||
};
|
||||
if (!threadId) {
|
||||
addEventListener("message", eventListener);
|
||||
} else {
|
||||
_wasmWorkers[threadId].addEventListener("message", eventListener);
|
||||
_wasmWorkers[threadId].postMessage({
|
||||
skwasmMessage: 'syncTimeOrigin',
|
||||
timeOrigin: performance.timeOrigin,
|
||||
});
|
||||
}
|
||||
};
|
||||
skwasm_getCurrentTimestamp = function() {
|
||||
return performance.now() + timeOriginDelta;
|
||||
};
|
||||
skwasm_postMessage = function(message, transfers, threadId) {
|
||||
if (threadId) {
|
||||
_wasmWorkers[threadId].postMessage(message, transfers);
|
||||
} else {
|
||||
postMessage(message, transfers);
|
||||
}
|
||||
};
|
||||
|
||||
const handleToCanvasMap = new Map();
|
||||
const associatedObjectsMap = new Map();
|
||||
|
||||
_skwasm_isSingleThreaded = function() {
|
||||
return Module["skwasmSingleThreaded"];
|
||||
};
|
||||
_skwasm_setAssociatedObjectOnThread = function(threadId, pointer, object) {
|
||||
skwasm_postMessage({
|
||||
skwasmMessage: 'setAssociatedObject',
|
||||
@ -217,22 +175,15 @@ mergeInto(LibraryManager.library, {
|
||||
});
|
||||
}
|
||||
},
|
||||
$skwasm_registerMessageListener: function() {},
|
||||
$skwasm_registerMessageListener__deps: ['$skwasm_support_setup'],
|
||||
$skwasm_getCurrentTimestamp: function () {},
|
||||
$skwasm_getCurrentTimestamp__deps: ['$skwasm_support_setup'],
|
||||
$skwasm_postMessage: function () {},
|
||||
$skwasm_postMessage__deps: ['$skwasm_support_setup'],
|
||||
skwasm_isSingleThreaded: function() {},
|
||||
skwasm_isSingleThreaded__deps: ['$skwasm_support_setup'],
|
||||
$skwasm_support_setup__deps: [ '$skwasm_threading_setup'],
|
||||
skwasm_setAssociatedObjectOnThread: function () {},
|
||||
skwasm_setAssociatedObjectOnThread__deps: ['$skwasm_support_setup', '$skwasm_postMessage'],
|
||||
skwasm_setAssociatedObjectOnThread__deps: ['$skwasm_support_setup'],
|
||||
skwasm_getAssociatedObject: function () {},
|
||||
skwasm_getAssociatedObject__deps: ['$skwasm_support_setup'],
|
||||
skwasm_disposeAssociatedObjectOnThread: function () {},
|
||||
skwasm_disposeAssociatedObjectOnThread__deps: ['$skwasm_support_setup'],
|
||||
skwasm_connectThread: function() {},
|
||||
skwasm_connectThread__deps: ['$skwasm_support_setup', '$skwasm_registerMessageListener', '$skwasm_getCurrentTimestamp'],
|
||||
skwasm_connectThread__deps: ['$skwasm_support_setup'],
|
||||
skwasm_dispatchRenderPictures: function() {},
|
||||
skwasm_dispatchRenderPictures__deps: ['$skwasm_support_setup'],
|
||||
skwasm_createOffscreenCanvas: function () {},
|
||||
|
@ -13,7 +13,6 @@
|
||||
using SkwasmObject = __externref_t;
|
||||
|
||||
extern "C" {
|
||||
extern bool skwasm_isSingleThreaded();
|
||||
extern void skwasm_setAssociatedObjectOnThread(unsigned long threadId,
|
||||
void* pointer,
|
||||
SkwasmObject object);
|
||||
|
@ -3,7 +3,6 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "surface.h"
|
||||
#include <emscripten/wasm_worker.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "skwasm_support.h"
|
||||
@ -15,23 +14,6 @@
|
||||
|
||||
using namespace Skwasm;
|
||||
|
||||
Surface::Surface() {
|
||||
if (skwasm_isSingleThreaded()) {
|
||||
skwasm_connectThread(0);
|
||||
} else {
|
||||
assert(emscripten_is_main_browser_thread());
|
||||
|
||||
_thread = emscripten_malloc_wasm_worker(65536);
|
||||
emscripten_wasm_worker_post_function_v(_thread, []() {
|
||||
// Listen to the main thread from the worker
|
||||
skwasm_connectThread(0);
|
||||
});
|
||||
|
||||
// Listen to messages from the worker
|
||||
skwasm_connectThread(_thread);
|
||||
}
|
||||
}
|
||||
|
||||
// Worker thread only
|
||||
void Surface::dispose() {
|
||||
delete this;
|
||||
@ -76,8 +58,16 @@ void Surface::setCallbackHandler(CallbackHandler* callbackHandler) {
|
||||
_callbackHandler = callbackHandler;
|
||||
}
|
||||
|
||||
// Worker thread only
|
||||
void Surface::_runWorker() {
|
||||
_init();
|
||||
emscripten_exit_with_live_runtime();
|
||||
}
|
||||
|
||||
// Worker thread only
|
||||
void Surface::_init() {
|
||||
// Listen to messages from the main thread
|
||||
skwasm_connectThread(0);
|
||||
_glContext = skwasm_createOffscreenCanvas(256, 256);
|
||||
if (!_glContext) {
|
||||
printf("Failed to create context!\n");
|
||||
@ -105,8 +95,6 @@ void Surface::_init() {
|
||||
|
||||
emscripten_glGetIntegerv(GL_SAMPLES, &_sampleCount);
|
||||
emscripten_glGetIntegerv(GL_STENCIL_BITS, &_stencil);
|
||||
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
// Worker thread only
|
||||
@ -134,10 +122,6 @@ void Surface::renderPicturesOnWorker(sk_sp<SkPicture>* pictures,
|
||||
int pictureCount,
|
||||
uint32_t callbackId,
|
||||
double rasterStart) {
|
||||
if (!_isInitialized) {
|
||||
_init();
|
||||
}
|
||||
|
||||
// This is populated by the `captureImageBitmap` call the first time it is
|
||||
// passed in.
|
||||
SkwasmObject imageBitmapArray = __builtin_wasm_ref_null_extern();
|
||||
@ -163,10 +147,6 @@ void Surface::renderPicturesOnWorker(sk_sp<SkPicture>* pictures,
|
||||
void Surface::rasterizeImageOnWorker(SkImage* image,
|
||||
ImageByteFormat format,
|
||||
uint32_t callbackId) {
|
||||
if (!_isInitialized) {
|
||||
_init();
|
||||
}
|
||||
|
||||
// We handle PNG encoding with browser APIs so that we can omit libpng from
|
||||
// skia to save binary size.
|
||||
assert(format != ImageByteFormat::png);
|
||||
@ -301,7 +281,3 @@ SKWASM_EXPORT void surface_onRasterizeComplete(Surface* surface,
|
||||
uint32_t callbackId) {
|
||||
surface->onRasterizeComplete(callbackId, data);
|
||||
}
|
||||
|
||||
SKWASM_EXPORT bool skwasm_isMultiThreaded() {
|
||||
return !skwasm_isSingleThreaded();
|
||||
}
|
||||
|
@ -75,10 +75,12 @@ class Surface {
|
||||
uint32_t callbackId);
|
||||
|
||||
private:
|
||||
void _runWorker();
|
||||
void _init();
|
||||
void _resizeCanvasToFit(int width, int height);
|
||||
void _recreateSurface();
|
||||
|
||||
std::string _canvasID;
|
||||
CallbackHandler* _callbackHandler = nullptr;
|
||||
uint32_t _currentCallbackId = 0;
|
||||
|
||||
@ -93,8 +95,6 @@ class Surface {
|
||||
GrGLint _stencil;
|
||||
|
||||
pthread_t _thread;
|
||||
|
||||
bool _isInitialized = false;
|
||||
};
|
||||
} // namespace Skwasm
|
||||
|
||||
|
31
engine/src/flutter/lib/web_ui/skwasm/surface_mt.cpp
Normal file
31
engine/src/flutter/lib/web_ui/skwasm/surface_mt.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "surface.h"
|
||||
|
||||
#include "skwasm_support.h"
|
||||
|
||||
using namespace Skwasm;
|
||||
|
||||
Surface::Surface() {
|
||||
assert(emscripten_is_main_browser_thread());
|
||||
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
pthread_create(
|
||||
&_thread, &attr,
|
||||
[](void* context) -> void* {
|
||||
static_cast<Surface*>(context)->_runWorker();
|
||||
return nullptr;
|
||||
},
|
||||
this);
|
||||
// Listen to messages from the worker
|
||||
skwasm_connectThread(_thread);
|
||||
}
|
||||
|
||||
SKWASM_EXPORT bool skwasm_isMultiThreaded() {
|
||||
return true;
|
||||
}
|
15
engine/src/flutter/lib/web_ui/skwasm/surface_st.cpp
Normal file
15
engine/src/flutter/lib/web_ui/skwasm/surface_st.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "surface.h"
|
||||
|
||||
using namespace Skwasm;
|
||||
|
||||
Surface::Surface() : _thread(0) {
|
||||
_init();
|
||||
}
|
||||
|
||||
SKWASM_EXPORT bool skwasm_isMultiThreaded() {
|
||||
return false;
|
||||
}
|
@ -88,7 +88,31 @@ wasm_toolchain("skwasm") {
|
||||
skia_use_libpng_encode = false
|
||||
|
||||
# skwasm is multithreaded
|
||||
wasm_use_workers = true
|
||||
wasm_use_pthreads = true
|
||||
wasm_prioritize_size = true
|
||||
}
|
||||
}
|
||||
|
||||
wasm_toolchain("skwasm_st") {
|
||||
extra_toolchain_args = {
|
||||
# In Chromium browsers, we can use the browser's APIs to get the necessary
|
||||
# ICU data.
|
||||
skia_use_icu = false
|
||||
skia_use_client_icu = true
|
||||
skia_icu_bidi_third_party_dir = "//flutter/third_party/canvaskit/icu_bidi"
|
||||
|
||||
skia_use_libjpeg_turbo_decode = false
|
||||
skia_use_libpng_decode = false
|
||||
skia_use_libwebp_decode = false
|
||||
|
||||
# We use OffscreenCanvas to produce PNG data instead of skia
|
||||
skia_use_no_png_encode = true
|
||||
skia_use_libpng_encode = false
|
||||
|
||||
# skwasm_st doesn't use pthreads, but does pass the shared memory flag in order
|
||||
# to be compatible with the way app modules import the memory object.
|
||||
wasm_use_pthreads = false
|
||||
wasm_shared_memory = true
|
||||
wasm_prioritize_size = true
|
||||
}
|
||||
}
|
||||
@ -109,3 +133,20 @@ copy("skwasm_group") {
|
||||
}
|
||||
outputs = [ "$root_out_dir/flutter_web_sdk/canvaskit/{{source_file_part}}" ]
|
||||
}
|
||||
|
||||
copy("skwasm_st_group") {
|
||||
visibility = [ "//flutter/web_sdk:*" ]
|
||||
public_deps = [ "//flutter/lib/web_ui/skwasm:skwasm_st(:skwasm_st)" ]
|
||||
|
||||
sources = [
|
||||
"$root_out_dir/skwasm_st/skwasm_st.js",
|
||||
"$root_out_dir/skwasm_st/skwasm_st.js.symbols",
|
||||
"$root_out_dir/skwasm_st/skwasm_st.wasm",
|
||||
]
|
||||
if (is_debug) {
|
||||
if (!wasm_use_dwarf) {
|
||||
sources += [ "$root_out_dir/skwasm_st/skwasm_st.wasm.map" ]
|
||||
}
|
||||
}
|
||||
outputs = [ "$root_out_dir/flutter_web_sdk/canvaskit/{{source_file_part}}" ]
|
||||
}
|
||||
|
@ -414,6 +414,7 @@ if (!is_fuchsia) {
|
||||
"//flutter/third_party/canvaskit:canvaskit_chromium_group",
|
||||
"//flutter/third_party/canvaskit:canvaskit_group",
|
||||
"//flutter/third_party/canvaskit:skwasm_group",
|
||||
"//flutter/third_party/canvaskit:skwasm_st_group",
|
||||
]
|
||||
}
|
||||
deps += [ "//flutter/lib/web_ui/flutter_js" ]
|
||||
@ -438,6 +439,9 @@ if (!is_fuchsia) {
|
||||
"$root_out_dir/flutter_web_sdk/canvaskit/skwasm.js",
|
||||
"$root_out_dir/flutter_web_sdk/canvaskit/skwasm.js.symbols",
|
||||
"$root_out_dir/flutter_web_sdk/canvaskit/skwasm.wasm",
|
||||
"$root_out_dir/flutter_web_sdk/canvaskit/skwasm_st.js",
|
||||
"$root_out_dir/flutter_web_sdk/canvaskit/skwasm_st.js.symbols",
|
||||
"$root_out_dir/flutter_web_sdk/canvaskit/skwasm_st.wasm",
|
||||
]
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user