mirror of
https://github.com/storytold/lightcraft.git
synced 2026-11-12 00:42:44 -06:00
M5.6: with a GPU, a slider drag's preview is drawn in the frame of the drag tick
A drag tick requested the loupe's draft and the frame ended; the draft, done in 1.5-3 ms on the GPU, was picked up at the start of the next frame, a frame after the slider moved. Now, in a drag, the loupe waits up to 40 % of a frame for its draft when the last loupe render took well under that (not with a render offload, nor zoomed in, where what changes on screen is the window's draft). A CPU render, which would only make the frame late, is not waited for. JobPool::wait waits for the next finished job, which try_recv then hands out; Renderer::poll's collection of finished jobs is split out so the wait can turn the draft into the texture. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
701f78ea2e
commit
c8f676252f
@@ -56,6 +56,8 @@ pub struct JobPool<S, R> {
|
||||
shared: Arc<Shared<S, R>>,
|
||||
tx: Sender<Done<S, R>>,
|
||||
rx: Receiver<Done<S, R>>,
|
||||
/// A finished job [`Self::wait`] took off the channel, handed out first by [`Self::try_recv`].
|
||||
early: Option<Done<S, R>>,
|
||||
#[cfg_attr(target_arch = "wasm32", allow(dead_code))]
|
||||
threads: usize,
|
||||
started: bool,
|
||||
@@ -82,6 +84,7 @@ impl<S: Copy + Eq + Hash + Send + 'static, R: Send + 'static> JobPool<S, R> {
|
||||
}),
|
||||
tx,
|
||||
rx,
|
||||
early: None,
|
||||
threads,
|
||||
started: false,
|
||||
seq: 0,
|
||||
@@ -210,8 +213,16 @@ impl<S: Copy + Eq + Hash + Send + 'static, R: Send + 'static> JobPool<S, R> {
|
||||
}
|
||||
|
||||
/// A finished job, if any.
|
||||
pub fn try_recv(&self) -> Option<Done<S, R>> {
|
||||
self.rx.try_recv().ok()
|
||||
pub fn try_recv(&mut self) -> Option<Done<S, R>> {
|
||||
self.early.take().or_else(|| self.rx.try_recv().ok())
|
||||
}
|
||||
|
||||
/// Wait up to `timeout` for a job to finish; whether one has (it is the next [`Self::try_recv`]).
|
||||
pub fn wait(&mut self, timeout: Duration) -> bool {
|
||||
if self.early.is_none() {
|
||||
self.early = self.rx.recv_timeout(timeout).ok();
|
||||
}
|
||||
self.early.is_some()
|
||||
}
|
||||
|
||||
/// Run up to `n` jobs on the calling thread (wasm, tests). Returns how many ran.
|
||||
|
||||
@@ -351,3 +351,16 @@ fn disk_cache_never_touches_foreign_files() {
|
||||
assert!(!disk::is_cache_file("01", "0123456789abcdef0123456789abcdef.jpg.bak"));
|
||||
let _ = std::fs::remove_dir_all(&dir);
|
||||
}
|
||||
|
||||
/// [`JobPool::wait`] returns once a job finishes, which [`JobPool::try_recv`] then hands out, or
|
||||
/// after the timeout.
|
||||
#[test]
|
||||
fn pool_wait_keeps_the_finished_job_for_try_recv() {
|
||||
let mut p: JobPool<u8, u8> = JobPool::new(1);
|
||||
assert!(!p.wait(std::time::Duration::from_millis(10)), "nothing runs");
|
||||
p.submit(1, 0, 1, Box::new(|| 7));
|
||||
assert!(p.wait(std::time::Duration::from_secs(10)));
|
||||
assert!(p.wait(std::time::Duration::ZERO), "kept until taken");
|
||||
assert_eq!(p.try_recv().map(|d| d.result), Some(7));
|
||||
assert!(p.try_recv().is_none());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user