mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 06:10:06 -04:00
egui:
* now every viewport has his own frame_nr eframe: * some refactoring * now on Windows spinner will make the async viewport refresh, this problem was only for async viewport in Windows * problem found there are two redraw systems, one was broken now is fixed, the one that was broken on Linux X11 was not needed, but for Windows both are needed! 1: The egui repaint_callback system 2: The egui repaint_after from FullOutput
This commit is contained in:
@@ -42,7 +42,7 @@ pub enum UserEvent {
|
|||||||
/// A repaint is requested.
|
/// A repaint is requested.
|
||||||
RequestRepaint {
|
RequestRepaint {
|
||||||
/// What to repaint.
|
/// What to repaint.
|
||||||
id: ViewportId,
|
viewport_id: ViewportId,
|
||||||
|
|
||||||
/// When to repaint.
|
/// When to repaint.
|
||||||
when: Instant,
|
when: Instant,
|
||||||
@@ -91,7 +91,7 @@ enum EventResult {
|
|||||||
|
|
||||||
trait WinitApp {
|
trait WinitApp {
|
||||||
/// The current frame number, as reported by egui.
|
/// The current frame number, as reported by egui.
|
||||||
fn frame_nr(&self) -> u64;
|
fn frame_nr(&self, viewport_id: ViewportId) -> u64;
|
||||||
|
|
||||||
fn is_focused(&self, window_id: winit::window::WindowId) -> bool;
|
fn is_focused(&self, window_id: winit::window::WindowId) -> bool;
|
||||||
|
|
||||||
@@ -187,16 +187,6 @@ fn run_and_return(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform-dependent event handlers to workaround a winit bug
|
|
||||||
// See: https://github.com/rust-windowing/winit/issues/987
|
|
||||||
// See: https://github.com/rust-windowing/winit/issues/1619
|
|
||||||
// #[cfg(target_os = "windows")]
|
|
||||||
// winit::event::Event::RedrawEventsCleared => {
|
|
||||||
// windows_next_repaint_times.clear();
|
|
||||||
// winit_app.run_ui_and_paint(None)
|
|
||||||
// vec![EventResult::Wait]
|
|
||||||
// }
|
|
||||||
// #[cfg(not(target_os = "windows"))]
|
|
||||||
winit::event::Event::RedrawRequested(window_id) => {
|
winit::event::Event::RedrawRequested(window_id) => {
|
||||||
windows_next_repaint_times.remove(window_id);
|
windows_next_repaint_times.remove(window_id);
|
||||||
winit_app.run_ui_and_paint(*window_id)
|
winit_app.run_ui_and_paint(*window_id)
|
||||||
@@ -205,11 +195,11 @@ fn run_and_return(
|
|||||||
winit::event::Event::UserEvent(UserEvent::RequestRepaint {
|
winit::event::Event::UserEvent(UserEvent::RequestRepaint {
|
||||||
when,
|
when,
|
||||||
frame_nr,
|
frame_nr,
|
||||||
id: window_id,
|
viewport_id,
|
||||||
}) => {
|
}) => {
|
||||||
if winit_app.frame_nr() == *frame_nr {
|
if winit_app.frame_nr(*viewport_id) == *frame_nr + 1 {
|
||||||
log::trace!("UserEvent::RequestRepaint scheduling repaint at {when:?}");
|
log::trace!("UserEvent::RequestRepaint scheduling repaint at {when:?}");
|
||||||
if let Some(window_id) = winit_app.get_window_winit_id(*window_id) {
|
if let Some(window_id) = winit_app.get_window_winit_id(*viewport_id) {
|
||||||
vec![EventResult::RepaintAt(window_id, *when)]
|
vec![EventResult::RepaintAt(window_id, *when)]
|
||||||
} else {
|
} else {
|
||||||
vec![EventResult::Wait]
|
vec![EventResult::Wait]
|
||||||
@@ -287,13 +277,11 @@ fn run_and_return(
|
|||||||
for (window_id, repaint_time) in &windows_next_repaint_times.clone() {
|
for (window_id, repaint_time) in &windows_next_repaint_times.clone() {
|
||||||
if *repaint_time <= Instant::now() {
|
if *repaint_time <= Instant::now() {
|
||||||
if let Some(window) = winit_app.window(*window_id) {
|
if let Some(window) = winit_app.window(*window_id) {
|
||||||
|
log::trace!("request_redraw");
|
||||||
window.read().request_redraw();
|
window.read().request_redraw();
|
||||||
windows_next_repaint_times.remove(window_id);
|
|
||||||
control_flow.set_poll();
|
|
||||||
} else {
|
|
||||||
windows_next_repaint_times.remove(window_id);
|
|
||||||
control_flow.set_wait();
|
|
||||||
}
|
}
|
||||||
|
windows_next_repaint_times.remove(window_id);
|
||||||
|
control_flow.set_poll();
|
||||||
} else {
|
} else {
|
||||||
next_repaint_time =
|
next_repaint_time =
|
||||||
Some(next_repaint_time.map_or(*repaint_time, |last| last.min(*repaint_time)));
|
Some(next_repaint_time.map_or(*repaint_time, |last| last.min(*repaint_time)));
|
||||||
@@ -344,15 +332,7 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
|||||||
vec![EventResult::Exit]
|
vec![EventResult::Exit]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform-dependent event handlers to workaround a winit bug
|
winit::event::Event::RedrawRequested(window_id) => {
|
||||||
// See: https://github.com/rust-windowing/winit/issues/987
|
|
||||||
// See: https://github.com/rust-windowing/winit/issues/1619
|
|
||||||
winit::event::Event::RedrawEventsCleared if cfg!(target_os = "windows") => {
|
|
||||||
// windows_next_repaint_times.clear();
|
|
||||||
// winit_app.run_ui_and_paint(None)
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
winit::event::Event::RedrawRequested(window_id) if !cfg!(target_os = "windows") => {
|
|
||||||
windows_next_repaint_times.remove(&window_id);
|
windows_next_repaint_times.remove(&window_id);
|
||||||
winit_app.run_ui_and_paint(window_id)
|
winit_app.run_ui_and_paint(window_id)
|
||||||
}
|
}
|
||||||
@@ -360,10 +340,10 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
|||||||
winit::event::Event::UserEvent(UserEvent::RequestRepaint {
|
winit::event::Event::UserEvent(UserEvent::RequestRepaint {
|
||||||
when,
|
when,
|
||||||
frame_nr,
|
frame_nr,
|
||||||
id: window_id,
|
viewport_id,
|
||||||
}) => {
|
}) => {
|
||||||
if winit_app.frame_nr() == frame_nr {
|
if winit_app.frame_nr(viewport_id) == frame_nr + 1 {
|
||||||
if let Some(window_id) = winit_app.get_window_winit_id(window_id) {
|
if let Some(window_id) = winit_app.get_window_winit_id(viewport_id) {
|
||||||
vec![EventResult::RepaintAt(window_id, when)]
|
vec![EventResult::RepaintAt(window_id, when)]
|
||||||
} else {
|
} else {
|
||||||
vec![EventResult::Wait]
|
vec![EventResult::Wait]
|
||||||
@@ -425,8 +405,8 @@ fn run_and_exit(event_loop: EventLoop<UserEvent>, mut winit_app: impl WinitApp +
|
|||||||
if let Some(window) = winit_app.window(*window_id) {
|
if let Some(window) = winit_app.window(*window_id) {
|
||||||
log::trace!("request_redraw");
|
log::trace!("request_redraw");
|
||||||
window.read().request_redraw();
|
window.read().request_redraw();
|
||||||
windows_next_repaint_times.remove(window_id);
|
|
||||||
}
|
}
|
||||||
|
windows_next_repaint_times.remove(window_id);
|
||||||
control_flow.set_poll();
|
control_flow.set_poll();
|
||||||
} else {
|
} else {
|
||||||
next_repaint_time =
|
next_repaint_time =
|
||||||
@@ -1030,7 +1010,7 @@ mod glow_integration {
|
|||||||
event_loop_proxy
|
event_loop_proxy
|
||||||
.lock()
|
.lock()
|
||||||
.send_event(UserEvent::RequestRepaint {
|
.send_event(UserEvent::RequestRepaint {
|
||||||
id: info.viewport_id,
|
viewport_id: info.viewport_id,
|
||||||
when,
|
when,
|
||||||
frame_nr,
|
frame_nr,
|
||||||
})
|
})
|
||||||
@@ -1303,11 +1283,10 @@ mod glow_integration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WinitApp for GlowWinitApp {
|
impl WinitApp for GlowWinitApp {
|
||||||
fn frame_nr(&self) -> u64 {
|
fn frame_nr(&self, viewport_id: ViewportId) -> u64 {
|
||||||
self.running
|
self.running.read().as_ref().map_or(0, |r| {
|
||||||
.read()
|
r.integration.read().egui_ctx.frame_nr_for(viewport_id)
|
||||||
.as_ref()
|
})
|
||||||
.map_or(0, |r| r.integration.read().egui_ctx.frame_nr())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_focused(&self, window_id: winit::window::WindowId) -> bool {
|
fn is_focused(&self, window_id: winit::window::WindowId) -> bool {
|
||||||
@@ -2073,7 +2052,7 @@ mod wgpu_integration {
|
|||||||
.send_event(UserEvent::RequestRepaint {
|
.send_event(UserEvent::RequestRepaint {
|
||||||
when,
|
when,
|
||||||
frame_nr,
|
frame_nr,
|
||||||
id: info.viewport_id,
|
viewport_id: info.viewport_id,
|
||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
});
|
});
|
||||||
@@ -2249,10 +2228,10 @@ mod wgpu_integration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl WinitApp for WgpuWinitApp {
|
impl WinitApp for WgpuWinitApp {
|
||||||
fn frame_nr(&self) -> u64 {
|
fn frame_nr(&self, viewport_id: ViewportId) -> u64 {
|
||||||
self.running
|
self.running.as_ref().map_or(0, |r| {
|
||||||
.as_ref()
|
r.integration.read().egui_ctx.frame_nr_for(viewport_id)
|
||||||
.map_or(0, |r| r.integration.read().egui_ctx.frame_nr())
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_focused(&self, window_id: winit::window::WindowId) -> bool {
|
fn is_focused(&self, window_id: winit::window::WindowId) -> bool {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ struct Repaint {
|
|||||||
/// The current frame number.
|
/// The current frame number.
|
||||||
///
|
///
|
||||||
/// Incremented at the end of each frame.
|
/// Incremented at the end of each frame.
|
||||||
frame_nr: u64,
|
viewports_frame_nr: HashMap<ViewportId, u64>,
|
||||||
|
|
||||||
/// The duration backend will poll for new events, before forcing another egui update
|
/// The duration backend will poll for new events, before forcing another egui update
|
||||||
/// even if there's no new events.
|
/// even if there's no new events.
|
||||||
@@ -83,7 +83,7 @@ impl Default for Repaint {
|
|||||||
let mut repaint_requests = HashMap::default();
|
let mut repaint_requests = HashMap::default();
|
||||||
repaint_requests.insert(ViewportId::MAIN, 1);
|
repaint_requests.insert(ViewportId::MAIN, 1);
|
||||||
Self {
|
Self {
|
||||||
frame_nr: 0,
|
viewports_frame_nr: HashMap::default(),
|
||||||
repaint_after,
|
repaint_after,
|
||||||
repaint_requests,
|
repaint_requests,
|
||||||
request_repaint_callback: None,
|
request_repaint_callback: None,
|
||||||
@@ -118,7 +118,7 @@ impl Repaint {
|
|||||||
if let Some(callback) = &self.request_repaint_callback {
|
if let Some(callback) = &self.request_repaint_callback {
|
||||||
let info = RequestRepaintInfo {
|
let info = RequestRepaintInfo {
|
||||||
after,
|
after,
|
||||||
current_frame_nr: self.frame_nr,
|
current_frame_nr: *self.viewports_frame_nr.entry(viewport_id).or_default(),
|
||||||
viewport_id,
|
viewport_id,
|
||||||
};
|
};
|
||||||
(callback)(info);
|
(callback)(info);
|
||||||
@@ -160,9 +160,11 @@ impl Repaint {
|
|||||||
self.repaint_after.insert(viewport_id, repaint_after);
|
self.repaint_after.insert(viewport_id, repaint_after);
|
||||||
|
|
||||||
self.requested_repaint_last_frame = repaint_after.is_zero();
|
self.requested_repaint_last_frame = repaint_after.is_zero();
|
||||||
self.frame_nr += 1;
|
*self.viewports_frame_nr.entry(viewport_id).or_default() += 1;
|
||||||
|
|
||||||
self.repaint_after.retain(|id, _| viewports.contains(id));
|
self.repaint_after.retain(|id, _| viewports.contains(id));
|
||||||
|
self.viewports_frame_nr
|
||||||
|
.retain(|id, _| viewports.contains(id));
|
||||||
self.repaint_requests
|
self.repaint_requests
|
||||||
.retain(|id, repaints| viewports.contains(id) && *repaints != 0);
|
.retain(|id, repaints| viewports.contains(id) && *repaints != 0);
|
||||||
|
|
||||||
@@ -1150,13 +1152,28 @@ impl Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The current frame number.
|
/// The current frame number for the current viewport.
|
||||||
///
|
///
|
||||||
/// Starts at zero, and is incremented at the end of [`Self::run`] or by [`Self::end_frame`].
|
/// Starts at zero, and is incremented at the end of [`Self::run`] or by [`Self::end_frame`].
|
||||||
///
|
///
|
||||||
/// Between calls to [`Self::run`], this is the frame number of the coming frame.
|
/// Between calls to [`Self::run`], this is the frame number of the coming frame.
|
||||||
pub fn frame_nr(&self) -> u64 {
|
pub fn frame_nr(&self) -> u64 {
|
||||||
self.read(|ctx| ctx.repaint.frame_nr)
|
self.frame_nr_for(self.viewport_id())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The current frame number.
|
||||||
|
///
|
||||||
|
/// Starts at zero, and is incremented at the end of [`Self::run`] or by [`Self::end_frame`].
|
||||||
|
///
|
||||||
|
/// Between calls to [`Self::run`], this is the frame number of the coming frame.
|
||||||
|
pub fn frame_nr_for(&self, id: ViewportId) -> u64 {
|
||||||
|
self.read(|ctx| {
|
||||||
|
ctx.repaint
|
||||||
|
.viewports_frame_nr
|
||||||
|
.get(&id)
|
||||||
|
.copied()
|
||||||
|
.unwrap_or_default()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call this if there is need to repaint the UI, i.e. if you are showing an animation.
|
/// Call this if there is need to repaint the UI, i.e. if you are showing an animation.
|
||||||
@@ -1648,10 +1665,8 @@ impl Context {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let repaint_after = self.write(|ctx| {
|
let repaint_after =
|
||||||
ctx.repaint
|
self.write(|ctx| ctx.repaint.end_frame(viewport_id, &avalibile_viewports));
|
||||||
.end_frame(ctx.viewport_id(), &avalibile_viewports)
|
|
||||||
});
|
|
||||||
|
|
||||||
FullOutput {
|
FullOutput {
|
||||||
platform_output,
|
platform_output,
|
||||||
|
|||||||
Reference in New Issue
Block a user