diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2018-03-20 13:30:53 +0100 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2019-02-07 16:13:26 +0000 |
commit | de4f256d48145778ed56389f5e883c5994b34dd2 (patch) | |
tree | b60e8d154cf86e6077eedda79c96b3abecae9a2f | |
parent | 6e7a7d5fb917b9099788a5917507dbfa56d5495c (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.json | 2 | ||||
-rw-r--r-- | mkspecs/features/qt.prf | 2 | ||||
-rw-r--r-- | mkspecs/features/wasm/wasm.prf | 33 | ||||
-rw-r--r-- | mkspecs/wasm-emscripten/qmake.conf | 1 | ||||
-rw-r--r-- | src/plugins/platforms/wasm/qtloader.js | 8 |
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 |