1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-01 06:10:06 -04:00

Some work on wgpu implementation

This commit is contained in:
Konkitoman
2023-08-06 09:21:44 +03:00
parent 05bf0e124a
commit 860160ed05
4 changed files with 87 additions and 80 deletions

View File

@@ -1701,12 +1701,12 @@ mod wgpu_integration {
/// initialized once the application has an associated `SurfaceView`. /// initialized once the application has an associated `SurfaceView`.
struct WgpuWinitRunning { struct WgpuWinitRunning {
painter: egui_wgpu::winit::Painter, painter: egui_wgpu::winit::Painter,
integration: epi_integration::EpiIntegration, integration: Arc<RwLock<epi_integration::EpiIntegration>>,
app: Box<dyn epi::App>, app: Box<dyn epi::App>,
windows: HashMap< windows: HashMap<
u64, u64,
( (
Option<winit::window::Window>, Option<Arc<RwLock<winit::window::Window>>>,
Option<egui_winit::State>, Option<egui_winit::State>,
Option<Arc<Box<ViewportRender>>>, Option<Arc<Box<ViewportRender>>>,
u64, u64,
@@ -1725,7 +1725,7 @@ mod wgpu_integration {
/// Window surface state that's initialized when the app starts running via a Resumed event /// Window surface state that's initialized when the app starts running via a Resumed event
/// and on Android will also be destroyed if the application is paused. /// and on Android will also be destroyed if the application is paused.
is_focused: bool, is_focused: Option<u64>,
} }
impl WgpuWinitApp { impl WgpuWinitApp {
@@ -1747,7 +1747,7 @@ mod wgpu_integration {
native_options, native_options,
running: None, running: None,
app_creator: Some(app_creator), app_creator: Some(app_creator),
is_focused: true, is_focused: Some(0),
} }
} }
@@ -1776,7 +1776,7 @@ mod wgpu_integration {
running.windows_id.insert(new_window.id(), *id); running.windows_id.insert(new_window.id(), *id);
pollster::block_on(running.painter.set_window(*id, Some(&new_window))); pollster::block_on(running.painter.set_window(*id, Some(&new_window)));
*window = Some(new_window); *window = Some(Arc::new(RwLock::new(new_window)));
*state = Some(egui_winit::State::new(event_loop)); *state = Some(egui_winit::State::new(event_loop));
} }
} }
@@ -1786,7 +1786,9 @@ mod wgpu_integration {
fn set_window(&mut self, id: u64) -> std::result::Result<(), egui_wgpu::WgpuError> { fn set_window(&mut self, id: u64) -> std::result::Result<(), egui_wgpu::WgpuError> {
if let Some(running) = &mut self.running { if let Some(running) = &mut self.running {
if let Some((window, _, _, _, _)) = running.windows.get(&id) { if let Some((window, _, _, _, _)) = running.windows.get(&id) {
pollster::block_on(running.painter.set_window(id, window.as_ref().map(|w| w)))?; window.as_ref().map(|w| {
pollster::block_on(running.painter.set_window(id, Some(&w.read())))
});
} }
} }
Ok(()) Ok(())
@@ -1894,11 +1896,20 @@ mod wgpu_integration {
windows_id.insert(window.id(), 0); windows_id.insert(window.id(), 0);
let mut windows = HashMap::default(); let mut windows = HashMap::default();
windows.insert(0, (Some(window), Some(state), None, 0, builder)); windows.insert(
0,
(
Some(Arc::new(RwLock::new(window))),
Some(state),
None,
0,
builder,
),
);
self.running = Some(WgpuWinitRunning { self.running = Some(WgpuWinitRunning {
painter, painter,
integration, integration: Arc::new(RwLock::new(integration)),
app, app,
windows, windows,
windows_id, windows_id,
@@ -1912,41 +1923,48 @@ mod wgpu_integration {
fn frame_nr(&self) -> u64 { fn frame_nr(&self) -> u64 {
self.running self.running
.as_ref() .as_ref()
.map_or(0, |r| r.integration.egui_ctx.frame_nr()) .map_or(0, |r| r.integration.read().egui_ctx.frame_nr())
} }
fn is_focused(&self, _: winit::window::WindowId) -> bool { fn is_focused(&self, window_id: winit::window::WindowId) -> bool {
self.is_focused if let Some(focus) = self.is_focused {
self.get_window_id(&window_id)
.map(|i| i == focus)
.unwrap_or(false)
} else {
false
}
} }
fn integration(&self) -> Option<Arc<RwLock<EpiIntegration>>> { fn integration(&self) -> Option<Arc<RwLock<EpiIntegration>>> {
todo!() self.running.as_ref().map(|r| r.integration.clone())
// self.running.as_ref().map(|r| r.integration)
} }
fn window( fn window(
&self, &self,
window_id: winit::window::WindowId, window_id: winit::window::WindowId,
) -> Option<Arc<RwLock<winit::window::Window>>> { ) -> Option<Arc<RwLock<winit::window::Window>>> {
todo!() self.running
// self.running .as_ref()
// .as_ref() .and_then(|r| r.windows_id.get(&window_id).map(|id| r.windows.get(id)))
// .and_then(|r| r.windows_id.get(&window_id).map(|id| r.windows.get(id))) .flatten()
// .flatten() .and_then(|w| w.0.clone())
// .and_then(|w| w.0.as_ref())
} }
fn get_window_winit_id(&self, id: u64) -> Option<winit::window::WindowId> { fn get_window_winit_id(&self, id: u64) -> Option<winit::window::WindowId> {
self.running self.running
.as_ref() .as_ref()
.and_then(|r| r.windows.get(&id)) .and_then(|r| r.windows.get(&id))
.and_then(|w| w.0.as_ref().map(|w| w.id())) .and_then(|w| w.0.as_ref().map(|w| w.read().id()))
} }
fn save_and_destroy(&mut self) { fn save_and_destroy(&mut self) {
if let Some(mut running) = self.running.take() { if let Some(mut running) = self.running.take() {
if let Some((Some(window), _, _, _, _)) = running.windows.get(&0) { if let Some((Some(window), _, _, _, _)) = running.windows.get(&0) {
running.integration.save(running.app.as_mut(), window); running
.integration
.write()
.save(running.app.as_mut(), &*window.read());
} }
#[cfg(feature = "glow")] #[cfg(feature = "glow")]
@@ -1984,7 +2002,8 @@ mod wgpu_integration {
{ {
let Some((viewport_id, (Some(window), Some(state), render, parent_viewport_id, _))) = windows_id.get(&window_id).and_then(|id|(windows.get_mut(id).map(|w|(*id, w)))) else{return vec![]}; let Some((viewport_id, (Some(window), Some(state), render, parent_viewport_id, _))) = windows_id.get(&window_id).and_then(|id|(windows.get_mut(id).map(|w|(*id, w)))) else{return vec![]};
let _ = pollster::block_on(painter.set_window(viewport_id, Some(window))); let _ =
pollster::block_on(painter.set_window(viewport_id, Some(&window.read())));
egui::FullOutput { egui::FullOutput {
platform_output, platform_output,
@@ -1993,22 +2012,27 @@ mod wgpu_integration {
shapes, shapes,
viewports, viewports,
viewport_commands, viewport_commands,
} = integration.update( } = integration.write().update(
app.as_mut(), app.as_mut(),
window, &*window.read(),
state, state,
render.clone(), render.clone(),
viewport_id, viewport_id,
*parent_viewport_id, *parent_viewport_id,
); );
integration.handle_platform_output(window, platform_output, state); integration.write().handle_platform_output(
&window.read(),
platform_output,
state,
);
let clipped_primitives = { let clipped_primitives = {
crate::profile_scope!("tessellate"); crate::profile_scope!("tessellate");
integration.egui_ctx.tessellate(shapes) integration.read().egui_ctx.tessellate(shapes)
}; };
let integration = &mut *integration.write();
let screenshot_requested = &mut integration.frame.output.screenshot_requested; let screenshot_requested = &mut integration.frame.output.screenshot_requested;
let screenshot = painter.paint_and_update_textures( let screenshot = painter.paint_and_update_textures(
@@ -2022,8 +2046,8 @@ mod wgpu_integration {
*screenshot_requested = false; *screenshot_requested = false;
integration.frame.screenshot.set(screenshot); integration.frame.screenshot.set(screenshot);
integration.post_rendering(app.as_mut(), window); integration.post_rendering(app.as_mut(), &window.read());
integration.post_present(window); integration.post_present(&window.read());
} }
let mut active_viewports_ids = vec![0]; let mut active_viewports_ids = vec![0];
@@ -2044,41 +2068,11 @@ mod wgpu_integration {
active_viewports_ids.push(id); active_viewports_ids.push(id);
} }
// TODO Make this more efficient egui_winit::process_viewport_commands(
for (id, command) in viewport_commands { viewport_commands,
if let Some(window) = windows.get(&id) { self.is_focused,
if let Some(win) = &window.0 { |viewport_id| windows.get(&viewport_id).and_then(|w| w.0.clone()),
match command { );
egui::window::ViewportCommand::Drag => {
// if this is not checked on x11 the input will be permanently taken until the app is killed!
// if let Some(focus) = self.is_focused {
// if focus == id {
win.drag_window();
// }
// }
}
egui::window::ViewportCommand::InnerSize(width, height) => {
win.set_inner_size(winit::dpi::PhysicalSize::new(
width, height,
));
}
egui::window::ViewportCommand::Resize(top, bottom, right, left) => {
win.drag_resize_window(match (top, bottom, right, left) {
(true, false, false, false) => ResizeDirection::North,
(false, true, false, false) => ResizeDirection::South,
(false, false, true, false) => ResizeDirection::East,
(false, false, false, true) => ResizeDirection::West,
(true, false, true, false) => ResizeDirection::NorthEast,
(false, true, true, false) => ResizeDirection::SouthEast,
(true, false, false, true) => ResizeDirection::NorthWest,
(false, true, false, true) => ResizeDirection::SouthWest,
_ => ResizeDirection::East,
});
}
}
}
}
}
windows.retain(|id, _| active_viewports_ids.contains(id)); windows.retain(|id, _| active_viewports_ids.contains(id));
windows_id.retain(|_, id| active_viewports_ids.contains(id)); windows_id.retain(|_, id| active_viewports_ids.contains(id));
@@ -2086,11 +2080,11 @@ mod wgpu_integration {
let mut control_flow = vec![EventResult::Wait]; let mut control_flow = vec![EventResult::Wait];
for repaint_after in repaint_after { for repaint_after in repaint_after {
control_flow.push(if integration.should_close() { control_flow.push(if integration.read().should_close() {
EventResult::Exit EventResult::Exit
} else if repaint_after.1.is_zero() { } else if repaint_after.1.is_zero() {
if let Some((Some(window_id), _, _, _, _)) = windows.get(&repaint_after.0) { if let Some((Some(window), _, _, _, _)) = windows.get(&repaint_after.0) {
EventResult::RepaintNext(window_id.id()) EventResult::RepaintNext(window.read().id())
} else { } else {
EventResult::Wait EventResult::Wait
} }
@@ -2102,8 +2096,8 @@ mod wgpu_integration {
// technically, this might lead to some weird corner cases where the user *WANTS* // technically, this might lead to some weird corner cases where the user *WANTS*
// winit to use `WaitUntil(MAX_INSTANT)` explicitly. they can roll their own // winit to use `WaitUntil(MAX_INSTANT)` explicitly. they can roll their own
// egui backend impl i guess. // egui backend impl i guess.
if let Some((Some(window_id), _, _, _, _)) = windows.get(&repaint_after.0) { if let Some((Some(window), _, _, _, _)) = windows.get(&repaint_after.0) {
EventResult::RepaintAt(window_id.id(), repaint_after_instant) EventResult::RepaintAt(window.read().id(), repaint_after_instant)
} else { } else {
EventResult::Wait EventResult::Wait
} }
@@ -2113,9 +2107,11 @@ mod wgpu_integration {
} }
let Some((_, (Some(window), _, _, _, _))) = windows_id.get(&window_id).and_then(|id|(windows.get_mut(id).map(|w|(*id, w)))) else{return vec![]}; let Some((_, (Some(window), _, _, _, _))) = windows_id.get(&window_id).and_then(|id|(windows.get_mut(id).map(|w|(*id, w)))) else{return vec![]};
integration.maybe_autosave(app.as_mut(), window); integration
.write()
.maybe_autosave(app.as_mut(), &window.read());
if window.is_minimized() == Some(true) { if window.read().is_minimized() == Some(true) {
// On Mac, a minimized Window uses up all CPU: // On Mac, a minimized Window uses up all CPU:
// https://github.com/emilk/egui/issues/325 // https://github.com/emilk/egui/issues/325
crate::profile_scope!("bg_sleep"); crate::profile_scope!("bg_sleep");
@@ -2140,7 +2136,7 @@ mod wgpu_integration {
if running.windows.get(&0).is_none() { if running.windows.get(&0).is_none() {
let window = Self::create_window( let window = Self::create_window(
event_loop, event_loop,
running.integration.frame.storage(), running.integration.read().frame.storage(),
&self.app_name, &self.app_name,
&self.native_options, &self.native_options,
)?; )?;
@@ -2171,6 +2167,7 @@ mod wgpu_integration {
.0 .0
.as_ref() .as_ref()
.unwrap() .unwrap()
.read()
.id(), .id(),
) )
} }
@@ -2181,6 +2178,7 @@ mod wgpu_integration {
} }
winit::event::Event::WindowEvent { event, window_id } => { winit::event::Event::WindowEvent { event, window_id } => {
let viewport_id = self.get_window_id(window_id);
if let Some(running) = &mut self.running { if let Some(running) = &mut self.running {
// On Windows, if a window is resized by the user, it should repaint synchronously, inside the // On Windows, if a window is resized by the user, it should repaint synchronously, inside the
// event handler. // event handler.
@@ -2199,7 +2197,7 @@ mod wgpu_integration {
match &event { match &event {
winit::event::WindowEvent::Focused(new_focused) => { winit::event::WindowEvent::Focused(new_focused) => {
self.is_focused = *new_focused; self.is_focused = new_focused.then(|| viewport_id).flatten();
} }
winit::event::WindowEvent::Resized(physical_size) => { winit::event::WindowEvent::Resized(physical_size) => {
repaint_asap = true; repaint_asap = true;
@@ -2235,7 +2233,7 @@ mod wgpu_integration {
} }
} }
winit::event::WindowEvent::CloseRequested winit::event::WindowEvent::CloseRequested
if running.integration.should_close() => if running.integration.read().should_close() =>
{ {
log::debug!("Received WindowEvent::CloseRequested"); log::debug!("Received WindowEvent::CloseRequested");
return Ok(EventResult::Exit); return Ok(EventResult::Exit);
@@ -2248,7 +2246,7 @@ mod wgpu_integration {
.get(window_id) .get(window_id)
.and_then(|id| running.windows.get_mut(id).map(|w| (*id, w))) .and_then(|id| running.windows.get_mut(id).map(|w| (*id, w)))
{ {
Some(running.integration.on_event( Some(running.integration.write().on_event(
running.app.as_mut(), running.app.as_mut(),
event, event,
window_id, window_id,
@@ -2259,7 +2257,7 @@ mod wgpu_integration {
None None
}; };
if running.integration.should_close() { if running.integration.read().should_close() {
EventResult::Exit EventResult::Exit
} else if let Some(event_response) = event_response { } else if let Some(event_response) = event_response {
if event_response.repaint { if event_response.repaint {
@@ -2288,7 +2286,7 @@ mod wgpu_integration {
.get(window_id) .get(window_id)
.and_then(|id| running.windows.get_mut(id)) .and_then(|id| running.windows.get_mut(id))
{ {
running.integration.on_accesskit_action_request( running.integration.write().on_accesskit_action_request(
request.clone(), request.clone(),
window_id, window_id,
state, state,
@@ -2306,7 +2304,9 @@ mod wgpu_integration {
} }
fn get_window_id(&self, id: &winit::window::WindowId) -> Option<u64> { fn get_window_id(&self, id: &winit::window::WindowId) -> Option<u64> {
todo!() self.running
.as_ref()
.and_then(|r| r.windows_id.get(id).cloned())
} }
} }

View File

@@ -104,7 +104,7 @@ impl eframe::App for Custom3d {
render: Option<&ViewportRender>, render: Option<&ViewportRender>,
) { ) {
if let Some(render) = render { if let Some(render) = render {
render(ctx, frame.viewport_id(), frame.parent_viewport_id()); render(ctx, ctx.get_viewport_id(), ctx.get_parent_viewport_id());
return; return;
} }
egui::CentralPanel::default().show(ctx, |ui| { egui::CentralPanel::default().show(ctx, |ui| {

View File

@@ -7,6 +7,8 @@ edition = "2021"
rust-version = "1.65" rust-version = "1.65"
publish = false publish = false
[features]
wgpu = ["eframe/wgpu"]
[dependencies] [dependencies]
eframe = { path = "../../crates/eframe" } eframe = { path = "../../crates/eframe" }

View File

@@ -3,6 +3,11 @@ use eframe::egui::window::ViewportBuilder;
use eframe::egui::Id; use eframe::egui::Id;
use eframe::NativeOptions; use eframe::NativeOptions;
#[cfg(feature = "wgpu")]
const RENDERER: eframe::Renderer = eframe::Renderer::Wgpu;
#[cfg(not(feature = "wgpu"))]
const RENDERER: eframe::Renderer = eframe::Renderer::Glow;
fn main() { fn main() {
env_logger::init(); // Use `RUST_LOG=debug` to see logs. env_logger::init(); // Use `RUST_LOG=debug` to see logs.
@@ -19,7 +24,7 @@ fn main() {
let _ = eframe::run_simple_native( let _ = eframe::run_simple_native(
"Viewports Examples", "Viewports Examples",
NativeOptions { NativeOptions {
renderer: eframe::Renderer::Glow, renderer: RENDERER,
..NativeOptions::default() ..NativeOptions::default()
}, },
move |ctx, _frame| { move |ctx, _frame| {
@@ -177,7 +182,7 @@ fn main() {
} else { } else {
ctx.memory_mut(|mem| { ctx.memory_mut(|mem| {
mem.set_dragged_id( mem.set_dragged_id(
egui::Id::new("Test2").with("frame_resize"), egui::Id::new("Test3").with("frame_resize"),
) )
}); });
} }