-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make request_repaint_after
actually respect the delay
#3925
Conversation
The branch that sets the repaint_delay to MAX was previously never actually taken, causing the repaint_delay to never be reset to MAX. This in turn effectively turn request_repaint_after into being equivalent to simply calling request_repaint, because the former only updates the repaint_time if it is shorter than the previous value.
3402b06
to
58db3a8
Compare
@@ -113,13 +113,13 @@ impl ContextImpl { | |||
let viewport = self.viewports.entry(viewport_id).or_default(); | |||
|
|||
viewport.repaint.prev_frame_paint_delay = viewport.repaint.repaint_delay; | |||
viewport.repaint.outstanding = viewport.repaint.outstanding.saturating_sub(1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The point of outstanding
it to run two refreshes on request_repaint
, and on startup, but with this PR that is now ignored.
That said, thanks to #3930 we might not need that "repaint twice" logic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah okay, I didn't realize that you actually wanted two invocations. It does make sense though, as it serves as a simple form of resilience against all kinds of "frame updates stuff and then expects it to show up on screen soon" -- let's try to keep that.
Note however that the previous logic didn't actually work: the == 0
branch was previously never taken at all, because begin_frame_repaint_logic
isn't ever actually called once outstanding
reached 0. You can verify this by throwing in a breakpoint or panic!()
.
Would it make sense to move the decrement as suggested in this PR and then simply explicitly set outstanding
to 2 in both the constructor and request_repaint
? I believe that this would also convey the intention of redrawing twice more clearly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah okay, I didn't realize that you actually wanted two invocations. It does make sense though, as it serves as a simple form of resilience against all kinds of "frame updates stuff and then expects it to show up on screen soon"
Exactly. It's a guard-rail, that's is nice to have. I'm not sure it is actually needed for anything (I'm turning it off now and testing, and nothing is obviously broken). Especially with #3930 merged the need should be smaller.
If you go to the backend panel of egui_demo_app
there is a simple test for some of this:
Clicking that button once will produce exactly 2 frames to be repainted after a five second delay, so it's not all broken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm yeah, true. If you just call request_repaint_after
once, it is working as intended. However, if you call it on every frame (like my sample code / diff does) in order to request a redraw e.g. at least once per second, it falls over because outstanding == 0
is never reached.
…nt (emilk#3978) * Closes emilk#3925 * Closes emilk#3109
I noticed that
request_repaint_after
currently doesn't actually work as promised and causes redraws in a busy-loop, akin to just usingrequest_repaint
. I debugged into it a bit and believe that I found both the problem and a solution.The branch that resets the repaint_delay to MAX was previously never actually taken, causing the repaint_delay to never be reset to MAX. This in turn effectively turned request_repaint_after into being equivalent to simply calling request_repaint, because the former only updates the repaint_time if it is shorter than the previous value:
egui/crates/egui/src/context.rs
Lines 147 to 148 in d72f92c
Testing
Here's a patch that I used for testing these changes: