Cache surface not image

macos-click-through
Keith Simmons 5 years ago
parent 84648518dc
commit 0cc51481b2

@ -20,6 +20,7 @@ pub struct DrawCommand {
pub struct Editor {
pub grid: Vec<Vec<GridCell>>,
pub dirty: Vec<Vec<bool>>,
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<DrawCommand> {
let commands = self.grid.iter().enumerate().map(|(row_index, row)| {
let mut draw_commands = Vec::new();
pub fn build_draw_commands(&mut self) -> (Vec<DrawCommand>, 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<DrawCommand>, command: Option<DrawCommand>) {
@ -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) {

@ -1,4 +1,4 @@
#![windows_subsystem = "windows"]
// #![windows_subsystem = "windows"]
mod editor;
mod events;

@ -17,7 +17,7 @@ const FONT_SIZE: f32 = 14.0;
pub struct Renderer {
editor: Arc<Mutex<Editor>>,
image: Option<Image>,
surface: Option<Surface>,
paint: Paint,
font: Font,
shaper: CachingShaper,
@ -31,7 +31,7 @@ pub struct Renderer {
impl Renderer {
pub fn new(editor: Arc<Mutex<Editor>>) -> 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;

@ -133,11 +133,6 @@ pub fn ui_loop(editor: Arc<Mutex<Editor>>, 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);
}) {

Loading…
Cancel
Save