From 34fea8a0e5fde91832046c3f73ee936a48e187dd Mon Sep 17 00:00:00 2001 From: Konkitoman Date: Wed, 2 Aug 2023 17:14:31 +0300 Subject: [PATCH] Some more work on making possible to render viewport_sync in glutin Context::current_rendering_viewport was replaced by Context::get_viewport_id Added Context::get_parent_viewport_id Changed Context::run to need parent_viewport_id Changed Context::beagin to need parent_viewport_id Added ImplContext::frame_stack Some work on making posibile to render multiples frames at the same time A lot of more things in glutin backend is not Arc> --- crates/eframe/src/native/epi_integration.rs | 10 +- crates/eframe/src/native/run.rs | 182 ++++++++++++++------ crates/egui/src/context.rs | 131 ++++++++------ crates/egui/src/lib.rs | 4 +- crates/egui_demo_lib/benches/benchmark.rs | 12 +- crates/egui_demo_lib/src/lib.rs | 4 +- examples/hello_world_simple/src/main.rs | 2 +- examples/viewports/Cargo.toml | 2 +- examples/viewports/src/main.rs | 25 ++- 9 files changed, 248 insertions(+), 124 deletions(-) diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index 79327c80e..65237e7ed 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -515,10 +515,12 @@ impl EpiIntegration { self.frame.info.parent_viewport = parent_id; // Run user code: - let full_output = self.egui_ctx.run(raw_input, viewport_id, |egui_ctx| { - crate::profile_scope!("App::update"); - app.update(egui_ctx, &mut self.frame, render.as_ref().map(|r| &***r)); - }); + let full_output = self + .egui_ctx + .run(raw_input, viewport_id, parent_id, |egui_ctx| { + crate::profile_scope!("App::update"); + app.update(egui_ctx, &mut self.frame, render.as_ref().map(|r| &***r)); + }); self.pending_full_output.append(full_output); let full_output = std::mem::take(&mut self.pending_full_output); diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index aba4b97b0..482bdc700 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -450,9 +450,9 @@ mod glow_integration { /// initialized once the application has an associated `SurfaceView`. struct GlowWinitRunning { gl: Arc, - painter: egui_glow::Painter, + painter: Arc>, integration: Arc>, - app: Box, + app: Arc>>, // Conceptually this will be split out eventually so that the rest of the state // can be persistent. glutin_ctx: Arc>, @@ -491,6 +491,9 @@ mod glow_integration { window_maps: HashMap, } + unsafe impl Sync for GlutinWindowContext {} + unsafe impl Send for GlutinWindowContext {} + impl GlutinWindowContext { /// There is a lot of complexity with opengl creation, so prefer extensive logging to get all the help we can to debug issues. /// @@ -962,12 +965,82 @@ mod glow_integration { } } + let glutin_ctx = Arc::new(RwLock::new(gl_window)); + + let egui_ctx = integration.egui_ctx.clone(); + let glutin = glutin_ctx.clone(); + let _gl = gl.clone(); + let painter = Arc::new(RwLock::new(painter)); + let _painter = painter.clone(); + + integration.egui_ctx.set_render_sync_callback( + move |viewport_builder, viewport_id, parent_viewport_id, render| { + let window = glutin.read().windows.get(&viewport_id).cloned(); + if let Some(window) = window { + let window = &mut *window.write(); + if let Some(winit_state) = &mut window.egui_winit { + if let Some(win) = window.window.clone() { + println!("Render beagin!"); + let win = win.read(); + let input = winit_state.take_egui_input(&win); + let output = + egui_ctx.run(input, viewport_id, parent_viewport_id, |ctx| { + render(&egui_ctx, viewport_id, parent_viewport_id); + }); + let glutin = &mut *glutin.write(); + + glutin.current_gl_context = Some( + glutin + .current_gl_context + .take() + .unwrap() + .make_not_current() + .unwrap() + .make_current(window.gl_surface.as_ref().unwrap()) + .unwrap(), + ); + + let screen_size_in_pixels: [u32; 2] = win.inner_size().into(); + + egui_glow::painter::clear( + &_gl, + screen_size_in_pixels, + [0.0, 0.0, 0.0, 0.0], + ); + + let clipped_primitives = egui_ctx.tessellate(output.shapes); + + _painter.write().paint_and_update_textures( + screen_size_in_pixels, + egui_ctx.pixels_per_point(), + &clipped_primitives, + &output.textures_delta, + ); + unsafe { + crate::profile_scope!("swap_buffers"); + let _ = window + .gl_surface + .as_ref() + .expect("failed to get surface to swap buffers") + .swap_buffers(glutin.current_gl_context.as_ref().expect( + "failed to get current context to swap buffers", + )); + } + println!("Should render sync"); + return; + } + } + } + render(&egui_ctx, 0, 0); + }, + ); + *self.running.write() = Some(GlowWinitRunning { - glutin_ctx: Arc::new(RwLock::new(gl_window)), + glutin_ctx, gl, painter, integration: Arc::new(RwLock::new(integration)), - app, + app: Arc::new(RwLock::new(app)), }); Ok(()) @@ -1033,7 +1106,7 @@ mod glow_integration { fn save_and_destroy(&mut self) { if let Some(mut running) = self.running.write().take() { running.integration.write().save( - running.app.as_mut(), + running.app.write().as_mut(), &running .glutin_ctx .read() @@ -1044,8 +1117,8 @@ mod glow_integration { .unwrap() .read(), ); - running.app.on_exit(Some(&running.gl)); - running.painter.destroy(); + running.app.write().on_exit(Some(&running.gl)); + running.painter.write().destroy(); } } @@ -1059,17 +1132,15 @@ mod glow_integration { puffin::GlobalProfiler::lock().new_frame(); crate::profile_scope!("frame"); - let mut running = self.running.write(); - let GlowWinitRunning { - glutin_ctx: gl_window, - gl, - app, - integration, - painter, - } = running.as_mut().unwrap(); + let running = self.running.clone(); + + let integration = self.running.read().as_ref().unwrap().integration.clone(); + let app = self.running.read().as_ref().unwrap().app.clone(); + let glutin_ctx = self.running.read().as_ref().unwrap().glutin_ctx.clone(); + let painter = self.running.read().as_ref().unwrap().painter.clone(); let mut window_map = HashMap::default(); - for (id, window) in gl_window.read().windows.iter() { + for (id, window) in glutin_ctx.read().windows.iter() { if let Some(win) = &window.read().window { window_map.insert(*id, win.read().id()); } @@ -1087,21 +1158,8 @@ mod glow_integration { let control_flow; { // let window = gl_window.window(window_index); - let win = gl_window.read().windows.get(&viewport_id).cloned(); + let win = glutin_ctx.read().windows.get(&viewport_id).cloned(); let win = win.unwrap(); - { - let mut gl_window = gl_window.write(); - gl_window.current_gl_context = Some( - gl_window - .current_gl_context - .take() - .unwrap() - .make_not_current() - .unwrap() - .make_current(win.read().gl_surface.as_ref().unwrap()) - .unwrap(), - ); - }; let screen_size_in_pixels: [u32; 2] = win .read() @@ -1112,18 +1170,6 @@ mod glow_integration { .inner_size() .into(); - win.write() - .window - .as_ref() - .unwrap() - .read() - .set_transparent(true); - egui_glow::painter::clear( - gl, - screen_size_in_pixels, - app.clear_color(&integration.read().egui_ctx.style().visuals), - ); - { let win = &mut *win.write(); egui::FullOutput { @@ -1134,7 +1180,7 @@ mod glow_integration { viewports, viewport_commands, } = integration.write().update( - app.as_mut(), + app.write().as_mut(), &win.window.as_ref().unwrap().read(), win.egui_winit.as_mut().unwrap(), win.render.clone(), @@ -1148,12 +1194,35 @@ mod glow_integration { win.egui_winit.as_mut().unwrap(), ); } + let clipped_primitives = { crate::profile_scope!("tessellate"); integration.read().egui_ctx.tessellate(shapes) }; + { + let mut gl_window = glutin_ctx.write(); + gl_window.current_gl_context = Some( + gl_window + .current_gl_context + .take() + .unwrap() + .make_not_current() + .unwrap() + .make_current(win.read().gl_surface.as_ref().unwrap()) + .unwrap(), + ); + }; - painter.paint_and_update_textures( + let gl = self.running.read().as_ref().unwrap().gl.clone(); + + egui_glow::painter::clear( + &gl, + screen_size_in_pixels, + app.read() + .clear_color(&integration.read().egui_ctx.style().visuals), + ); + + painter.write().paint_and_update_textures( screen_size_in_pixels, integration.read().egui_ctx.pixels_per_point(), &clipped_primitives, @@ -1167,12 +1236,12 @@ mod glow_integration { if *screenshot_requested { *screenshot_requested = false; - let screenshot = painter.read_screen_rgba(screen_size_in_pixels); + let screenshot = painter.read().read_screen_rgba(screen_size_in_pixels); integration.frame.screenshot.set(Some(screenshot)); } integration.post_rendering( - app.as_mut(), + app.write().as_mut(), &win.read().window.as_ref().unwrap().read(), ); } @@ -1185,7 +1254,7 @@ mod glow_integration { .as_ref() .expect("failed to get surface to swap buffers") .swap_buffers( - gl_window + glutin_ctx .read() .current_gl_context .as_ref() @@ -1203,7 +1272,7 @@ mod glow_integration { path.ends_with(".png"), "Expected EFRAME_SCREENSHOT_TO to end with '.png', got {path:?}" ); - let screenshot = painter.read_screen_rgba(screen_size_in_pixels); + let screenshot = painter.read().read_screen_rgba(screen_size_in_pixels); image::save_buffer( &path, screenshot.as_raw(), @@ -1246,8 +1315,10 @@ mod glow_integration { .collect::>() }; - integration - .maybe_autosave(app.as_mut(), &win.read().window.as_ref().unwrap().read()); + integration.maybe_autosave( + app.write().as_mut(), + &win.read().window.as_ref().unwrap().read(), + ); if win.read().window.as_ref().unwrap().read().is_minimized() == Some(true) { // On Mac, a minimized Window uses up all CPU: @@ -1261,7 +1332,7 @@ mod glow_integration { let mut active_viewports_ids = vec![0]; viewports.retain_mut(|(id, _, builder, render)| { - if let Some(w) = gl_window.read().windows.get(id) { + if let Some(w) = glutin_ctx.read().windows.get(id) { let mut w = w.write(); if w.builder != *builder { if let Some(window) = &mut w.window { @@ -1283,7 +1354,7 @@ mod glow_integration { }); for (id, parent, builder, render) in viewports { - gl_window.write().windows.insert( + glutin_ctx.write().windows.insert( id, Arc::new(RwLock::new(Window { builder, @@ -1299,7 +1370,7 @@ mod glow_integration { } for (id, command) in viewport_commands { - if let Some(window) = gl_window.read().windows.get(&id) { + if let Some(window) = glutin_ctx.read().windows.get(&id) { let window = window.read(); if let Some(win) = &window.window { @@ -1334,12 +1405,11 @@ mod glow_integration { } } + let mut gl_window = glutin_ctx.write(); gl_window - .write() .windows .retain(|id, _| active_viewports_ids.contains(id)); gl_window - .write() .window_maps .retain(|_, id| active_viewports_ids.contains(id)); @@ -1499,7 +1569,7 @@ mod glow_integration { let viewport = &mut *viewport.write(); break 'res running.integration.write().on_event( - running.app.as_mut(), + running.app.write().as_mut(), event, window_id, viewport.egui_winit.as_mut().unwrap(), diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 12a96b4a9..b6db46305 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -183,7 +183,10 @@ struct ContextImpl { input: HashMap, /// State that is collected during a frame and then cleared - frame_state: FrameState, + frame_state: HashMap, + + // Viewport Id, Parent Viewport Id + frame_stack: Vec<(u64, u64)>, // The output of a frame: graphics: GraphicLayers, @@ -216,7 +219,6 @@ struct ContextImpl { >, viewport_counter: u64, - current_rendering_viewport: u64, is_desktop: bool, /// Written to during the frame. @@ -233,9 +235,14 @@ struct ContextImpl { } impl ContextImpl { - fn begin_frame_mut(&mut self, mut new_raw_input: RawInput, viewport_id: u64) { - self.current_rendering_viewport = viewport_id; - self.repaint.start_frame(self.current_rendering_viewport); + fn begin_frame_mut( + &mut self, + mut new_raw_input: RawInput, + viewport_id: u64, + parent_viewport_id: u64, + ) { + self.frame_stack.push((viewport_id, parent_viewport_id)); + self.repaint.start_frame(self.get_viewport_id()); if let Some(new_pixels_per_point) = self.memory.new_pixels_per_point.take() { new_raw_input.pixels_per_point = Some(new_pixels_per_point); @@ -268,6 +275,8 @@ impl ContextImpl { self.input.insert(viewport_id, input); self.frame_state + .entry(viewport_id) + .or_default() .begin_frame(self.input.get(&viewport_id).unwrap()); self.update_fonts_mut(); @@ -293,7 +302,10 @@ impl ContextImpl { builder.set_transform(accesskit::Affine::scale(input.pixels_per_point().into())); let mut node_builders = IdMap::default(); node_builders.insert(id, builder); - self.frame_state.accesskit_state = Some(AccessKitFrameState { + self.frame_state + .entry(self.get_viewport_id()) + .or_default() + .accesskit_state = Some(AccessKitFrameState { node_builders, parent_stack: vec![id], }); @@ -302,10 +314,7 @@ impl ContextImpl { /// Load fonts unless already loaded. fn update_fonts_mut(&mut self) { - let input = self - .input - .entry(self.current_rendering_viewport) - .or_default(); + let input = self.input.entry(self.get_viewport_id()).or_default(); let pixels_per_point = input.pixels_per_point(); let max_texture_side = input.max_texture_side; @@ -332,7 +341,13 @@ impl ContextImpl { #[cfg(feature = "accesskit")] fn accesskit_node_builder(&mut self, id: Id) -> &mut accesskit::NodeBuilder { - let state = self.frame_state.accesskit_state.as_mut().unwrap(); + let state = self + .frame_state + .entry(self.get_viewport_id()) + .or_default() + .accesskit_state + .as_mut() + .unwrap(); let builders = &mut state.node_builders; if let std::collections::hash_map::Entry::Vacant(entry) = builders.entry(id) { entry.insert(Default::default()); @@ -344,6 +359,16 @@ impl ContextImpl { } } +impl ContextImpl { + fn get_viewport_id(&self) -> u64 { + self.frame_stack.last().cloned().unwrap_or_default().0 + } + + fn get_parent_viewport_id(&self) -> u64 { + self.frame_stack.last().cloned().unwrap_or_default().1 + } +} + // ---------------------------------------------------------------------------- /// Your handle to egui. @@ -464,9 +489,10 @@ impl Context { &self, new_input: RawInput, viewport_id: u64, + parent_viewport_id: u64, run_ui: impl FnOnce(&Context), ) -> FullOutput { - self.begin_frame(new_input, viewport_id); + self.begin_frame(new_input, viewport_id, parent_viewport_id); run_ui(self); self.end_frame() } @@ -488,8 +514,8 @@ impl Context { /// let full_output = ctx.end_frame(); /// // handle full_output /// ``` - pub fn begin_frame(&self, new_input: RawInput, viewport_id: u64) { - self.write(|ctx| ctx.begin_frame_mut(new_input, viewport_id)); + pub fn begin_frame(&self, new_input: RawInput, viewport_id: u64, parent_viewport_id: u64) { + self.write(|ctx| ctx.begin_frame_mut(new_input, viewport_id, parent_viewport_id)); } } @@ -516,7 +542,7 @@ impl Context { self.read(move |ctx| { reader( ctx.input - .get(&ctx.current_rendering_viewport) + .get(&ctx.get_viewport_id()) .unwrap_or(&Default::default()), ) }) @@ -580,13 +606,13 @@ impl Context { /// Read-only access to [`FrameState`]. #[inline] pub(crate) fn frame_state(&self, reader: impl FnOnce(&FrameState) -> R) -> R { - self.read(move |ctx| reader(&ctx.frame_state)) + self.read(move |ctx| reader(ctx.frame_state.get(&ctx.get_viewport_id()).unwrap())) } /// Read-write access to [`FrameState`]. #[inline] pub(crate) fn frame_state_mut(&self, writer: impl FnOnce(&mut FrameState) -> R) -> R { - self.write(move |ctx| writer(&mut ctx.frame_state)) + self.write(move |ctx| writer(ctx.frame_state.entry(ctx.get_viewport_id()).or_default())) } /// Read-only access to [`Fonts`]. @@ -770,7 +796,7 @@ impl Context { if hovered { let pointer_pos = ctx .input - .get(&ctx.current_rendering_viewport) + .get(&ctx.get_viewport_id()) .unwrap() .pointer .interact_pos(); @@ -867,13 +893,14 @@ impl Context { let clicked_elsewhere = response.clicked_elsewhere(); self.write(|ctx| { + let viewport_id = ctx.get_viewport_id(); let memory = &mut ctx.memory; if sense.focusable { memory.interested_in_focus(id); } - let input = ctx.input.get_mut(&ctx.current_rendering_viewport).unwrap(); + let input = ctx.input.get_mut(&viewport_id).unwrap(); if sense.click && memory.has_focus(response.id) @@ -1064,7 +1091,7 @@ impl Context { /// (this will work on `eframe`). pub fn request_repaint(&self) { // request two frames of repaint, just to cover some corner cases (frame delays): - self.write(|ctx| ctx.repaint.request_repaint(ctx.current_rendering_viewport)); + self.write(|ctx| ctx.repaint.request_repaint(ctx.get_viewport_id())); } pub fn request_repaint_viewport(&self, id: u64) { @@ -1104,7 +1131,7 @@ impl Context { // Maybe we can check if duration is ZERO, and call self.request_repaint()? self.write(|ctx| { ctx.repaint - .request_repaint_after(duration, ctx.current_rendering_viewport) + .request_repaint_after(duration, ctx.get_viewport_id()) }); } @@ -1328,7 +1355,7 @@ impl Context { pub fn end_frame(&self) -> FullOutput { let mut viewports: Vec = self.write(|ctx| { ctx.layer_rects_prev_viewports.insert( - ctx.current_rendering_viewport, + ctx.get_viewport_id(), std::mem::take(&mut ctx.layer_rects_this_frame), ); ctx.viewports @@ -1344,9 +1371,12 @@ impl Context { let textures_delta = self.write(|ctx| { ctx.memory.end_frame( - ctx.input.get(&ctx.current_rendering_viewport).unwrap(), + ctx.input.get(&ctx.get_viewport_id()).unwrap(), &viewports, - &ctx.frame_state.used_ids, + &ctx.frame_state + .entry(ctx.get_viewport_id()) + .or_default() + .used_ids, ); let font_image_delta = ctx.fonts.as_ref().unwrap().font_image_delta(); @@ -1399,10 +1429,8 @@ impl Context { .retain(|id, _| viewports.contains(id)) }); - let repaint_after = self.write(|ctx| { - ctx.repaint - .end_frame(ctx.current_rendering_viewport, viewports) - }); + let repaint_after = + self.write(|ctx| ctx.repaint.end_frame(ctx.get_viewport_id(), viewports)); let shapes = self.drain_paint_lists(); // This is used for, @@ -1417,20 +1445,21 @@ impl Context { let mut viewports = Vec::new(); self.write(|ctx| { + let viewport_id = ctx.get_viewport_id(); ctx.viewports .retain(|_, (builder, id, parent, used, render)| { let out = *used; - if ctx.current_rendering_viewport == *parent { + if viewport_id == *parent { *used = false; } viewports.push((*id, *parent, builder.clone(), render.clone())); - (out || ctx.current_rendering_viewport != *parent) - && avalibile_viewports.contains(parent) + (out || viewport_id != *parent) && avalibile_viewports.contains(parent) }) }); + self.write(|ctx| ctx.frame_stack.pop()); FullOutput { platform_output, repaint_after, @@ -1455,7 +1484,7 @@ impl Context { self.write(|ctx| { let pixels_per_point = ctx .input - .entry(ctx.current_rendering_viewport) + .entry(ctx.get_viewport_id()) .or_default() .pixels_per_point(); let tessellation_options = ctx.memory.options.tessellation_options; @@ -1500,7 +1529,11 @@ impl Context { /// How much space is used by panels and windows. pub fn used_rect(&self) -> Rect { self.read(|ctx| { - let mut used = ctx.frame_state.used_by_panels; + let mut used = ctx + .frame_state + .get(&ctx.get_viewport_id()) + .unwrap() + .used_by_panels; for window in ctx.memory.areas.visible_windows() { used = used.union(window.rect()); } @@ -1670,7 +1703,7 @@ impl Context { pub fn animate_bool_with_time(&self, id: Id, target_value: bool, animation_time: f32) -> f32 { let animated_value = self.write(|ctx| { ctx.animation_manager.animate_bool( - ctx.input.get(&ctx.current_rendering_viewport).unwrap(), + ctx.input.get(&ctx.get_viewport_id()).unwrap(), animation_time, id, target_value, @@ -1690,7 +1723,7 @@ impl Context { pub fn animate_value_with_time(&self, id: Id, target_value: f32, animation_time: f32) -> f32 { let animated_value = self.write(|ctx| { ctx.animation_manager.animate_value( - ctx.input.get(&ctx.current_rendering_viewport).unwrap(), + ctx.input.get(&ctx.get_viewport_id()).unwrap(), animation_time, id, target_value, @@ -2014,6 +2047,8 @@ impl Context { ) -> Option { self.write(|ctx| { ctx.frame_state + .entry(ctx.get_viewport_id()) + .or_default() .accesskit_state .is_some() .then(|| ctx.accesskit_node_builder(id)) @@ -2057,8 +2092,12 @@ impl Context { use containers::window::ViewportBuilder; /// # Windows impl Context { - pub fn current_rendering_viewport(&self) -> u64 { - self.read(|ctx| ctx.current_rendering_viewport) + pub fn get_viewport_id(&self) -> u64 { + self.read(|ctx| ctx.get_viewport_id()) + } + + pub fn get_parent_viewport_id(&self) -> u64 { + self.read(|ctx| ctx.get_parent_viewport_id()) } pub fn set_render_sync_callback( @@ -2091,9 +2130,10 @@ impl Context { ) { if self.is_desktop() { self.write(|ctx| { + let viewport_id = ctx.get_viewport_id(); if let Some(window) = ctx.viewports.get_mut(&viewport_builder.title) { window.0 = viewport_builder; - window.2 = ctx.current_rendering_viewport; + window.2 = viewport_id; window.3 = true; window.4 = Some(Arc::new(Box::new(func))); } else { @@ -2104,7 +2144,7 @@ impl Context { ( viewport_builder, id, - ctx.current_rendering_viewport, + viewport_id, true, Some(Arc::new(Box::new(func))), ), @@ -2125,9 +2165,10 @@ impl Context { let mut viewport_id = 0; let mut parent_viewport_id = 0; let render_sync = self.write(|ctx| { + viewport_id = ctx.get_viewport_id(); if let Some(window) = ctx.viewports.get_mut(&viewport_builder.title) { window.0 = viewport_builder.clone(); - window.2 = ctx.current_rendering_viewport; + window.2 = viewport_id; window.3 = true; window.4 = None; viewport_id = window.1; @@ -2137,16 +2178,10 @@ impl Context { ctx.viewport_counter = id; ctx.viewports.insert( viewport_builder.title.clone(), - ( - viewport_builder.clone(), - id, - ctx.current_rendering_viewport, - true, - None, - ), + (viewport_builder.clone(), id, viewport_id, true, None), ); viewport_id = id; - parent_viewport_id = ctx.current_rendering_viewport; + parent_viewport_id = ctx.get_viewport_id(); } ctx.render_sync.clone() diff --git a/crates/egui/src/lib.rs b/crates/egui/src/lib.rs index b742fe2e1..05f09c5cf 100644 --- a/crates/egui/src/lib.rs +++ b/crates/egui/src/lib.rs @@ -555,7 +555,7 @@ pub type ViewportRender = dyn Fn(&Context, u64, u64) + Sync + Send; pub fn __run_test_ctx(mut run_ui: impl FnMut(&Context)) { let ctx = Context::default(); ctx.set_fonts(FontDefinitions::empty()); // prevent fonts from being loaded (save CPU time) - let _ = ctx.run(Default::default(), 0, |ctx| { + let _ = ctx.run(Default::default(), 0, 0, |ctx| { run_ui(ctx); }); } @@ -564,7 +564,7 @@ pub fn __run_test_ctx(mut run_ui: impl FnMut(&Context)) { pub fn __run_test_ui(mut add_contents: impl FnMut(&mut Ui)) { let ctx = Context::default(); ctx.set_fonts(FontDefinitions::empty()); // prevent fonts from being loaded (save CPU time) - let _ = ctx.run(Default::default(), 0, |ctx| { + let _ = ctx.run(Default::default(), 0, 0, |ctx| { crate::CentralPanel::default().show(ctx, |ui| { add_contents(ui); }); diff --git a/crates/egui_demo_lib/benches/benchmark.rs b/crates/egui_demo_lib/benches/benchmark.rs index e9ee67199..eac580f1d 100644 --- a/crates/egui_demo_lib/benches/benchmark.rs +++ b/crates/egui_demo_lib/benches/benchmark.rs @@ -13,7 +13,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { // The most end-to-end benchmark. c.bench_function("demo_with_tessellate__realistic", |b| { b.iter(|| { - let full_output = ctx.run(RawInput::default(), 0, |ctx| { + let full_output = ctx.run(RawInput::default(), 0, 0, |ctx| { demo_windows.ui(ctx); }); ctx.tessellate(full_output.shapes) @@ -22,13 +22,13 @@ pub fn criterion_benchmark(c: &mut Criterion) { c.bench_function("demo_no_tessellate", |b| { b.iter(|| { - ctx.run(RawInput::default(), 0, |ctx| { + ctx.run(RawInput::default(), 0, 0, |ctx| { demo_windows.ui(ctx); }) }); }); - let full_output = ctx.run(RawInput::default(), 0, |ctx| { + let full_output = ctx.run(RawInput::default(), 0, 0, |ctx| { demo_windows.ui(ctx); }); c.bench_function("demo_only_tessellate", |b| { @@ -42,7 +42,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { let mut demo_windows = egui_demo_lib::DemoWindows::default(); c.bench_function("demo_full_no_tessellate", |b| { b.iter(|| { - ctx.run(RawInput::default(), 0, |ctx| { + ctx.run(RawInput::default(), 0, 0, |ctx| { demo_windows.ui(ctx); }) }); @@ -51,7 +51,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { { let ctx = egui::Context::default(); - let _ = ctx.run(RawInput::default(), 0, |ctx| { + let _ = ctx.run(RawInput::default(), 0, 0, |ctx| { egui::CentralPanel::default().show(ctx, |ui| { c.bench_function("label &str", |b| { b.iter(|| { @@ -69,7 +69,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { { let ctx = egui::Context::default(); - ctx.begin_frame(RawInput::default(), 0); + ctx.begin_frame(RawInput::default(), 0, 0); egui::CentralPanel::default().show(&ctx, |ui| { c.bench_function("Painter::rect", |b| { diff --git a/crates/egui_demo_lib/src/lib.rs b/crates/egui_demo_lib/src/lib.rs index 31d2bbcbf..f9c3866bc 100644 --- a/crates/egui_demo_lib/src/lib.rs +++ b/crates/egui_demo_lib/src/lib.rs @@ -68,7 +68,7 @@ fn test_egui_e2e() { const NUM_FRAMES: usize = 5; for _ in 0..NUM_FRAMES { - let full_output = ctx.run(raw_input.clone(), 0, |ctx| { + let full_output = ctx.run(raw_input.clone(), 0, 0, |ctx| { demo_windows.ui(ctx); }); let clipped_primitives = ctx.tessellate(full_output.shapes); @@ -87,7 +87,7 @@ fn test_egui_zero_window_size() { const NUM_FRAMES: usize = 5; for _ in 0..NUM_FRAMES { - let full_output = ctx.run(raw_input.clone(), 0, |ctx| { + let full_output = ctx.run(raw_input.clone(), 0, 0, |ctx| { demo_windows.ui(ctx); }); let clipped_primitives = ctx.tessellate(full_output.shapes); diff --git a/examples/hello_world_simple/src/main.rs b/examples/hello_world_simple/src/main.rs index 268fd48c7..c4d8f4811 100644 --- a/examples/hello_world_simple/src/main.rs +++ b/examples/hello_world_simple/src/main.rs @@ -18,7 +18,7 @@ fn main() -> Result<(), eframe::Error> { egui::CentralPanel::default().show(ctx, |ui| { ui.label(format!( "Current rendering window: {}", - ctx.current_rendering_viewport() + ctx.get_viewport_id() )); ui.heading("My egui Application"); ui.horizontal(|ui| { diff --git a/examples/viewports/Cargo.toml b/examples/viewports/Cargo.toml index 07b2ccd65..9a5200441 100644 --- a/examples/viewports/Cargo.toml +++ b/examples/viewports/Cargo.toml @@ -9,5 +9,5 @@ publish = false [dependencies] -eframe = { path = "../../crates/eframe", features = ["wgpu"] } +eframe = { path = "../../crates/eframe" } env_logger = "0.10" diff --git a/examples/viewports/src/main.rs b/examples/viewports/src/main.rs index b3748682a..45ca6385e 100644 --- a/examples/viewports/src/main.rs +++ b/examples/viewports/src/main.rs @@ -1,4 +1,5 @@ use eframe::egui; +use eframe::egui::window::ViewportBuilder; use eframe::egui::Id; use eframe::NativeOptions; @@ -10,7 +11,7 @@ fn main() { let _ = eframe::run_simple_native( "Viewports Examples", NativeOptions { - renderer: eframe::Renderer::Wgpu, + renderer: eframe::Renderer::Glow, ..NativeOptions::default() }, move |ctx, _frame| { @@ -21,6 +22,22 @@ fn main() { ctx.set_desktop(is_desktop); ui.checkbox(&mut to_repair, "To Repair!"); + ctx.create_viewport_sync( + ViewportBuilder::default().with_title("Sync rendering!"), + |ctx, viewport_id, parent_viewport_id| { + egui::CentralPanel::default().show(ctx, |ui| { + ui.horizontal(|ui| { + ui.label("Viewport ID: "); + ui.label(format!("{viewport_id}")) + }); + ui.horizontal(|ui| { + ui.label("Parent Viewport ID: "); + ui.label(format!("{parent_viewport_id}")) + }); + }) + }, + ); + egui::CollapsingHeader::new("Show Test1").show(ui, |ui| { egui::Window::new("Test1").show(ctx, move |ui, id, parent_id| { ui.label(format!("Frame: {}", ui.ctx().frame_nr())); @@ -40,7 +57,7 @@ fn main() { let ctx = ui.ctx().clone(); ui.label(format!( "Current rendering window: {}", - ctx.current_rendering_viewport() + ctx.get_viewport_id() )); if ui.button("Drag").is_pointer_button_down_on() { if id != parent_id { @@ -71,7 +88,7 @@ fn main() { let ctx = ui.ctx().clone(); ui.label(format!( "Current rendering window: {}", - ctx.current_rendering_viewport() + ctx.get_viewport_id() )); if ui.button("Drag").is_pointer_button_down_on() { @@ -94,7 +111,7 @@ fn main() { let ctx = ui.ctx().clone(); ui.label(format!( "Current rendering window: {}", - ctx.current_rendering_viewport() + ctx.get_viewport_id() )); if ui.button("Drag").is_pointer_button_down_on() {