From 62fe8d554e73c2f85bafa1952ff2138a015f0f0d Mon Sep 17 00:00:00 2001 From: Emil Ernerfeldt Date: Tue, 9 May 2023 10:11:46 +0200 Subject: [PATCH] Optimize GLTF/GLB texture loading in debug builds --- crates/re_renderer/src/importer/gltf.rs | 13 +++++++++-- crates/re_renderer/src/lib.rs | 23 +++++++++++++++++++ .../src/resource_managers/texture_manager.rs | 9 -------- .../src/gpu_bridge/tensor_to_gpu.rs | 23 ++----------------- 4 files changed, 36 insertions(+), 32 deletions(-) diff --git a/crates/re_renderer/src/importer/gltf.rs b/crates/re_renderer/src/importer/gltf.rs index ba259c9f30bbd..bcf43901dc9dd 100644 --- a/crates/re_renderer/src/importer/gltf.rs +++ b/crates/re_renderer/src/importer/gltf.rs @@ -21,10 +21,17 @@ pub fn load_gltf_from_buffer( lifetime: ResourceLifeTime, ctx: &mut RenderContext, ) -> anyhow::Result> { - let (doc, buffers, images) = gltf::import_slice(buffer)?; + crate::profile_function!(); + + let (doc, buffers, images) = { + crate::profile_scope!("gltf::import_slice"); + gltf::import_slice(buffer)? + }; let mut images_as_textures = Vec::with_capacity(images.len()); for (_index, image) in images.into_iter().enumerate() { + crate::profile_scope!("image"); + let (format, data) = if let Some(format) = map_format(image.format) { (format, image.pixels) } else { @@ -33,7 +40,7 @@ pub fn load_gltf_from_buffer( re_log::debug!("Converting Rgb8 to Rgba8"); ( wgpu::TextureFormat::Rgba8UnormSrgb, - Texture2DCreationDesc::convert_rgb8_to_rgba8(&image.pixels), + crate::pad_rgb_to_rgba(&image.pixels, 255), ) } else { anyhow::bail!("Unsupported texture format {:?}", image.format); @@ -83,6 +90,8 @@ pub fn load_gltf_from_buffer( let mut meshes = HashMap::with_capacity(doc.meshes().len()); for ref mesh in doc.meshes() { + crate::profile_scope!("mesh"); + let re_mesh = import_mesh( mesh, &buffers, diff --git a/crates/re_renderer/src/lib.rs b/crates/re_renderer/src/lib.rs index f6e07b5839c1f..b4067b7ec7e81 100644 --- a/crates/re_renderer/src/lib.rs +++ b/crates/re_renderer/src/lib.rs @@ -112,3 +112,26 @@ macro_rules! profile_scope { puffin::profile_scope!($($arg)*); }; } + +// --------------------------------------------------------------------------- + +/// Pad `RGB` to `RGBA` with the given alpha. +pub fn pad_rgb_to_rgba(rgb: &[T], alpha: T) -> Vec { + crate::profile_function!(); + if cfg!(debug_assertions) { + // fastest version in debug builds. + // 5x faster in debug builds, but 2x slower in release + let mut rgba = vec![alpha; rgb.len() / 3 * 4]; + for i in 0..(rgb.len() / 3) { + rgba[4 * i] = rgb[3 * i]; + rgba[4 * i + 1] = rgb[3 * i + 1]; + rgba[4 * i + 2] = rgb[3 * i + 2]; + } + rgba + } else { + // fastest version in optimized builds + rgb.chunks_exact(3) + .flat_map(|chunk| [chunk[0], chunk[1], chunk[2], alpha]) + .collect() + } +} diff --git a/crates/re_renderer/src/resource_managers/texture_manager.rs b/crates/re_renderer/src/resource_managers/texture_manager.rs index 80da2c5768fef..f754529db9374 100644 --- a/crates/re_renderer/src/resource_managers/texture_manager.rs +++ b/crates/re_renderer/src/resource_managers/texture_manager.rs @@ -86,15 +86,6 @@ pub struct Texture2DCreationDesc<'a> { //generate_mip_maps: bool, // TODO(andreas): generate mipmaps! } -impl<'a> Texture2DCreationDesc<'a> { - pub fn convert_rgb8_to_rgba8(rgb_pixels: &[u8]) -> Vec { - rgb_pixels - .chunks_exact(3) - .flat_map(|color| [color[0], color[1], color[2], 255]) - .collect() - } -} - // TODO(andreas): Move this to texture pool. #[derive(thiserror::Error, Debug)] pub enum TextureCreationError { diff --git a/crates/re_viewer_context/src/gpu_bridge/tensor_to_gpu.rs b/crates/re_viewer_context/src/gpu_bridge/tensor_to_gpu.rs index 9defa73232172..d5873bdb0c912 100644 --- a/crates/re_viewer_context/src/gpu_bridge/tensor_to_gpu.rs +++ b/crates/re_viewer_context/src/gpu_bridge/tensor_to_gpu.rs @@ -10,6 +10,7 @@ use wgpu::TextureFormat; use re_log_types::component_types::{DecodedTensor, Tensor, TensorData}; use re_renderer::{ + pad_rgb_to_rgba, renderer::{ColorMapper, ColormappedTexture}, resource_managers::Texture2DCreationDesc, RenderContext, @@ -419,29 +420,9 @@ fn narrow_f64_to_f32s(slice: &[f64]) -> Cow<'static, [u8]> { bytes.into() } -fn pad_to_four_elements(data: &[T], pad: T) -> Vec { - crate::profile_function!(); - if cfg!(debug_assertions) { - // fastest version in debug builds. - // 5x faster in debug builds, but 2x slower in release - let mut padded = vec![pad; data.len() / 3 * 4]; - for i in 0..(data.len() / 3) { - padded[4 * i] = data[3 * i]; - padded[4 * i + 1] = data[3 * i + 1]; - padded[4 * i + 2] = data[3 * i + 2]; - } - padded - } else { - // fastest version in optimized builds - data.chunks_exact(3) - .flat_map(|chunk| [chunk[0], chunk[1], chunk[2], pad]) - .collect() - } -} - fn pad_and_cast(data: &[T], pad: T) -> Cow<'static, [u8]> { crate::profile_function!(); - let padded: Vec = pad_to_four_elements(data, pad); + let padded: Vec = pad_rgb_to_rgba(data, pad); let bytes: Vec = pod_collect_to_vec(&padded); bytes.into() }