Skip to content

Commit

Permalink
Update wgpu_integration.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
rustbasic authored Jun 29, 2024
1 parent 956ff54 commit 4d0bbcd
Showing 1 changed file with 120 additions and 85 deletions.
205 changes: 120 additions & 85 deletions crates/eframe/src/native/wgpu_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,8 @@ impl WgpuWinitApp {

egui_ctx.set_request_repaint_callback(move |info| {
log::trace!("request_repaint_callback: {info:?}");
let when = Instant::now() + info.delay;
// let when = Instant::now() + info.delay;
let when = Instant::now();
let frame_nr = info.current_frame_nr;

event_loop_proxy
Expand Down Expand Up @@ -317,9 +318,20 @@ impl WgpuWinitApp {
// SAFETY: the event loop lives longer than
// the Rc:s we just upgraded above.
#[allow(unsafe_code)]
if let Some(event_loop) = unsafe { event_loop.as_ref() } {
render_immediate_viewport(
event_loop,
beginning,
&shared,
immediate_viewport,
);
}
/*
#[allow(unsafe_code)]
let event_loop = unsafe { event_loop.as_ref().unwrap() };
render_immediate_viewport(event_loop, beginning, &shared, immediate_viewport);
*/
} else {
log::warn!("render_sync_callback called after window closed");
}
Expand Down Expand Up @@ -464,7 +476,7 @@ impl WinitApp for WgpuWinitApp {
}

if let Some(window) = viewport.window.as_ref() {
EventResult::RepaintNext(window.id())
EventResult::RepaintNow(window.id())
} else {
EventResult::Wait
}
Expand Down Expand Up @@ -502,6 +514,7 @@ impl WinitApp for WgpuWinitApp {
EventResult::Wait
}
}

_ => EventResult::Wait,
})
}
Expand Down Expand Up @@ -529,7 +542,7 @@ impl WgpuWinitRunning {
fn run_ui_and_paint(&mut self, window_id: WindowId) -> EventResult {
crate::profile_function!();

let Some(viewport_id) = self
let Some(mut viewport_id) = self
.shared
.borrow()
.viewport_from_window
Expand Down Expand Up @@ -559,20 +572,19 @@ impl WgpuWinitRunning {
viewports, painter, ..
} = &mut *shared_lock;

if viewport_id != ViewportId::ROOT {
let Some(viewport) = viewports.get(&viewport_id) else {
let Some(original_viewport) = viewports.get(&viewport_id) else {
return EventResult::Wait;
};

if original_viewport.class == ViewportClass::Immediate {
let Some(parent_viewport) = viewports.get(&original_viewport.ids.parent) else {
return EventResult::Wait;
};

if viewport.viewport_ui_cb.is_none() {
// This will only happen if this is an immediate viewport.
// That means that the viewport cannot be rendered by itself and needs his parent to be rendered.
if let Some(viewport) = viewports.get(&viewport.ids.parent) {
if let Some(window) = viewport.window.as_ref() {
return EventResult::RepaintNext(window.id());
}
}
return EventResult::Wait;
if parent_viewport.class == ViewportClass::Deferred {
viewport_id = parent_viewport.ids.this;
} else {
viewport_id = ViewportId::ROOT;
}
}

Expand Down Expand Up @@ -663,8 +675,6 @@ impl WgpuWinitRunning {
return EventResult::Wait;
};

egui_winit.handle_platform_output(window, platform_output);

let clipped_primitives = egui_ctx.tessellate(shapes, pixels_per_point);

let screenshot_requested = viewport
Expand Down Expand Up @@ -716,7 +726,7 @@ impl WgpuWinitRunning {

integration.post_rendering(window);

let active_viewports_ids: ViewportIdSet = viewport_output.keys().copied().collect();
egui_winit.handle_platform_output(window, platform_output);

handle_viewport_output(
&integration.egui_ctx,
Expand All @@ -726,11 +736,6 @@ impl WgpuWinitRunning {
viewport_from_window,
);

// Prune dead viewports:
viewports.retain(|id, _| active_viewports_ids.contains(id));
viewport_from_window.retain(|_, id| active_viewports_ids.contains(id));
painter.gc_viewports(&active_viewports_ids);

let window = viewport_from_window
.get(&window_id)
.and_then(|id| viewports.get(id))
Expand All @@ -740,20 +745,23 @@ impl WgpuWinitRunning {

integration.maybe_autosave(app.as_mut(), window.map(|w| w.as_ref()));

if let Some(window) = window {
if window.is_minimized() == Some(true) {
// On Mac, a minimized Window uses up all CPU:
// https://github.com/emilk/egui/issues/325
crate::profile_scope!("minimized_sleep");
std::thread::sleep(std::time::Duration::from_millis(10));
let is_windows = cfg!(target_os = "windows");
if !is_windows {
if let Some(window) = window {
let is_minimized = window.is_minimized().unwrap_or(false);
if !is_minimized {
// On Mac, a minimized Window uses up all CPU:
// https://github.com/emilk/egui/issues/325
crate::profile_scope!("minimized_sleep");
std::thread::sleep(std::time::Duration::from_millis(10));
}
}
}

if integration.should_close() {
EventResult::Exit
} else {
EventResult::Wait
}
// When we press the Close button on the Title Bar, `WindowEvent::CloseRequested` occurs,
// Select whether to use `ViewportCommand::CancelClose` or `ViewportCommand::Close`.
// If `ViewportCommand::Close` is sent, it is processed here after being handled in `process_viewport_command()`.
handle_viewport_close(&viewports, painter, window_id, viewport_id)
}

fn on_window_event(
Expand All @@ -768,65 +776,61 @@ impl WgpuWinitRunning {
shared,
..
} = self;
let mut shared = shared.borrow_mut();

let viewport_id = shared.viewport_from_window.get(&window_id).copied();

// On Windows, if a window is resized by the user, it should repaint synchronously, inside the
// event handler.
//
// If this is not done, the compositor will assume that the window does not want to redraw,
// and continue ahead.
//
// In eframe's case, that causes the window to rapidly flicker, as it struggles to deliver
// new frames to the compositor in time.
//
// The flickering is technically glutin or glow's fault, but we should be responding properly
// to resizes anyway, as doing so avoids dropping frames.
//
// See: https://github.com/emilk/egui/issues/903
let mut repaint_asap = false;
let mut shared_mut = shared.borrow_mut();
let SharedState {
viewports,
painter,
viewport_from_window,
..
} = &mut *shared_mut;

let viewport_id = viewport_from_window.get(&window_id).copied();

match event {
winit::event::WindowEvent::Focused(new_focused) => {
shared.focused_viewport = new_focused.then(|| viewport_id).flatten();
shared_mut.focused_viewport = new_focused.then(|| viewport_id).flatten();
}

winit::event::WindowEvent::Resized(physical_size) => {
// Resize with 0 width and height is used by winit to signal a minimize event on Windows.
// See: https://github.com/rust-windowing/winit/issues/208
// This solves an issue where the app would panic when minimizing on Windows.
if let Some(viewport_id) = viewport_id {
if let (Some(width), Some(height)) = (
NonZeroU32::new(physical_size.width),
NonZeroU32::new(physical_size.height),
) {
repaint_asap = true;
shared.painter.on_window_resized(viewport_id, width, height);
shared_mut
.painter
.on_window_resized(viewport_id, width, height);
return EventResult::RepaintNext(window_id);
}
}
}

winit::event::WindowEvent::CloseRequested => {
if viewport_id == Some(ViewportId::ROOT) && integration.should_close() {
log::debug!(
"Received WindowEvent::CloseRequested for main viewport - shutting down."
);
return EventResult::Exit;
}

log::debug!("Received WindowEvent::CloseRequested for viewport {viewport_id:?}");

if let Some(viewport_id) = viewport_id {
if let Some(viewport) = shared.viewports.get_mut(&viewport_id) {
if let Some(viewport) = viewports.get_mut(&viewport_id) {
// Tell viewport it should close:
viewport.info.close_requested_on();
viewport.info.events.push(egui::ViewportEvent::Close);

// We may need to repaint both us and our parent to close the window,
// and perhaps twice (once to notice the close-event, once again to enforce it).
// `request_repaint_of` does a double-repaint though:
integration.egui_ctx.request_repaint_of(viewport_id);
integration.egui_ctx.request_repaint_of(viewport.ids.parent);
if viewport_id != ViewportId::ROOT {
self.integration
.egui_ctx
.request_repaint_of(viewport.ids.parent);
if viewport.ids.parent != ViewportId::ROOT {
self.integration
.egui_ctx
.request_repaint_of(ViewportId::ROOT);
}
}

// If `close_cancelable` is `false`, `ViewportCommand::CancelClose` is not possible, it is processed here.
return handle_viewport_close(&viewports, painter, window_id, viewport_id);
}
}
}
Expand All @@ -836,24 +840,21 @@ impl WgpuWinitRunning {

let event_response = viewport_id
.and_then(|viewport_id| {
shared.viewports.get_mut(&viewport_id).and_then(|viewport| {
Some(integration.on_window_event(
viewport.window.as_deref()?,
viewport.egui_winit.as_mut()?,
event,
))
})
shared_mut
.viewports
.get_mut(&viewport_id)
.and_then(|viewport| {
Some(integration.on_window_event(
viewport.window.as_deref()?,
viewport.egui_winit.as_mut()?,
event,
))
})
})
.unwrap_or_default();

if integration.should_close() {
EventResult::Exit
} else if event_response.repaint {
if repaint_asap {
EventResult::RepaintNow(window_id)
} else {
EventResult::RepaintNext(window_id)
}
if event_response.repaint {
EventResult::RepaintNow(window_id)
} else {
EventResult::Wait
}
Expand All @@ -869,14 +870,17 @@ impl Viewport {
windows_id: &mut HashMap<WindowId, ViewportId>,
painter: &mut egui_wgpu::winit::Painter,
) {
let viewport_id = self.ids.this;

self.info.this = viewport_id;
self.info.parent = Some(egui_ctx.parent_viewport_id_of(viewport_id));

if self.window.is_some() {
return; // we already have one
}

crate::profile_function!();

let viewport_id = self.ids.this;

match egui_winit::create_window(egui_ctx, event_loop, &self.builder) {
Ok(window) => {
windows_id.insert(window.id(), viewport_id);
Expand All @@ -897,6 +901,7 @@ impl Viewport {
painter.max_texture_side(),
));

self.info.transparent = self.builder.transparent;
egui_winit::update_viewport_info(&mut self.info, egui_ctx, &window, true);
self.window = Some(window);
}
Expand Down Expand Up @@ -1107,6 +1112,35 @@ fn handle_viewport_output(
remove_viewports_not_in(viewports, painter, viewport_from_window, viewport_output);
}

fn handle_viewport_close(
viewports: &ViewportIdMap<Viewport>,
painter: &mut egui_wgpu::winit::Painter,
window_id: WindowId,
viewport_id: ViewportId,
) -> EventResult {
if let Some(viewport) = viewports.get(&viewport_id) {
if viewport.info.should_close() {
if viewport_id == ViewportId::ROOT {
log::debug!(
"Received WindowEvent::CloseRequested for main viewport - shutting down."
);
}

if viewport_id == ViewportId::ROOT {
return EventResult::Exit(window_id);
} else {
if let (Some(width), Some(height)) = (NonZeroU32::new(0), NonZeroU32::new(0)) {
painter.on_window_resized(viewport_id, width, height);
}
// self.resize(viewport_id, physical_size);
return EventResult::ViewportExit(window_id);
}
}
}

EventResult::Wait
}

fn initialize_or_update_viewport(
viewports: &mut Viewports,
ids: ViewportIdPair,
Expand Down Expand Up @@ -1140,7 +1174,8 @@ fn initialize_or_update_viewport(
})
}

std::collections::hash_map::Entry::Occupied(mut entry) => {
std::collections::hash_map::Entry::Occupied(entry) => {
/*
// Patch an existing viewport:
let viewport = entry.get_mut();
Expand All @@ -1161,7 +1196,7 @@ fn initialize_or_update_viewport(
}
viewport.deferred_commands.append(&mut delta_commands);

*/
entry.into_mut()
}
}
Expand Down

0 comments on commit 4d0bbcd

Please sign in to comment.