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 | |
| 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.
| -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(); | 
