Fix `stable_dt` (#3832)
This broke in https://github.com/emilk/egui/pull/3172 Since 0.24.1, `stable_dt` has been fixed at 1/60s, which is a little bit _too_ stable. The code issue was the logic for asking "Is this the result of an immeditate repaint?" was completely broken (always returning false). * Closes https://github.com/emilk/egui/issues/3830
This commit is contained in:
parent
9e924ec5f0
commit
42013cd6c2
|
|
@ -68,6 +68,28 @@ impl Default for WrappedTextureManager {
|
||||||
|
|
||||||
/// Repaint-logic
|
/// Repaint-logic
|
||||||
impl ContextImpl {
|
impl ContextImpl {
|
||||||
|
/// This is where we update the repaint logic.
|
||||||
|
fn begin_frame_repaint_logic(&mut self, viewport_id: ViewportId) {
|
||||||
|
let viewport = self.viewports.entry(viewport_id).or_default();
|
||||||
|
|
||||||
|
viewport.repaint.prev_frame_paint_delay = viewport.repaint.repaint_delay;
|
||||||
|
|
||||||
|
if viewport.repaint.outstanding == 0 {
|
||||||
|
// We are repainting now, so we can wait a while for the next repaint.
|
||||||
|
viewport.repaint.repaint_delay = Duration::MAX;
|
||||||
|
} else {
|
||||||
|
viewport.repaint.repaint_delay = Duration::ZERO;
|
||||||
|
viewport.repaint.outstanding -= 1;
|
||||||
|
if let Some(callback) = &self.request_repaint_callback {
|
||||||
|
(callback)(RequestRepaintInfo {
|
||||||
|
viewport_id,
|
||||||
|
delay: Duration::ZERO,
|
||||||
|
current_frame_nr: viewport.repaint.frame_nr,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn request_repaint(&mut self, viewport_id: ViewportId) {
|
fn request_repaint(&mut self, viewport_id: ViewportId) {
|
||||||
self.request_repaint_after(Duration::ZERO, viewport_id);
|
self.request_repaint_after(Duration::ZERO, viewport_id);
|
||||||
}
|
}
|
||||||
|
|
@ -79,13 +101,13 @@ impl ContextImpl {
|
||||||
// This solves some corner-cases of missing repaints on frame-delayed responses.
|
// This solves some corner-cases of missing repaints on frame-delayed responses.
|
||||||
viewport.repaint.outstanding = 1;
|
viewport.repaint.outstanding = 1;
|
||||||
|
|
||||||
if let Some(callback) = &self.request_repaint_callback {
|
// We save some CPU time by only calling the callback if we need to.
|
||||||
// We save some CPU time by only calling the callback if we need to.
|
// If the new delay is greater or equal to the previous lowest,
|
||||||
// If the new delay is greater or equal to the previous lowest,
|
// it means we have already called the callback, and don't need to do it again.
|
||||||
// it means we have already called the callback, and don't need to do it again.
|
if delay < viewport.repaint.repaint_delay {
|
||||||
if delay < viewport.repaint.repaint_delay {
|
viewport.repaint.repaint_delay = delay;
|
||||||
viewport.repaint.repaint_delay = delay;
|
|
||||||
|
|
||||||
|
if let Some(callback) = &self.request_repaint_callback {
|
||||||
(callback)(RequestRepaintInfo {
|
(callback)(RequestRepaintInfo {
|
||||||
viewport_id,
|
viewport_id,
|
||||||
delay,
|
delay,
|
||||||
|
|
@ -96,10 +118,10 @@ impl ContextImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
fn requested_repaint_last_frame(&self, viewport_id: &ViewportId) -> bool {
|
fn requested_immediate_repaint_prev_frame(&self, viewport_id: &ViewportId) -> bool {
|
||||||
self.viewports
|
self.viewports.get(viewport_id).map_or(false, |v| {
|
||||||
.get(viewport_id)
|
v.repaint.requested_immediate_repaint_prev_frame()
|
||||||
.map_or(false, |v| v.repaint.requested_last_frame)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
|
@ -178,8 +200,11 @@ struct ViewportRepaintInfo {
|
||||||
/// While positive, keep requesting repaints. Decrement at the start of each frame.
|
/// While positive, keep requesting repaints. Decrement at the start of each frame.
|
||||||
outstanding: u8,
|
outstanding: u8,
|
||||||
|
|
||||||
/// Did we?
|
/// What was the output of `repaint_delay` on the previous frame?
|
||||||
requested_last_frame: bool,
|
///
|
||||||
|
/// If this was zero, we are repaining as quickly as possible
|
||||||
|
/// (as far as we know).
|
||||||
|
prev_frame_paint_delay: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ViewportRepaintInfo {
|
impl Default for ViewportRepaintInfo {
|
||||||
|
|
@ -193,11 +218,17 @@ impl Default for ViewportRepaintInfo {
|
||||||
// Let's run a couple of frames at the start, because why not.
|
// Let's run a couple of frames at the start, because why not.
|
||||||
outstanding: 1,
|
outstanding: 1,
|
||||||
|
|
||||||
requested_last_frame: false,
|
prev_frame_paint_delay: Duration::MAX,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ViewportRepaintInfo {
|
||||||
|
pub fn requested_immediate_repaint_prev_frame(&self) -> bool {
|
||||||
|
self.prev_frame_paint_delay == Duration::ZERO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
|
|
@ -261,22 +292,10 @@ impl ContextImpl {
|
||||||
|
|
||||||
let is_outermost_viewport = self.viewport_stack.is_empty(); // not necessarily root, just outermost immediate viewport
|
let is_outermost_viewport = self.viewport_stack.is_empty(); // not necessarily root, just outermost immediate viewport
|
||||||
self.viewport_stack.push(ids);
|
self.viewport_stack.push(ids);
|
||||||
let viewport = self.viewports.entry(viewport_id).or_default();
|
|
||||||
|
|
||||||
if viewport.repaint.outstanding == 0 {
|
self.begin_frame_repaint_logic(viewport_id);
|
||||||
// We are repainting now, so we can wait a while for the next repaint.
|
|
||||||
viewport.repaint.repaint_delay = Duration::MAX;
|
let viewport = self.viewports.entry(viewport_id).or_default();
|
||||||
} else {
|
|
||||||
viewport.repaint.repaint_delay = Duration::ZERO;
|
|
||||||
viewport.repaint.outstanding -= 1;
|
|
||||||
if let Some(callback) = &self.request_repaint_callback {
|
|
||||||
(callback)(RequestRepaintInfo {
|
|
||||||
viewport_id,
|
|
||||||
delay: Duration::ZERO,
|
|
||||||
current_frame_nr: viewport.repaint.frame_nr,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_outermost_viewport {
|
if is_outermost_viewport {
|
||||||
if let Some(new_zoom_factor) = self.new_zoom_factor.take() {
|
if let Some(new_zoom_factor) = self.new_zoom_factor.take() {
|
||||||
|
|
@ -310,7 +329,7 @@ impl ContextImpl {
|
||||||
|
|
||||||
viewport.input = std::mem::take(&mut viewport.input).begin_frame(
|
viewport.input = std::mem::take(&mut viewport.input).begin_frame(
|
||||||
new_raw_input,
|
new_raw_input,
|
||||||
viewport.repaint.requested_last_frame,
|
viewport.repaint.requested_immediate_repaint_prev_frame(),
|
||||||
pixels_per_point,
|
pixels_per_point,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -1312,7 +1331,7 @@ impl Context {
|
||||||
/// Was a repaint requested last frame for the given viewport?
|
/// Was a repaint requested last frame for the given viewport?
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn requested_repaint_last_frame_for(&self, viewport_id: &ViewportId) -> bool {
|
pub fn requested_repaint_last_frame_for(&self, viewport_id: &ViewportId) -> bool {
|
||||||
self.read(|ctx| ctx.requested_repaint_last_frame(viewport_id))
|
self.read(|ctx| ctx.requested_immediate_repaint_prev_frame(viewport_id))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Has a repaint been requested for the current viewport?
|
/// Has a repaint been requested for the current viewport?
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ impl InputState {
|
||||||
pub fn begin_frame(
|
pub fn begin_frame(
|
||||||
mut self,
|
mut self,
|
||||||
mut new: RawInput,
|
mut new: RawInput,
|
||||||
requested_repaint_last_frame: bool,
|
requested_immediate_repaint_prev_frame: bool,
|
||||||
pixels_per_point: f32,
|
pixels_per_point: f32,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
|
|
@ -155,7 +155,7 @@ impl InputState {
|
||||||
let time = new.time.unwrap_or(self.time + new.predicted_dt as f64);
|
let time = new.time.unwrap_or(self.time + new.predicted_dt as f64);
|
||||||
let unstable_dt = (time - self.time) as f32;
|
let unstable_dt = (time - self.time) as f32;
|
||||||
|
|
||||||
let stable_dt = if requested_repaint_last_frame {
|
let stable_dt = if requested_immediate_repaint_prev_frame {
|
||||||
// we should have had a repaint straight away,
|
// we should have had a repaint straight away,
|
||||||
// so this should be trustable.
|
// so this should be trustable.
|
||||||
unstable_dt
|
unstable_dt
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue