From 0cc51481b28356ddc84100f5b3820f9402c25d11 Mon Sep 17 00:00:00 2001 From: Keith Simmons Date: Wed, 18 Dec 2019 17:09:41 -0800 Subject: [PATCH] Cache surface not image --- src/editor/mod.rs | 16 +++++++----- src/main.rs | 2 +- src/renderer/mod.rs | 60 ++++++++++++++++++++++----------------------- src/window.rs | 5 ---- 4 files changed, 41 insertions(+), 42 deletions(-) diff --git a/src/editor/mod.rs b/src/editor/mod.rs index 7c84af3..956ff27 100644 --- a/src/editor/mod.rs +++ b/src/editor/mod.rs @@ -20,6 +20,7 @@ pub struct DrawCommand { pub struct Editor { pub grid: Vec>, pub dirty: Vec>, + pub should_clear: bool, pub title: String, pub size: (u64, u64), pub cursor: Cursor, @@ -33,6 +34,7 @@ impl Editor { let mut editor = Editor { grid: Vec::new(), dirty: Vec::new(), + should_clear: true, title: "Neovide".to_string(), cursor: Cursor::new(), size: (width, height), @@ -62,9 +64,9 @@ impl Editor { } } - pub fn build_draw_commands(&mut self) -> Vec { - let commands = self.grid.iter().enumerate().map(|(row_index, row)| { - let mut draw_commands = Vec::new(); + pub fn build_draw_commands(&mut self) -> (Vec, bool) { + let mut draw_commands = Vec::new(); + for (row_index, row) in self.grid.iter().enumerate() { let mut command = None; fn add_command(commands_list: &mut Vec, command: Option) { @@ -104,12 +106,13 @@ impl Editor { } } add_command(&mut draw_commands, command); + } + let should_clear = self.should_clear; - draw_commands - }).flatten().collect(); let (width, height) = self.size; self.dirty = vec![vec![false; width as usize]; height as usize]; - commands + self.should_clear = false; + (draw_commands, should_clear) } fn draw_grid_line_cell(&mut self, row_index: u64, column_pos: &mut u64, cell: GridLineCell) { @@ -159,6 +162,7 @@ impl Editor { let (width, height) = self.size; self.grid = vec![vec![None; width as usize]; height as usize]; self.dirty = vec![vec![true; width as usize]; height as usize]; + self.should_clear = true; } fn scroll_region(&mut self, top: u64, bot: u64, left: u64, right: u64, rows: i64, cols: i64) { diff --git a/src/main.rs b/src/main.rs index e45cc3d..495df74 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -#![windows_subsystem = "windows"] +// #![windows_subsystem = "windows"] mod editor; mod events; diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 4b4fc39..6f5183e 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -17,7 +17,7 @@ const FONT_SIZE: f32 = 14.0; pub struct Renderer { editor: Arc>, - image: Option, + surface: Option, paint: Paint, font: Font, shaper: CachingShaper, @@ -31,7 +31,7 @@ pub struct Renderer { impl Renderer { pub fn new(editor: Arc>) -> Renderer { - let image = None; + let surface = None; let paint = Paint::new(colors::WHITE, None); let typeface = Typeface::new(FONT_NAME, FontStyle::default()).expect("Could not load font file."); let font = Font::from_typeface(typeface, FONT_SIZE); @@ -45,7 +45,7 @@ impl Renderer { let fps_tracker = FpsTracker::new(); - Renderer { editor, image, paint, font, shaper, font_width, font_height, cursor_pos, fps_tracker } + Renderer { editor, surface, paint, font, shaper, font_width, font_height, cursor_pos, fps_tracker } } fn draw_background(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors) { @@ -59,7 +59,7 @@ impl Renderer { canvas.draw_rect(region, &self.paint); } - fn draw_foreground(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors, update_cache: bool) { + fn draw_foreground(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors) { let (grid_x, grid_y) = grid_pos; let x = grid_x as f32 * self.font_width; let y = grid_y as f32 * self.font_height; @@ -76,24 +76,18 @@ impl Renderer { self.paint.set_color(style.foreground(&default_colors).to_color()); let text = text.trim_end(); if text.len() > 0 { - let reference; - let blob = if update_cache { - self.shaper.shape_cached(text.to_string(), &self.font) - } else { - reference = self.shaper.shape(text, &self.font); - &reference - }; + let blob = self.shaper.shape_cached(text.to_string(), &self.font); canvas.draw_text_blob(blob, (x, y), &self.paint); } } - fn draw_text(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors, update_cache: bool) { + fn draw_text(&mut self, canvas: &mut Canvas, text: &str, grid_pos: (u64, u64), style: &Style, default_colors: &Colors) { self.draw_background(canvas, text, grid_pos, style, default_colors); - self.draw_foreground(canvas, text, grid_pos, style, default_colors, update_cache); + self.draw_foreground(canvas, text, grid_pos, style, default_colors); } pub fn draw(&mut self, gpu_canvas: &mut Canvas, coordinate_system_helper: &CoordinateSystemHelper) { - let (draw_commands, default_colors, (width, height), cursor) = { + let ((draw_commands, should_clear), default_colors, (width, height), cursor) = { let mut editor = self.editor.lock().unwrap(); ( editor.build_draw_commands(), @@ -103,38 +97,44 @@ impl Renderer { ) }; - let mut context = gpu_canvas.gpu_context().unwrap(); - let budgeted = Budgeted::YES; - let image_info = gpu_canvas.image_info(); - let surface_origin = SurfaceOrigin::TopLeft; - let mut surface = Surface::new_render_target(&mut context, budgeted, &image_info, None, surface_origin, None, None).expect("Could not create surface"); - let mut canvas = surface.canvas(); - coordinate_system_helper.use_logical_coordinates(&mut canvas); + if should_clear { + self.surface = None; + } - if let Some(image) = self.image.as_ref() { - canvas.draw_image(image, (0, 0), Some(&self.paint)); - } else { + let mut surface = self.surface.take().unwrap_or_else(|| { + dbg!("rebuild surface"); + let mut context = gpu_canvas.gpu_context().unwrap(); + let budgeted = Budgeted::YES; + let image_info = gpu_canvas.image_info(); + let surface_origin = SurfaceOrigin::TopLeft; + let mut surface = Surface::new_render_target(&mut context, budgeted, &image_info, None, surface_origin, None, None).expect("Could not create surface"); + let canvas = surface.canvas(); canvas.clear(default_colors.background.clone().unwrap().to_color()); - } + surface + }); + + let mut canvas = surface.canvas(); + coordinate_system_helper.use_logical_coordinates(&mut canvas); for command in draw_commands.iter() { - self.draw_background(canvas, &command.text, command.grid_position.clone(), &command.style, &default_colors); + self.draw_background(&mut canvas, &command.text, command.grid_position.clone(), &command.style, &default_colors); } for command in draw_commands { - self.draw_foreground(canvas, &command.text, command.grid_position.clone(), &command.style, &default_colors, true); + self.draw_foreground(&mut canvas, &command.text, command.grid_position.clone(), &command.style, &default_colors); } self.fps_tracker.record_frame(); - self.draw_text(canvas, &self.fps_tracker.fps.to_string(), (width - 2, height - 1), &Style::new(default_colors.clone()), &default_colors, false); + self.draw_text(canvas, &self.fps_tracker.fps.to_string(), (width - 2, height - 1), &Style::new(default_colors.clone()), &default_colors); let (cursor_grid_x, cursor_grid_y) = cursor.position; let target_cursor_x = cursor_grid_x as f32 * self.font_width; let target_cursor_y = cursor_grid_y as f32 * self.font_height; let (previous_cursor_x, previous_cursor_y) = self.cursor_pos; - self.image = Some(surface.image_snapshot()); coordinate_system_helper.use_physical_coordinates(gpu_canvas); - gpu_canvas.draw_image(self.image.as_ref().unwrap(), (0, 0), Some(&self.paint)); + gpu_canvas.draw_image(surface.image_snapshot(), (0, 0), Some(&self.paint)); + + self.surface = Some(surface); let cursor_x = (target_cursor_x - previous_cursor_x) * 0.5 + previous_cursor_x; let cursor_y = (target_cursor_y - previous_cursor_y) * 0.5 + previous_cursor_y; diff --git a/src/window.rs b/src/window.rs index 431f4a2..9499685 100644 --- a/src/window.rs +++ b/src/window.rs @@ -133,11 +133,6 @@ pub fn ui_loop(editor: Arc>, nvim: Neovim, initial_size: (u64, u64 event: WindowEvent::RedrawRequested, .. } => { - { - let editor = editor.lock().unwrap(); - window.set_title(&editor.title); - }; - if let Err(e) = skulpin_renderer.draw(&window, |canvas, coordinate_system_helper| { renderer.draw(canvas, coordinate_system_helper); }) {