From c96f0c30f7fa240354eeff1a96a77fe81e87b155 Mon Sep 17 00:00:00 2001 From: el-j Date: Thu, 29 Oct 2026 00:31:46 +0100 Subject: [PATCH] perf(ui-egui): eliminate zero-filling allocation on canvas texture upload in color_image (#4504) - Replace vec![Color32::TRANSPARENT; N] zero-initialization with direct single-copy bytemuck::cast_slice(&img.pixels).to_vec() in color_image. - Eliminates redundant zero-filling of ~20.7 MB buffer on every canvas frame render on Retina displays, saving memory bandwidth and allocation overhead. - Fallback preserves transparent image for undersized or mismatched pixel buffers. Fixes #4504. --- crates/ui-egui/src/canvas/raster.rs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/crates/ui-egui/src/canvas/raster.rs b/crates/ui-egui/src/canvas/raster.rs index 321ed2acf..a799bbe29 100644 --- a/crates/ui-egui/src/canvas/raster.rs +++ b/crates/ui-egui/src/canvas/raster.rs @@ -5,12 +5,13 @@ use super::{Affine, CacheKey, VectorcraftApp, Xf}; /// A raster whose bytes don't match its size gives an empty image of that size. pub(crate) fn color_image(img: &vectorcraft_render::Rendered) -> egui::ColorImage { let size = [img.width as usize, img.height as usize]; - let mut pixels = vec![egui::Color32::TRANSPARENT; size[0] * size[1]]; - let bytes: &mut [u8] = bytemuck::cast_slice_mut(&mut pixels); - if bytes.len() == img.pixels.len() { - bytes.copy_from_slice(&img.pixels); + let expected = size[0].saturating_mul(size[1]).saturating_mul(4); + if expected == img.pixels.len() { + let pixels: Vec = bytemuck::cast_slice(&img.pixels).to_vec(); + egui::ColorImage::new(size, pixels) + } else { + egui::ColorImage::new(size, vec![egui::Color32::TRANSPARENT; size[0].saturating_mul(size[1])]) } - egui::ColorImage::new(size, pixels) } /// The pixels of the `w`×`h` frame through `view` to render again for `doc`, when only the document