gtauri: distance-from-viewport drop policy for ALL jobs
The backlog must never delay on-screen work. Urgent jobs (real Chromium requests) are now stale-dropped too, not just prefetch: a fast fling queues urgent work for every band it crosses, and all of it except the final band is dead — it filled the queue cap and made fresh on-screen requests wait for the JS retry timer. Safe because the anchor now settles at the final scroll position (trailing send), and on-screen cells have idx >= VPORT so they can never be dropped. A pure LIFO would not fix this: stale jobs sit at the stack bottom, never popped, still blocking the cap. Emulator fling test: 309 stale urgent jobs purged, queue peak 28, all 850 decodable images loaded.
This commit is contained in:
parent
02d1f097ac
commit
d990627200
|
|
@ -228,11 +228,13 @@ fn set_prefetch_window(lo: usize, hi: usize) {
|
|||
VPORT.store(lo as u32, Ordering::Relaxed);
|
||||
let mut q = Q.lock().unwrap();
|
||||
let mut inq = INFLIGHT.lock().unwrap();
|
||||
// Stale PREFETCH work (far behind the new viewport) is worthless — drop
|
||||
// it. URGENT jobs (real pending requests) are never dropped here.
|
||||
// The anchor just moved to `lo`: everything more than STALE_ROWS
|
||||
// behind it is dead work (urgent included — a fling leaves urgent
|
||||
// jobs for every band it crossed). Drop it instantly so it can never
|
||||
// delay the new viewport or eat queue capacity.
|
||||
let kept = q.len();
|
||||
q.retain(|j| {
|
||||
if j.urgent || j.idx + STALE_ROWS >= lo as u32 {
|
||||
if j.idx + STALE_ROWS >= lo as u32 {
|
||||
return true;
|
||||
}
|
||||
inq.remove(&j.id);
|
||||
|
|
@ -269,14 +271,21 @@ fn pop_next() -> Job {
|
|||
g = Q_CV.wait(g).unwrap();
|
||||
continue;
|
||||
}
|
||||
// Only PREFETCH work is droppable. URGENT jobs are real pending
|
||||
// requests (JS/Chromium is waiting on them) — even if the viewport
|
||||
// anchor went stale, they must run.
|
||||
// Distance-from-viewport policy: any job more than STALE_ROWS
|
||||
// behind the viewport is dead work — the user flung past it, and
|
||||
// decoding it would only delay what is actually on screen. This
|
||||
// applies to URGENT jobs too (a fling queues urgent work for every
|
||||
// band it crosses; all of it except the final band is stale). Safe
|
||||
// because the anchor now always settles at the final scroll
|
||||
// position (trailing send), and on-screen cells have idx >= VPORT
|
||||
// so they can never be dropped. (A pure LIFO would not solve this:
|
||||
// the stale pile sits at the stack bottom, never popped, still
|
||||
// blocking the queue cap.)
|
||||
if let Some(j) = g.front() {
|
||||
if !j.urgent && j.idx + STALE_ROWS < VPORT.load(Ordering::Relaxed) {
|
||||
if j.idx + STALE_ROWS < VPORT.load(Ordering::Relaxed) {
|
||||
let j = g.pop_front().unwrap();
|
||||
INFLIGHT.lock().unwrap().remove(&j.id);
|
||||
tr(&format!("drop stale id={} idx={}", j.id, j.idx));
|
||||
tr(&format!("drop stale id={} idx={} urgent={}", j.id, j.idx, j.urgent));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user