T12: disarm visible-content gate on software path after first real frame
This commit is contained in:
@@ -128,6 +128,10 @@ fn handle_request(
|
|||||||
session.scroll_x = 0;
|
session.scroll_x = 0;
|
||||||
session.scroll_y = 0;
|
session.scroll_y = 0;
|
||||||
session.awaiting_visible_frame = true;
|
session.awaiting_visible_frame = true;
|
||||||
|
// New URL: the previous tab's pixels are no longer
|
||||||
|
// valid evidence that "we have visible content"; let
|
||||||
|
// the gate skip blank loading frames again.
|
||||||
|
session.ever_visible_frame = false;
|
||||||
}
|
}
|
||||||
if apply_input(
|
if apply_input(
|
||||||
host,
|
host,
|
||||||
@@ -417,9 +421,18 @@ fn poll_frame(
|
|||||||
// already encodes "Servo finished painting" — trust it
|
// already encodes "Servo finished painting" — trust it
|
||||||
// for the hardware path instead of double-checking via a
|
// for the hardware path instead of double-checking via a
|
||||||
// readback we know to be unreliable.
|
// readback we know to be unreliable.
|
||||||
|
//
|
||||||
|
// For the software path, the threshold check is only
|
||||||
|
// useful once per URL: after we've confirmed at least one
|
||||||
|
// paint had real content, every subsequent input deserves
|
||||||
|
// an immediate return on the next pending frame instead
|
||||||
|
// of another 250 ms wait. `session.ever_visible_frame`
|
||||||
|
// tracks that, reset on navigate.
|
||||||
let has_visible_content = match rendering_context_kind {
|
let has_visible_content = match rendering_context_kind {
|
||||||
RenderingContextKind::Software => {
|
RenderingContextKind::Software => {
|
||||||
frame.non_white_pixel_count() > 0 && frame.content_pixel_count() > 0
|
session.ever_visible_frame
|
||||||
|
|| (frame.non_white_pixel_count() > 0
|
||||||
|
&& frame.content_pixel_count() > 0)
|
||||||
}
|
}
|
||||||
#[cfg(feature = "hardware-render")]
|
#[cfg(feature = "hardware-render")]
|
||||||
RenderingContextKind::Hardware => true,
|
RenderingContextKind::Hardware => true,
|
||||||
@@ -434,6 +447,7 @@ fn poll_frame(
|
|||||||
let outcome = LiveOutcome::from_frame(report, frame, timings);
|
let outcome = LiveOutcome::from_frame(report, frame, timings);
|
||||||
if has_visible_content {
|
if has_visible_content {
|
||||||
session.awaiting_visible_frame = false;
|
session.awaiting_visible_frame = false;
|
||||||
|
session.ever_visible_frame = true;
|
||||||
return Ok(outcome);
|
return Ok(outcome);
|
||||||
}
|
}
|
||||||
if !session.awaiting_visible_frame {
|
if !session.awaiting_visible_frame {
|
||||||
@@ -463,6 +477,16 @@ struct LiveSession {
|
|||||||
scroll_x: i32,
|
scroll_x: i32,
|
||||||
scroll_y: i32,
|
scroll_y: i32,
|
||||||
awaiting_visible_frame: bool,
|
awaiting_visible_frame: bool,
|
||||||
|
/// Sticky for the lifetime of a single URL: flipped to `true`
|
||||||
|
/// the first time `poll_frame` sees a paint with real content
|
||||||
|
/// (non-white, non-empty) and reset to `false` on every navigate.
|
||||||
|
/// After it's `true`, the visible-content gate stops gating —
|
||||||
|
/// scroll/click/hover/type all return on the first
|
||||||
|
/// `has_pending_frame=true` (~3 ms) instead of waiting the full
|
||||||
|
/// `LIVE_FRAME_WAIT_TIMEOUT`. The gate stays armed for the
|
||||||
|
/// initial paint of each new URL so loading frames are still
|
||||||
|
/// skipped.
|
||||||
|
ever_visible_frame: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LiveSession {
|
impl LiveSession {
|
||||||
@@ -476,6 +500,7 @@ impl LiveSession {
|
|||||||
scroll_x: 0,
|
scroll_x: 0,
|
||||||
scroll_y: 0,
|
scroll_y: 0,
|
||||||
awaiting_visible_frame: false,
|
awaiting_visible_frame: false,
|
||||||
|
ever_visible_frame: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user