diff options
author | Ben Bridle <bridle.benjamin@gmail.com> | 2023-12-19 21:02:55 +1300 |
---|---|---|
committer | Ben Bridle <bridle.benjamin@gmail.com> | 2023-12-19 21:17:35 +1300 |
commit | 68017c61c1ec1d0657f2e22f0d4044a955b84ccc (patch) | |
tree | 25863085b51768e6f67966fd4456ecf382241e8e /src/window.rs | |
parent | 1fb788cc09fa349957da501dd911435f1957c03a (diff) | |
download | phosphor-68017c61c1ec1d0657f2e22f0d4044a955b84ccc.zip |
Make window rendering code more efficient
The code to scale the window buffer and draw it to the window surface
has been made more efficient through the use of slice::copy_from_within
and slice::fill, instead of what was slow pixel-by-pixel iteration over
long horizontal strips.
Diffstat (limited to 'src/window.rs')
-rw-r--r-- | src/window.rs | 49 |
1 files changed, 25 insertions, 24 deletions
diff --git a/src/window.rs b/src/window.rs index fcb5b2a..b01795e 100644 --- a/src/window.rs +++ b/src/window.rs @@ -152,47 +152,48 @@ impl Window { if self.surface_dimensions.is_zero() { return; } - - let pixel_scale = self.pixel_scale; + let scale = self.pixel_scale as usize; let physical_dim = self.surface_dimensions; let logical_dim = self.buffer.dimensions(); self.controller.on_render(&mut self.buffer, self.current_render_hint); let buffer = self.buffer.as_u32_slice(); let mut surface = self.surface.buffer_mut().unwrap(); - if self.pixel_scale == 1 { + if scale == 1 { let overlap = std::cmp::min(buffer.len(), surface.len()); surface[..overlap].copy_from_slice(&buffer[..overlap]); } else { - let logical_content_width = logical_dim.width as usize; - let physical_content_width = (logical_dim.width * pixel_scale) as usize; - let row_excess = (physical_dim.width as usize).saturating_sub(physical_content_width); + let logical_width = logical_dim.width as usize; + let logical_height = logical_dim.height as usize; + let physical_width = physical_dim.width as usize; + let physical_content_width = logical_dim.width as usize * scale; + let row_excess = physical_width.saturating_sub(physical_content_width); let mut bi: usize = 0; let mut si: usize = 0; - for _y in 0..logical_dim.height { - for _py in 0..pixel_scale { - for _x in 0..logical_dim.width { - for _px in 0..pixel_scale { - surface[si] = buffer[bi]; - si += 1; + let mut row_start: usize = 0; + let mut row_end: usize = 0; + for _y in 0..logical_height { + for py in 0..scale { + if py == 0 { + row_start = si; + for _x in 0..logical_width { + surface[si..si+scale].fill(buffer[bi]); + si += scale; + bi += 1; } - bi += 1; - } - // Fill the excess space on the right edge with black. - for _ in 0..row_excess { - surface[si] = 0; - si += 1; + // Fill the excess space on the right edge with black. + surface[si..si+row_excess].fill(0); + si += row_excess; + row_end = si; + } else { + surface.copy_within(row_start..row_end, si); + si += physical_width; } - bi -= logical_content_width; } - bi += logical_content_width; } // Fill the excess space on the bottom edge with black. let excess = surface.len().saturating_sub(si); - for _ in 0..excess { - surface[si] = 0; - si += 1; - } + surface[si..si+excess].fill(0); } surface.present().unwrap(); |