summaryrefslogtreecommitdiff
path: root/src/window.rs
diff options
context:
space:
mode:
authorBen Bridle <bridle.benjamin@gmail.com>2023-12-19 21:02:55 +1300
committerBen Bridle <bridle.benjamin@gmail.com>2023-12-19 21:17:35 +1300
commit68017c61c1ec1d0657f2e22f0d4044a955b84ccc (patch)
tree25863085b51768e6f67966fd4456ecf382241e8e /src/window.rs
parent1fb788cc09fa349957da501dd911435f1957c03a (diff)
downloadphosphor-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.rs49
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();