Skip to content

Commit a897b49

Browse files
committed
[Web] Make {emscripten,godot}ThreadPool values automatic
1 parent 71a9948 commit a897b49

File tree

6 files changed

+33
-29
lines changed

6 files changed

+33
-29
lines changed

misc/dist/html/editor.html

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -425,7 +425,7 @@ <h2 id="welcome-modal-title" class="welcome-modal-title">Important - Please read
425425
let setStatusNotice;
426426
let video_driver = '';
427427

428-
function clearPersistence() { // eslint-disable-line no-unused-vars
428+
async function clearPersistence() { // eslint-disable-line no-unused-vars
429429
function deleteDB(path) {
430430
return new Promise(function (resolve, reject) {
431431
const req = indexedDB.deleteDatabase(path);
@@ -440,16 +440,30 @@ <h2 id="welcome-modal-title" class="welcome-modal-title">Important - Please read
440440
};
441441
});
442442
}
443+
async function removeServiceWorkerAndCache() {
444+
const registrations = await navigator.serviceWorker.getRegistrations();
445+
for (const registration of registrations) {
446+
// eslint-disable-next-line no-await-in-loop
447+
for (const key of await (caches?.keys() ?? [])) {
448+
await caches.delete(key); // eslint-disable-line no-await-in-loop
449+
}
450+
await registration.unregister(); // eslint-disable-line no-await-in-loop
451+
}
452+
}
443453
if (!window.confirm('Are you sure you want to delete all the locally stored files?\nClicking "OK" will permanently remove your projects and editor settings!')) {
444454
return;
445455
}
446-
Promise.all([
447-
deleteDB('/home/web_user'),
448-
]).then(function (results) {
456+
try {
457+
await Promise.all([
458+
deleteDB('/home/web_user'),
459+
removeServiceWorkerAndCache(),
460+
]);
449461
alert('Done.');
450-
}).catch(function (err) {
462+
window.location.reload();
463+
} catch (error) {
464+
console.error('Error deleting local files:', error);
451465
alert('Error deleting local files. Please retry after reloading the page.');
452-
});
466+
}
453467
}
454468

455469
function selectVideoMode() {

platform/web/detect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def configure(env: "SConsEnvironment"):
256256
env.Append(CCFLAGS=["-sUSE_PTHREADS=1"])
257257
env.Append(LINKFLAGS=["-sUSE_PTHREADS=1"])
258258
env.Append(LINKFLAGS=["-sDEFAULT_PTHREAD_STACK_SIZE=%sKB" % env["default_pthread_stack_size"]])
259-
env.Append(LINKFLAGS=["-sPTHREAD_POOL_SIZE=\"Module['emscriptenPoolSize']||8\""])
259+
env.Append(LINKFLAGS=["-sPTHREAD_POOL_SIZE='Module['emscriptenPoolSize'] ?? navigator.hardwareConcurrency'"])
260260
env.Append(LINKFLAGS=["-sWASM_MEM_MAX=2048MB"])
261261
if not env["dlink_enabled"]:
262262
# Workaround https://github.com/emscripten-core/emscripten/issues/21844#issuecomment-2116936414.

platform/web/doc_classes/EditorExportPlatformWeb.xml

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,6 @@
7979
- [b]Landscape:[/b] Forces a horizontal layout (wider than it is taller).
8080
- [b]Portrait:[/b] Forces a vertical layout (taller than it is wider).
8181
</member>
82-
<member name="threads/emscripten_pool_size" type="int" setter="" getter="">
83-
The number of threads that emscripten will allocate at startup. A smaller value will allocate fewer threads and consume fewer system resources, but you may run the risk of running out of threads in the pool and needing to allocate more threads at run time which may cause a deadlock.
84-
[b]Note:[/b] Some browsers have a hard cap on the number of threads that can be allocated, so it is best to be cautious and keep this number low.
85-
</member>
86-
<member name="threads/godot_pool_size" type="int" setter="" getter="">
87-
Override for the default size of the [WorkerThreadPool]. This setting is used when [member ProjectSettings.threading/worker_pool/max_threads] size is set to -1 (which it is by default). This size must be smaller than [member threads/emscripten_pool_size] otherwise deadlocks may occur.
88-
When using threads this size needs to be large enough to accommodate features that rely on having a dedicated thread like [member ProjectSettings.physics/2d/run_on_separate_thread] or [member ProjectSettings.rendering/driver/threads/thread_model]. In general, it is best to ensure that this is at least 4 and is at least 2 or 3 less than [member threads/emscripten_pool_size].
89-
</member>
9082
<member name="variant/extensions_support" type="bool" setter="" getter="">
9183
If [code]true[/code] enables [GDExtension] support for this web build.
9284
</member>

platform/web/export/export_plugin.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,6 @@ void EditorExportPlatformWeb::_fix_html(Vector<uint8_t> &p_html, const Ref<Edito
149149
config["fileSizes"] = p_file_sizes;
150150
config["ensureCrossOriginIsolationHeaders"] = (bool)p_preset->get("progressive_web_app/ensure_cross_origin_isolation_headers");
151151

152-
config["godotPoolSize"] = p_preset->get("threads/godot_pool_size");
153-
config["emscriptenPoolSize"] = p_preset->get("threads/emscripten_pool_size");
154-
155152
String head_include;
156153
if (p_preset->get("html/export_icon")) {
157154
head_include += "<link id=\"-gd-engine-icon\" rel=\"icon\" type=\"image/png\" href=\"" + p_name + ".icon.png\" />\n";
@@ -386,9 +383,6 @@ void EditorExportPlatformWeb::get_export_options(List<ExportOption> *r_options)
386383
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/icon_180x180", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg"), ""));
387384
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "progressive_web_app/icon_512x512", PROPERTY_HINT_FILE, "*.png,*.webp,*.svg"), ""));
388385
r_options->push_back(ExportOption(PropertyInfo(Variant::COLOR, "progressive_web_app/background_color", PROPERTY_HINT_COLOR_NO_ALPHA), Color()));
389-
390-
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "threads/emscripten_pool_size"), 8));
391-
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "threads/godot_pool_size"), 4));
392386
}
393387

