summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2018-03-20 13:30:53 +0100
committerMorten Johan Sørvig <morten.sorvig@qt.io>2019-02-07 16:13:26 +0000
commitde4f256d48145778ed56389f5e883c5994b34dd2 (patch)
treeb60e8d154cf86e6077eedda79c96b3abecae9a2f
parent6e7a7d5fb917b9099788a5917507dbfa56d5495c (diff)
Wasm: enable thread support
configure.json: Make the “thread” feature be allowed for wasm but disabled by default. Change qmake.conf and wasm.prf to enable Emscripten pthreads mode: - Add USE_PTHREADS=1 linker flag - Add PTHREAD_POOL_SIZE linker flag with a default pool size (4). - Add TOTAL_MEMORY linker flag to set available memory (1GB) It is possible to override options such as PTHREAD_POOL_SIZE from the application .pro file using QMAKE_WASM_PTHREAD_POOL_SIZE To change TOTAL_MEMORY, use QMAKE_WASM_TOTAL_MEMORY Make qtloader.js work in pthreads mode: - The Module.instantiateWasm callback must provide the module in addition to the instance to Emscripten. - Set Module.mainScriptUrlOrBlob so that the pthreads web workers can access the main script Task-number: QTBUG-64625 Change-Id: I1ab5a559ec97c27c5fc24500ba5f863bcd275141 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io> Reviewed-by: Lorn Potter <lorn.potter@gmail.com>
-rw-r--r--configure.json2
-rw-r--r--mkspecs/features/qt.prf2
-rw-r--r--mkspecs/features/wasm/wasm.prf33
-rw-r--r--mkspecs/wasm-emscripten/qmake.conf1
-rw-r--r--src/plugins/platforms/wasm/qtloader.js8
5 files changed, 40 insertions, 6 deletions
diff --git a/configure.json b/configure.json
index 4a9e1fc24e..f7449ec068 100644
--- a/configure.json
+++ b/configure.json
@@ -1199,7 +1199,7 @@
"label": "Thread support",
"purpose": "Provides QThread and related classes.",
"section": "Kernel",
- "condition": "!config.wasm",
+ "autoDetect": "!config.wasm",
"output": [ "publicFeature" ]
},
"future": {
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index d8d5acaafd..5ac640190a 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -2,7 +2,7 @@
# due to required Qt modules being missing.
!isEmpty(QMAKE_FAILED_REQUIREMENTS): return()
-CONFIG *= thread
+qtConfig(thread): CONFIG *= thread
#handle defines
win32 {
diff --git a/mkspecs/features/wasm/wasm.prf b/mkspecs/features/wasm/wasm.prf
index c885b166ce..de726c674c 100644
--- a/mkspecs/features/wasm/wasm.prf
+++ b/mkspecs/features/wasm/wasm.prf
@@ -2,6 +2,39 @@
# DESTDIR will be empty if not set in the app .pro file; make sure it has a value
isEmpty(DESTDIR): DESTDIR = $$OUT_PWD
+exists($$QMAKE_QT_CONFIG) {
+ qtConfig(thread) {
+
+ EMCC_THREAD_LFLAGS += -s USE_PTHREADS=1
+ # Hardcode wasm memory size. Emscripten does not currently support memory growth
+ # (ALLOW_MEMORY_GROWTH) in pthreads mode, and requires specifying the memory size
+ # at build time. Further, browsers limit the maximum initial memory size to 1GB.
+ TOTAL_MEMORY = 1GB
+ !isEmpty(QMAKE_WASM_TOTAL_MEMORY) {
+ TOTAL_MEMORY = $$QMAKE_WASM_TOTAL_MEMORY
+ }
+
+ message("Setting TOTAL_MEMORY to" $$TOTAL_MEMORY)
+ EMCC_THREAD_LFLAGS += -s TOTAL_MEMORY=$$TOTAL_MEMORY
+
+ # Create worker threads at startup. This is supposed to be an optimization,
+ # however exceeding the pool size has been obesverved to hang the application.
+ POOL_SIZE = 4
+ !isEmpty(QMAKE_WASM_PTHREAD_POOL_SIZE) {
+ POOL_SIZE = $$QMAKE_WASM_PTHREAD_POOL_SIZE
+ }
+
+ message("Setting PTHREAD_POOL_SIZE to" $$POOL_SIZE)
+ EMCC_THREAD_LFLAGS += -s PTHREAD_POOL_SIZE=$$POOL_SIZE
+ } else {
+ EMCC_THREAD_LFLAGS += -s ALLOW_MEMORY_GROWTH=1
+ }
+ QMAKE_LFLAGS += $$EMCC_THREAD_LFLAGS
+ QMAKE_LFLAGS_DEBUG += $$EMCC_THREAD_LFLAGS
+ QMAKE_CFLAGS += $$EMCC_THREAD_LFLAGS
+ QMAKE_CXXFLAGS += $$EMCC_THREAD_LFLAGS
+}
+
# Create js and wasm files for applications
contains(TEMPLATE, .*app) {
TARGET_BASE = $${TARGET}
diff --git a/mkspecs/wasm-emscripten/qmake.conf b/mkspecs/wasm-emscripten/qmake.conf
index e7b45d312d..6c4e62aff2 100644
--- a/mkspecs/wasm-emscripten/qmake.conf
+++ b/mkspecs/wasm-emscripten/qmake.conf
@@ -15,7 +15,6 @@ EMTERP_FLAGS = \
EMCC_COMMON_LFLAGS = \
-s WASM=1 \
-s FULL_ES2=1 \
- -s ALLOW_MEMORY_GROWTH=1 \
-s USE_WEBGL2=1 \
-s NO_EXIT_RUNTIME=0 \
-s ERROR_ON_UNDEFINED_SYMBOLS=1 \
diff --git a/src/plugins/platforms/wasm/qtloader.js b/src/plugins/platforms/wasm/qtloader.js
index 37a5308034..84694c7b9f 100644
--- a/src/plugins/platforms/wasm/qtloader.js
+++ b/src/plugins/platforms/wasm/qtloader.js
@@ -312,13 +312,13 @@ function QtLoader(config)
// and is ready to be instantiated. Define the instantiateWasm callback which
// emscripten will call to create the instance.
Module.instantiateWasm = function(imports, successCallback) {
- return WebAssembly.instantiate(wasmModule, imports).then(function(instance) {
- successCallback(instance);
- return instance;
+ WebAssembly.instantiate(wasmModule, imports).then(function(instance) {
+ successCallback(instance, wasmModule);
}, function(error) {
self.error = error;
setStatus("Error");
});
+ return {};
};
Module.locateFile = Module.locateFile || function(filename) {
@@ -382,6 +382,8 @@ function QtLoader(config)
}
});
+ Module.mainScriptUrlOrBlob = new Blob([emscriptenModuleSource], {type: 'text/javascript'});
+
config.restart = function() {
// Restart by reloading the page. This will wipe all state which means