godot
godot copied to clipboard
Rework threaded resource loading
I've reworked the resource loader so all the kinds of loads (current thread, another thread, multiple threads) cooperate better among them regardless which are in flight. This should get rid of some or all of the issues that users are encountering in this area. (I've come across some crashes due to some of the resources being loaded being of classes which are not thread-safe, but those are separate issues.)
The exposed API is the same, but the inner workings of the loaders are changed so that they have more common code paths.
Progress reporting also works now! It has room for improvement, but at least it goes from 0 to 1 with growing intermediate values.
~TODO: Progress reporting is still not done.~
There are plans to maybe re-rewrite this based on a worker thread pool, but this should serve as a better base than the former implementation.
Supersedes #74120. Supersedes #74108. Fixes #56882.
Now resource loading passes thread sanitization tests from #73825 with only a few minor data race issues that are not a real issue in practice (see https://github.com/RandomShaper/godot/actions/runs/4337516127/jobs/7573570235).
UPDATE: More:
- Cleanup of load tasks is pretty robust now (or so I think). When closing the engine, a cascade of cancels happens so tasks don't leak resources. The slight issue with that is that resource loaders print errors about non-satisfied dependencies, but that could be made silent if a big deal.
All that said, I need help testing this, because I've run out of time. CC @godotengine/production
~@Anixias, I'm not completely sure your issue is due to resource loading, but could you give this PR a try?~
~@mrTag, once again I'm summoning you, this time for testing this attempt of mine to fix the thing.~
There's still an issue to fix before testing. I'll write another comment when ready.
This is ready for testing, so this comment is relevant again:
@Anixias, I'm not completely sure your issue is due to resource loading, but could you give this PR a try?
@mrTag, once again I'm summoning you, this time for testing this attempt of mine to fix the thing.
@RandomShaper hmm, the loading freezes pretty much instantly and every time with this PR. I had a look at the threads and the main thread hangs in the thread_load_mutex with this callstack:
[libc.so.6] <unknown> 0x00007f716274d6f0
[godot.linuxbsd.editor.x86_64] MutexLock::MutexLock mutex.h:122
[godot.linuxbsd.editor.x86_64] ResourceLoader::_load_complete resource_loader.cpp:560
[godot.linuxbsd.editor.x86_64] ResourceLoader::load_threaded_get ref_counted.h:115
[godot.linuxbsd.editor.x86_64] core_bind::ResourceLoader::load_threaded_get core_bind.cpp:64
[godot.linuxbsd.editor.x86_64] call_with_ptr_args_ret_helper<…> binder_common.h:324
[godot.linuxbsd.editor.x86_64] call_with_ptr_args_ret<…> binder_common.h:572
[godot.linuxbsd.editor.x86_64] MethodBindTR::ptrcall method_bind.h:478
[godot.linuxbsd.editor.x86_64] GDScriptFunction::call gdscript_vm.cpp:2027
[godot.linuxbsd.editor.x86_64] GDScriptInstance::callp gdscript.cpp:1832
[godot.linuxbsd.editor.x86_64] Object::callp object.cpp:711
[godot.linuxbsd.editor.x86_64] Variant::callp variant_call.cpp:1161
[godot.linuxbsd.editor.x86_64] GDScriptFunction::call gdscript_vm.cpp:1632
[godot.linuxbsd.editor.x86_64] GDScriptFunctionState::resume gdscript_function.cpp:252
[godot.linuxbsd.editor.x86_64] GDScriptFunctionState::_signal_callback gdscript_function.cpp:202
[godot.linuxbsd.editor.x86_64] MethodBindVarArgTR::call method_bind.h:254
[godot.linuxbsd.editor.x86_64] Object::callp object.cpp:733
[godot.linuxbsd.editor.x86_64] Callable::callp callable.cpp:62
[godot.linuxbsd.editor.x86_64] CallableCustomBind::call callable_bind.cpp:140
[godot.linuxbsd.editor.x86_64] Object::emit_signalp object.cpp:1046
[godot.linuxbsd.editor.x86_64] Object::emit_signal<…> object.h:866
[godot.linuxbsd.editor.x86_64] GDScriptFunctionState::resume gdscript_function.cpp:273
[godot.linuxbsd.editor.x86_64] GDScriptFunctionState::_signal_callback gdscript_function.cpp:202
[godot.linuxbsd.editor.x86_64] MethodBindVarArgTR::call method_bind.h:254
[godot.linuxbsd.editor.x86_64] Object::callp object.cpp:733
[godot.linuxbsd.editor.x86_64] Callable::callp callable.cpp:62
[godot.linuxbsd.editor.x86_64] CallableCustomBind::call callable_bind.cpp:140
[godot.linuxbsd.editor.x86_64] Object::emit_signalp object.cpp:1046
[godot.linuxbsd.editor.x86_64] GDScriptFunction::call gdscript_vm.cpp:1666
[godot.linuxbsd.editor.x86_64] GDScriptInstance::callp gdscript.cpp:1832
[godot.linuxbsd.editor.x86_64] Node::_gdvirtual__process_call<…> node.h:238
[godot.linuxbsd.editor.x86_64] Node::_notification node.cpp:60
[godot.linuxbsd.editor.x86_64] Object::notification object.cpp:790
[godot.linuxbsd.editor.x86_64] SceneTree::_notify_group_pause scene_tree.cpp:886
[godot.linuxbsd.editor.x86_64] SceneTree::process scene_tree.cpp:476
[godot.linuxbsd.editor.x86_64] Main::iteration main.cpp:3164
[godot.linuxbsd.editor.x86_64] OS_LinuxBSD::run os_linuxbsd.cpp:880
[godot.linuxbsd.editor.x86_64] main godot_linuxbsd.cpp:73
The strange thing ist this though: I went through all the other threads and none were locking this mutex 🤔 so maybe someone just forgot to unlock it?
Btw: we load the resources with this ResourceLoaderQueue: https://gist.github.com/mrTag/c8ac769f82ee9b0b408f7f55ef71edad
And I also removed the complete _process, just to see if any of the ResourceLoader.load_threaded_get_status or ResourceLoader.load_threaded_get were the culprit: they weren't, the main thread also hangs with just a few ResourceLoader.load_threaded_request triggered.
@mrTag, I just realized a silly mutex mistake. I've fixed it and improved a number of other things.
@RandomShaper it doesn't freeze on loading anymore, so that's good! Unfortunately even a ResourceLoader.load_threaded_request with subthreads=false results in the "referenced nonexistent resource" and the loading fails. When I set subthreads to true, then it fails even earlier with that error.
I'll have a look at the unit tests for the threaded resource loading, maybe I'll find a way to add our usage to a unit test, then you'll have faster iteration time 😃
@RandomShaper I think I isolated the problem successfully in a test! Have a look here: https://gist.github.com/mrTag/117ba6737ab9cee789cb4835dc702fe2 When I run the test like this, I'll get the dreaded "referenced non-existent resource" error and the test fails. But when I uncomment the two 5000 microsecond delays in line 52 and 58 (essentially making it single threaded), then it runs through without errors and the test passes (that is my check to make sure I didn't mess up the test :)
The test creates resources with sub resources like this:
- it creates 1 item_script_mock.tres mocking something like an item script
- then it creates 25 item_scene_mock.tres, each one having the item_script_mock as a sub resource, mocking something like concrete item scenes
- and lastly it creates 1 item_collection_mock.tres, which has all the item_scene_mock as a sub resources, mocking something like an item pool At first I tried it with just the item_script and item_scene and that passed (but only with use_sub_threads=false!). So it seems like it needs the 2 layers of sub resources to fail! 🤔
The existing "[Resource] Thread safety test" in the test_resource.h freezes on my system and I didn't quite get what it wanted to test, so I didn't touch it...
A side note, maybe of interest: I also just tried that unit test with our current version of godot (basically 4.0.1-rc with this PR https://github.com/godotengine/godot/pull/74108 and this commit: https://github.com/RandomShaper/godot/commit/047671df0f6a7a300b83f36b5d6110a8165b0dfd ) and it passes. Which I kind of expected, since our game uses threaded resource loading like this and the loading works.
@mrTag, thanks to your test case, I've spotted a couple of issues. They are fixed now.
Rebased for 4.1, by the way.
Pushed after a rebase that simplifies the management of thread ids.
Pushed with an additional change, expanding the scope of the benefits of this PR (see update 3 in the description).
Some notes on this PR.
- I think it needs to wait until #75901 is merged, as it rewrites CallQueue in a way that is incompatible with it.
- I don't think the changes to CallQueue are an improvement.
- The thread code needs to use WorkerThreadPool, otherwise it will not work on web.
- I think it needs to wait until Refactor Node Processing to allow Scene Multithreading #75901 is merged, as it rewrites CallQueue in a way that is incompatible with it.
This PR is needed to fix the currently heavily broken resource loader. It was already late to merge it for Godot 4.0 (since it still had issues) and it would be pretty unfortunate that it wouldn't make it in time for Godot 4.1 either because of having to wait for your PR, that I don't think will be merged soon. Also, if this PR is always considered lower priority than any other one touching any of the engine parts it touches, it will be ever-rotten, always needing to be rebased an updated, until I finally give up.
- I don't think the changes to CallQueue are an improvement.
It's a way of making all the resource types compatible with being loaded in a non-main thread, without having to incorporate thread explicit awareness to their code. I believe it's an elegant solution: resources need to queue updates, so they are given a thread-specific call queue to avoid crashes and inconsistencies. I already submitted a similar fix for Godot 3, which was never merged, so the issue has been present until this very day. And now it's more important than ever to have it fixed for good.
- The thread code needs to use WorkerThreadPool, otherwise it will not work on web.
That's orthogonal to this PR. Can be done after it. In any case, there's an outstanding issue by which the threads in the pool may not be attached to the scripting languages. Therefore, using those threads for resource loading, in cases where that implies running user scripts, would lead to issues.
If your PR is going to be merged soon, I can rebase this once more when that happens, but from that point on I won't be able to spend more time on this than the needed for fixing issues.
I've rebased on top of #75901 and based it on the WorkerThreadPool, as requested. See Update 6 in the PR description for further info.
Thanks!
Will this be in 4.0.3 or is this gonna wait for 4.1 or whatever? (Tbh same question applies to nav avoidance rework)
This PR may also fix #75841
This PR may also fix #75841
@akien-mga, I'm adding bugs I'm finding that may be fixed by this to the description of the PR, so they get this:
Is that enough? The problem is that really testing them would consume a lot of time. Maybe we could just close them as hypothetically fixed and ask the reporters to re-open them if that turned out not to be true?
Will this be in 4.0.3 or is this gonna wait for 4.1 or whatever? (Tbh same question applies to nav avoidance rework)
Not in 4.0.3 at any rate, and unlikely for 4.0.4+ IMO, the scope of both of this changes is way too big and not worth the risk of regression / breakage when 4.1 is just around the corner. 4.0.x releases are for safe bugfixes.
4.1 being just around the corner is great news <3, means that question is moot anyway
@RandomShaper The Android editor crashes after this PR with the following stack trace:
--------- beginning of crash
2023-05-12 04:08:24.430 A/libc: Fatal signal 6 (SIGABRT), code -1 (SI_QUEUE) in tid 12317 (GLThread 194), pid 12257 (tProjectManager)
2023-05-12 04:08:24.490 E/crash_dump64: invalid core_num: -1
2023-05-12 04:08:25.656 A/DEBUG: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
2023-05-12 04:08:25.656 A/DEBUG: Build fingerprint: 'samsung/gts8wifixx/gts8wifi:13/TP1A.220624.014/X700XXU3BWC1:user/release-keys'
2023-05-12 04:08:25.656 A/DEBUG: Revision: '8'
2023-05-12 04:08:25.656 A/DEBUG: ABI: 'arm64'
2023-05-12 04:08:25.656 A/DEBUG: Processor: '-1'
2023-05-12 04:08:25.656 A/DEBUG: Timestamp: 2023-05-12 04:08:24.548147037-0700
2023-05-12 04:08:25.656 A/DEBUG: Process uptime: 13s
2023-05-12 04:08:25.656 A/DEBUG: Cmdline: org.godotengine.editor.v4.dev:GodotProjectManager
2023-05-12 04:08:25.656 A/DEBUG: pid: 12257, tid: 12317, name: GLThread 194 >>> org.godotengine.editor.v4.dev:GodotProjectManager <<<
2023-05-12 04:08:25.656 A/DEBUG: uid: 10340
2023-05-12 04:08:25.656 A/DEBUG: tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE)
2023-05-12 04:08:25.656 A/DEBUG: pac_enabled_keys: 000000000000000f (PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY)
2023-05-12 04:08:25.656 A/DEBUG: signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
2023-05-12 04:08:25.656 A/DEBUG: Abort message: 'terminating with uncaught exception of type std::__ndk1::system_error: recursive_mutex lock failed: Try again'
2023-05-12 04:08:25.656 A/DEBUG: x0 0000000000000000 x1 000000000000301d x2 0000000000000006 x3 000000729310c620
2023-05-12 04:08:25.656 A/DEBUG: x4 736f646277641f73 x5 736f646277641f73 x6 736f646277641f73 x7 7f7f7f7f7f7f7f7f
2023-05-12 04:08:25.656 A/DEBUG: x8 00000000000000f0 x9 000000761bca4bf8 x10 0000000000000001 x11 000000761bce5870
2023-05-12 04:08:25.656 A/DEBUG: x12 0000007647de1020 x13 000000007fffffff x14 00000000045b26cc x15 0000071ef6c3f60e
2023-05-12 04:08:25.656 A/DEBUG: x16 000000761bd4dd70 x17 000000761bd295b0 x18 0000007292072000 x19 0000000000002fe1
2023-05-12 04:08:25.656 A/DEBUG: x20 000000000000301d x21 00000000ffffffff x22 ffffff80ffffffc8 x23 000000729310c870
2023-05-12 04:08:25.656 A/DEBUG: x24 000000729310c750 x25 000000729310c790 x26 000000729310d6c4 x27 000000729310d6b0
2023-05-12 04:08:25.656 A/DEBUG: x28 000000729310d5b0 x29 000000729310c6a0
2023-05-12 04:08:25.656 A/DEBUG: lr 000000761bcd67a8 sp 000000729310c600 pc 000000761bcd67d4 pst 0000000000001000
2023-05-12 04:08:25.656 A/DEBUG: backtrace:
2023-05-12 04:08:25.656 A/DEBUG: #00 pc 00000000000537d4 /apex/com.android.runtime/lib64/bionic/libc.so (abort+168) (BuildId: 870560a8376a70249f9e9a7b480cc02f)
2023-05-12 04:08:25.656 A/DEBUG: #01 pc 00000000000cece8 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libc++_shared.so (abort_message+240) (BuildId: d7ce478d849eba1d3e692ae740f6c04a08fb8fab)
2023-05-12 04:08:25.656 A/DEBUG: #02 pc 00000000000cee9c /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libc++_shared.so (demangling_terminate_handler()+264) (BuildId: d7ce478d849eba1d3e692ae740f6c04a08fb8fab)
2023-05-12 04:08:25.656 A/DEBUG: #03 pc 00000000000e3c5c /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libc++_shared.so (std::__terminate(void (*)())+16) (BuildId: d7ce478d849eba1d3e692ae740f6c04a08fb8fab)
2023-05-12 04:08:25.656 A/DEBUG: #04 pc 00000000000e32f4 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libc++_shared.so (__cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*)+32) (BuildId: d7ce478d849eba1d3e692ae740f6c04a08fb8fab)
2023-05-12 04:08:25.656 A/DEBUG: #05 pc 00000000000e3248 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libc++_shared.so (__cxa_throw+124) (BuildId: d7ce478d849eba1d3e692ae740f6c04a08fb8fab)
2023-05-12 04:08:25.656 A/DEBUG: #06 pc 00000000000ce0a0 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libc++_shared.so (std::__ndk1::__throw_system_error(int, char const*)+100) (BuildId: d7ce478d849eba1d3e692ae740f6c04a08fb8fab)
2023-05-12 04:08:25.656 A/DEBUG: #07 pc 00000000000c2d4c /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libc++_shared.so (std::__ndk1::recursive_mutex::lock()+40) (BuildId: d7ce478d849eba1d3e692ae740f6c04a08fb8fab)
2023-05-12 04:08:25.656 A/DEBUG: #08 pc 0000000007e3a3c0 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libgodot_android.so (CallQueue::flush()+92)
2023-05-12 04:08:25.656 A/DEBUG: #09 pc 000000000571fef4 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libgodot_android.so (SceneTree::_process_group(SceneTree::ProcessGroup*, bool)+52)
2023-05-12 04:08:25.656 A/DEBUG: #10 pc 000000000571cec8 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libgodot_android.so (SceneTree::_process(bool)+1216)
2023-05-12 04:08:25.656 A/DEBUG: #11 pc 000000000571dbb8 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libgodot_android.so (SceneTree::process(double)+284)
2023-05-12 04:08:25.656 A/DEBUG: #12 pc 0000000002a480ec /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libgodot_android.so (Main::iteration()+1308)
2023-05-12 04:08:25.656 A/DEBUG: #13 pc 00000000029d99a4 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libgodot_android.so (OS_Android::main_loop_iterate(bool*)+88)
2023-05-12 04:08:25.656 A/DEBUG: #14 pc 00000000029fdf98 /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/lib/arm64/libgodot_android.so (Java_org_godotengine_godot_GodotLib_step+492)
2023-05-12 04:08:25.656 A/DEBUG: #15 pc 0000000000461554 /apex/com.android.art/lib64/libart.so (art_quick_generic_jni_trampoline+148) (BuildId: 289d75599f6112d5757113220599e90b)
2023-05-12 04:08:25.656 A/DEBUG: #16 pc 0000000000209398 /apex/com.android.art/lib64/libart.so (nterp_helper+152) (BuildId: 289d75599f6112d5757113220599e90b)
2023-05-12 04:08:25.656 A/DEBUG: #17 pc 0000000000004dd0 [anon:dalvik-classes12.dex extracted in memory from /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/base.apk!classes12.dex] (org.godotengine.godot.gl.GodotRenderer.onDrawFrame+20)
2023-05-12 04:08:25.656 A/DEBUG: #18 pc 000000000020b074 /apex/com.android.art/lib64/libart.so (nterp_helper+7540) (BuildId: 289d75599f6112d5757113220599e90b)
2023-05-12 04:08:25.656 A/DEBUG: #19 pc 0000000000003f3a [anon:dalvik-classes12.dex extracted in memory from /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/base.apk!classes12.dex] (org.godotengine.godot.gl.GLSurfaceView$GLThread.guardedRun+986)
2023-05-12 04:08:25.656 A/DEBUG: #20 pc 000000000020a254 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: 289d75599f6112d5757113220599e90b)
2023-05-12 04:08:25.656 A/DEBUG: #21 pc 0000000000004500 [anon:dalvik-classes12.dex extracted in memory from /data/app/~~V9RI7paugJrIZ_nHjmG3Vw==/org.godotengine.editor.v4.dev-PDKumFv9MYqCdIF2P0LT0A==/base.apk!classes12.dex] (org.godotengine.godot.gl.GLSurfaceView$GLThread.run+52)
2023-05-12 04:08:25.656 A/DEBUG: #22 pc 0000000000457b6c /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+556) (BuildId: 289d75599f6112d5757113220599e90b)
2023-05-12 04:08:25.656 A/DEBUG: #23 pc 0000000000484e54 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+156) (BuildId: 289d75599f6112d5757113220599e90b)
2023-05-12 04:08:25.656 A/DEBUG: #24 pc 0000000000484b20 /apex/com.android.art/lib64/libart.so (art::JValue art::InvokeVirtualOrInterfaceWithJValues<art::ArtMethod*>(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, art::ArtMethod*, jvalue const*)+400) (BuildId: 289d75599f6112d5757113220599e90b)
2023-05-12 04:08:25.656 A/DEBUG: #25 pc 00000000005ce334 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1684) (BuildId: 289d75599f6112d5757113220599e90b)
2023-05-12 04:08:25.656 A/DEBUG: #26 pc 00000000000bb728 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+208) (BuildId: 870560a8376a70249f9e9a7b480cc02f)
2023-05-12 04:08:25.656 A/DEBUG: #27 pc 000000000005501c /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+68) (BuildId: 870560a8376a70249f9e9a7b480cc02f)
2023-05-12 04:08:25.676 E/tombstoned: Tombstone written to: tombstone_13
@m4gr3d, can you please test with #77229?
@m4gr3d, can you please test with #77229?
@RandomShaper Looks to have fixed the issue! The editor usually crashed a few seconds after starting, but that's no longer happening. I'll keep it running and keep an eye on it to ensure it's fully resolved.
I'm using this class https://github.com/bakneko/godot-template/blob/main/core/classes/loader.gd and once I request to load a scene (46kb, not many nodes), it freezes the game for like 0.2 seconds and I remember it worked fine in previous versions
tested with just load() and works the same, it is ignoring the background loading @RandomShaper
@venilark Please open a bug report with an MRP and a detailed explanation of your issue.
If you haven't already, you should consider asking about this on the forums or discord. My personal experience is that multithreaded loading is much much faster than single threaded loading (I've tested on 4.2.1 and dev3ish). So it is possible that you have made a mistake in your code.
@venilark Please open a bug report with an MRP and a detailed explanation of your issue.
If you haven't already, you should consider asking about this on the forums or discord. My personal experience is that multithreaded loading is much much faster than single threaded loading (I've tested on 4.2.1 and dev3ish). So it is possible that you have made a mistake in your code.
found the problem, it was a mesh with a particular material/shader, without it the background loading works fine
would like to add that with use_sub_threads = true, I've had random crashes with one particular scene without without any kind of error log being output, with = false it doesn't happen, or at least it hasn't happened in over 50 tests I can't upload the project but the scene I try to load has several nodes that are instances and those nodes also have instances as their children I don't open a new issue because I can't upload the MRP
@venilark, do you think you could apply https://github.com/godotengine/godot/pull/88561 locally and try to reproduce the issue to see if that PR fixes it?