From 015da72250f636934453d184bc8bc07379418d93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois?= Date: Fri, 7 Jan 2022 07:19:22 +0000 Subject: [PATCH] gltf loader: do not use the taskpool for only one task (#3577) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Objective - Fix the case mentioned in https://github.com/bevyengine/bevy/pull/2725#issuecomment-1007014024. - On a machine with 4 cores, so 1 thread for assets, loading a gltf with only one textures hangs all asset loading ## Solution - Do not use the task pool when there is only one texture to load Co-authored-by: François <8672791+mockersf@users.noreply.github.com> --- crates/bevy_gltf/src/loader.rs | 62 ++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/crates/bevy_gltf/src/loader.rs b/crates/bevy_gltf/src/loader.rs index b15ab4dbc6..db59b3a8f2 100644 --- a/crates/bevy_gltf/src/loader.rs +++ b/crates/bevy_gltf/src/loader.rs @@ -247,36 +247,40 @@ async fn load_gltf<'a, 'b>( .collect(); // TODO: use the threaded impl on wasm once wasm thread pool doesn't deadlock on it - #[cfg(target_arch = "wasm32")] - for gltf_texture in gltf.textures() { - let (texture, label) = - load_texture(gltf_texture, &buffer_data, &linear_textures, &load_context).await?; - load_context.set_labeled_asset(&label, LoadedAsset::new(texture)); - } - - #[cfg(not(target_arch = "wasm32"))] - load_context - .task_pool() - .scope(|scope| { - gltf.textures().for_each(|gltf_texture| { - let linear_textures = &linear_textures; - let load_context: &LoadContext = load_context; - let buffer_data = &buffer_data; - scope.spawn(async move { - load_texture(gltf_texture, buffer_data, linear_textures, load_context).await - }); - }); - }) - .into_iter() - .filter_map(|res| { - if let Err(err) = res.as_ref() { - warn!("Error loading glTF texture: {}", err); - } - res.ok() - }) - .for_each(|(texture, label)| { + // See https://github.com/bevyengine/bevy/issues/1924 for more details + // The taskpool use is also avoided when there is only one texture for performance reasons and + // to avoid https://github.com/bevyengine/bevy/pull/2725 + if gltf.textures().len() == 1 || cfg!(target_arch = "wasm32") { + for gltf_texture in gltf.textures() { + let (texture, label) = + load_texture(gltf_texture, &buffer_data, &linear_textures, load_context).await?; load_context.set_labeled_asset(&label, LoadedAsset::new(texture)); - }); + } + } else { + #[cfg(not(target_arch = "wasm32"))] + load_context + .task_pool() + .scope(|scope| { + gltf.textures().for_each(|gltf_texture| { + let linear_textures = &linear_textures; + let load_context: &LoadContext = load_context; + let buffer_data = &buffer_data; + scope.spawn(async move { + load_texture(gltf_texture, buffer_data, linear_textures, load_context).await + }); + }); + }) + .into_iter() + .filter_map(|res| { + if let Err(err) = res.as_ref() { + warn!("Error loading glTF texture: {}", err); + } + res.ok() + }) + .for_each(|(texture, label)| { + load_context.set_labeled_asset(&label, LoadedAsset::new(texture)); + }); + } let mut scenes = vec![]; let mut named_scenes = HashMap::default();