Very minor performance improvements

This commit is contained in:
itsjunetime
2024-06-04 01:12:40 -06:00
parent 7e2d0d3bea
commit a86730b8da
7 changed files with 71 additions and 35 deletions
+5 -7
View File
@@ -1,10 +1,8 @@
use flume::{Receiver, SendError, Sender, TryRecvError};
use image::ImageFormat;
use itertools::Itertools;
use ratatui_image::{picker::Picker, protocol::Protocol, Resize};
use tokio::sync::mpsc::{
error::{SendError, TryRecvError},
UnboundedReceiver, UnboundedSender
};
use futures_util::stream::StreamExt;
use crate::renderer::{fill_default, PageInfo, RenderError};
@@ -23,8 +21,8 @@ pub enum ConverterMsg {
}
pub async fn run_conversion_loop(
sender: UnboundedSender<Result<ConvertedPage, RenderError>>,
mut receiver: UnboundedReceiver<ConverterMsg>,
sender: Sender<Result<ConvertedPage, RenderError>>,
receiver: Receiver<ConverterMsg>,
mut picker: Picker
) -> Result<(), SendError<Result<ConvertedPage, RenderError>>> {
let mut images = vec![];
@@ -119,7 +117,7 @@ pub async fn run_conversion_loop(
}
}
let Some(msg) = receiver.recv().await else {
let Some(msg) = receiver.stream().next().await else {
break;
};
+10 -6
View File
@@ -44,7 +44,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let file = std::env::args().nth(1).ok_or("Program requires a file to process")?;
let path = PathBuf::from_str(&file)?.canonicalize()?;
let (watch_tx, render_rx) = tokio::sync::mpsc::unbounded_channel();
//let (watch_tx, render_rx) = tokio::sync::mpsc::unbounded_channel();
let (watch_tx, render_rx) = flume::unbounded();
let tui_tx = watch_tx.clone();
// we need to call this outside the recommended_watcher call because if we call it inside, that
@@ -62,7 +63,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
watcher.watch(&path, RecursiveMode::NonRecursive)?;
let file_path = format!("file://{}", path.clone().into_os_string().to_string_lossy());
let (render_tx, mut tui_rx) = tokio::sync::mpsc::unbounded_channel();
let (render_tx, tui_rx) = flume::unbounded();
let mut window_size = window_size()?;
@@ -132,8 +133,8 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut ev_stream = crossterm::event::EventStream::new();
let (to_converter, from_main) = tokio::sync::mpsc::unbounded_channel();
let (to_main, mut from_converter) = tokio::sync::mpsc::unbounded_channel();
let (to_converter, from_main) = flume::unbounded();
let (to_main, from_converter) = flume::unbounded();
tokio::spawn(run_conversion_loop(to_main, from_main, picker));
@@ -163,6 +164,9 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut main_area = tui::Tui::main_layout(&term.get_frame());
tui_tx.send(RenderNotif::Area(main_area[1]))?;
let mut tui_rx = tui_rx.into_stream();
let mut from_converter = from_converter.into_stream();
loop {
let mut needs_redraw = tokio::select! {
// First we check if we have any keystrokes
@@ -186,7 +190,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}
},
Some(renderer_msg) = tui_rx.recv() => {
Some(renderer_msg) = tui_rx.next() => {
match renderer_msg {
Ok(RenderInfo::NumPages(num)) => {
tui.set_n_pages(num);
@@ -200,7 +204,7 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
}
true
}
Some(img_res) = from_converter.recv() => {
Some(img_res) = from_converter.next() => {
match img_res {
Ok(ConvertedPage { page, num, num_results }) => tui.page_ready(page, num, num_results),
Err(e) => tui.show_error(e),
+9 -11
View File
@@ -1,9 +1,9 @@
use cairo::{Antialias, Format};
use crossterm::terminal::WindowSize;
use flume::{Receiver, Sender, TryRecvError};
use itertools::Itertools;
use poppler::{Color, Document, FindFlags, Page, Rectangle, SelectionStyle};
use ratatui::layout::Rect;
use tokio::sync::mpsc::{error::TryRecvError, UnboundedReceiver, UnboundedSender};
pub enum RenderNotif {
Area(Rect),
@@ -61,15 +61,15 @@ pub fn fill_default<T: Default>(vec: &mut Vec<T>, size: usize) {
// we're done.
pub fn start_rendering(
path: String,
sender: UnboundedSender<Result<RenderInfo, RenderError>>,
mut receiver: UnboundedReceiver<RenderNotif>,
sender: Sender<Result<RenderInfo, RenderError>>,
receiver: Receiver<RenderNotif>,
size: WindowSize
) {
// first, wait 'til we get told what the current starting area is so that we can set it to
// know what to render to
let mut area;
loop {
if let RenderNotif::Area(r) = receiver.blocking_recv().unwrap() {
if let RenderNotif::Area(r) = receiver.recv().unwrap() {
area = r;
break;
}
@@ -231,7 +231,7 @@ pub fn start_rendering(
loop {
// This once returned None despite the main thing being still connected (I think, at
// last), so I'm just being safe here
let Some(msg) = receiver.blocking_recv() else {
let Ok(msg) = receiver.recv() else {
return;
};
handle_notif!(msg);
@@ -293,7 +293,7 @@ fn render_single_page(
let surface_height = p_height * scale_factor;
let surface = cairo::ImageSurface::create(
Format::ARgb32,
Format::Rgb16_565,
// No matter how big you make these arguments, the image will be drawn at the same
// size. So if you make them really big, the image will be drawn on a quarter of it. If
// you make them really small, the image will cover more than all of the surface.
@@ -306,9 +306,9 @@ fn render_single_page(
surface_height as i32
)
.map_err(|e| format!("Couldn't create ImageSurface: {e}"))?;
let ctx = cairo::Context::new(surface).map_err(|e| format!("Couldn't create Context: {e}"))?;
surface.set_device_scale(scale_factor, scale_factor);
ctx.scale(scale_factor, scale_factor);
let ctx = cairo::Context::new(surface).map_err(|e| format!("Couldn't create Context: {e}"))?;
// The default background color of PDFs (at least, I think) is white, so we need to set
// that as the background color, then paint, then render.
@@ -344,9 +344,7 @@ fn render_single_page(
}
}
ctx.scale(1. / scale_factor, 1. / scale_factor);
let mut img_data = Vec::new();
let mut img_data = Vec::with_capacity((surface_height * surface_width) as usize);
ctx.target()
.write_to_png(&mut img_data)
.map_err(|e| format!("Couldn't write surface to png: {e}"))?;