394388
bool EditorExportPlatformWeb::get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const {
@@ -397,10 +391,6 @@ bool EditorExportPlatformWeb::get_export_option_visibility(const EditorExportPre
397391
return advanced_options_enabled;
398392
}
399393

400-
if (p_option == "threads/godot_pool_size" || p_option == "threads/emscripten_pool_size") {
401-
return p_preset->get("variant/thread_support").operator bool();
402-
}
403-
404394
return true;
405395
}
406396

platform/web/js/engine/config.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ const EngineConfig = {}; // eslint-disable-line no-unused-vars
1717
* @ignore
1818
*/
1919
const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-vars
20+
const emscriptenPoolSize = Math.max(navigator.hardwareConcurrency, 6);
21+
const godotPoolSize = Math.max(3, Math.floor(emscriptenPoolSize / 4));
22+
2023
const cfg = /** @lends {InternalConfig.prototype} */ {
2124
/**
2225
* Whether to unload the engine automatically after the instance is initialized.
@@ -137,12 +140,12 @@ const InternalConfig = function (initConfig) { // eslint-disable-line no-unused-
137140
* @ignore
138141
* @type {number}
139142
*/
140-
emscriptenPoolSize: 8,
143+
emscriptenPoolSize,
141144
/**
142145
* @ignore
143146
* @type {number}
144147
*/
145-
godotPoolSize: 4,
148+
godotPoolSize,
146149
/**
147150
* A callback function for handling Godot's ``OS.execute`` calls.
148151
*

platform/web/js/libs/library_godot_os.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ const GodotConfig = {
7171
GodotConfig.locale = p_opts['locale'] || GodotConfig.locale;
7272
GodotConfig.virtual_keyboard = p_opts['virtualKeyboard'];
7373
GodotConfig.persistent_drops = !!p_opts['persistentDrops'];
74+
GodotConfig.emscripten_pool_size = p_opts['emscriptenPoolSize'];
7475
GodotConfig.godot_pool_size = p_opts['godotPoolSize'];
7576
GodotConfig.on_execute = p_opts['onExecute'];
7677
GodotConfig.on_exit = p_opts['onExit'];
@@ -343,9 +344,13 @@ const GodotOS = {
343344
godot_js_os_hw_concurrency_get__proxy: 'sync',
344345
godot_js_os_hw_concurrency_get__sig: 'i',
345346
godot_js_os_hw_concurrency_get: function () {
347+
if (typeof PThread === 'undefined') {
348+
// Threads aren't supported, so default to `1`.
349+
return 1;
350+
}
351+
346352
// TODO Godot core needs fixing to avoid spawning too many threads (> 24).
347-
const concurrency = navigator.hardwareConcurrency || 1;
348-
return concurrency < 2 ? concurrency : 2;
353+
return Math.max(GodotConfig.emscripten_pool_size, 2);
349354
},
350355

351356
godot_js_os_thread_pool_size_get__proxy: 'sync',

0 commit comments

Comments
 (0)