From d6c2f3e8f36806c6ebf63670fd01d77b4a47da00 Mon Sep 17 00:00:00 2001 From: Konkitoman Date: Sun, 22 Oct 2023 17:15:21 +0300 Subject: [PATCH] Fix pixels per point for multiples viewports Fix ./scripts/check.sh errors --- crates/eframe/src/native/epi_integration.rs | 3 +- crates/eframe/src/native/run.rs | 101 +++++++++++--------- crates/eframe/src/web/app_runner.rs | 4 +- crates/egui-winit/Cargo.toml | 4 +- crates/egui-winit/src/lib.rs | 3 +- crates/egui/src/context.rs | 29 +++--- crates/egui/src/lib.rs | 2 +- crates/egui/src/memory.rs | 3 - crates/egui_demo_lib/benches/benchmark.rs | 6 +- crates/egui_demo_lib/src/lib.rs | 6 +- crates/egui_glow/src/winit.rs | 12 ++- scripts/check.sh | 2 +- 12 files changed, 93 insertions(+), 82 deletions(-) diff --git a/crates/eframe/src/native/epi_integration.rs b/crates/eframe/src/native/epi_integration.rs index 2f1c78eea..e66b136c0 100644 --- a/crates/eframe/src/native/epi_integration.rs +++ b/crates/eframe/src/native/epi_integration.rs @@ -553,10 +553,11 @@ impl EpiIntegration { pub fn handle_platform_output( &mut self, window: &winit::window::Window, + viewport_id: ViewportId, platform_output: egui::PlatformOutput, egui_winit: &mut egui_winit::State, ) { - egui_winit.handle_platform_output(window, &self.egui_ctx, platform_output); + egui_winit.handle_platform_output(window, viewport_id, &self.egui_ctx, platform_output); } // ------------------------------------------------------------------------ diff --git a/crates/eframe/src/native/run.rs b/crates/eframe/src/native/run.rs index c37e52f36..3d7277044 100644 --- a/crates/eframe/src/native/run.rs +++ b/crates/eframe/src/native/run.rs @@ -992,30 +992,6 @@ mod glow_integration { #[cfg(feature = "wgpu")] None, ); - #[cfg(feature = "accesskit")] - { - let window = &glutin_ctx.viewports[&ViewportId::MAIN]; - let window = &mut *window.write(); - integration.init_accesskit( - window.egui_winit.as_mut().unwrap(), - &window.window.as_ref().unwrap().read(), - self.repaint_proxy.lock().clone(), - ); - } - let theme = system_theme.unwrap_or(self.native_options.default_theme); - integration.egui_ctx.set_visuals(theme.egui_visuals()); - - if self.native_options.mouse_passthrough { - glutin_ctx - .window(ViewportId::MAIN) - .read() - .window - .as_ref() - .unwrap() - .read() - .set_cursor_hittest(false) - .unwrap(); - } { let event_loop_proxy = self.repaint_proxy.clone(); @@ -1036,6 +1012,32 @@ mod glow_integration { }); } + #[cfg(feature = "accesskit")] + { + let event_loop_proxy = self.repaint_proxy.lock().clone(); + let window = &glutin_ctx.viewports[&ViewportId::MAIN]; + let window = &mut *window.write(); + integration.init_accesskit( + window.egui_winit.as_mut().unwrap(), + &window.window.as_ref().unwrap().read(), + event_loop_proxy, + ); + } + let theme = system_theme.unwrap_or(self.native_options.default_theme); + integration.egui_ctx.set_visuals(theme.egui_visuals()); + + if self.native_options.mouse_passthrough { + glutin_ctx + .window(ViewportId::MAIN) + .read() + .window + .as_ref() + .unwrap() + .read() + .set_cursor_hittest(false) + .unwrap(); + } + let app_creator = std::mem::take(&mut self.app_creator) .expect("Single-use AppCreator has unexpectedly already been taken"); let mut app; @@ -1172,7 +1174,7 @@ mod glow_integration { let screen_size_in_pixels: [u32; 2] = win.inner_size().into(); - let clipped_primitives = egui_ctx.tessellate(output.shapes); + let clipped_primitives = egui_ctx.tessellate(output.shapes, pair.this); glutin.current_gl_context = Some( glutin @@ -1197,9 +1199,10 @@ mod glow_integration { egui_glow::painter::clear(gl, screen_size_in_pixels, [0.0, 0.0, 0.0, 0.0]); + let pixels_per_point = egui_ctx.input_for(pair.this, |i| i.pixels_per_point()); painter.write().paint_and_update_textures( screen_size_in_pixels, - egui_ctx.pixels_per_point(), + pixels_per_point, &clipped_primitives, &output.textures_delta, ); @@ -1214,7 +1217,7 @@ mod glow_integration { .as_ref() .expect("failed to get current context to swap buffers"), ); - winit_state.handle_platform_output(&win, egui_ctx, output.platform_output); + winit_state.handle_platform_output(&win, pair.this, egui_ctx, output.platform_output); } fn process_viewport_builders( @@ -1422,7 +1425,6 @@ mod glow_integration { let control_flow; { - // let window = gl_window.window(window_index); let win = glutin.read().viewports.get(&viewport_id).cloned(); let win = win.unwrap(); @@ -1453,6 +1455,7 @@ mod glow_integration { integration.write().handle_platform_output( &win.window.as_ref().unwrap().read(), + viewport_id, platform_output, win.egui_winit.as_mut().unwrap(), ); @@ -1460,7 +1463,7 @@ mod glow_integration { let clipped_primitives = { crate::profile_scope!("tessellate"); - integration.read().egui_ctx.tessellate(shapes) + integration.read().egui_ctx.tessellate(shapes, viewport_id) }; { let mut gl_window = glutin.write(); @@ -1485,9 +1488,14 @@ mod glow_integration { .clear_color(&integration.read().egui_ctx.style().visuals), ); + let pixels_per_point = integration + .read() + .egui_ctx + .input_for(viewport_id, |i| i.pixels_per_point()); + painter.write().paint_and_update_textures( screen_size_in_pixels, - integration.read().egui_ctx.pixels_per_point(), + pixels_per_point, &clipped_primitives, &textures_delta, ); @@ -2020,14 +2028,6 @@ mod wgpu_integration { wgpu_render_state.clone(), ); - let mut state = egui_winit::State::new(event_loop); - #[cfg(feature = "accesskit")] - { - integration.init_accesskit(&mut state, &window, self.repaint_proxy.lock().clone()); - } - let theme = system_theme.unwrap_or(self.native_options.default_theme); - integration.egui_ctx.set_visuals(theme.egui_visuals()); - { let event_loop_proxy = self.repaint_proxy.clone(); @@ -2049,6 +2049,15 @@ mod wgpu_integration { }); } + let mut state = egui_winit::State::new(event_loop); + #[cfg(feature = "accesskit")] + { + let event_loop_proxy = self.repaint_proxy.lock().clone(); + integration.init_accesskit(&mut state, &window, event_loop_proxy); + } + let theme = system_theme.unwrap_or(self.native_options.default_theme); + integration.egui_ctx.set_visuals(theme.egui_visuals()); + let app_creator = std::mem::take(&mut self.app_creator) .expect("Single-use AppCreator has unexpectedly already been taken"); let cc = epi::CreationContext { @@ -2204,17 +2213,18 @@ mod wgpu_integration { ); } - let clipped_primitives = egui_ctx.tessellate(output.shapes); + let pixels_per_point = egui_ctx.input_for(pair.this, |i| i.pixels_per_point()); + let clipped_primitives = egui_ctx.tessellate(output.shapes, pair.this); c_painter.write().paint_and_update_textures( pair.this, - egui_ctx.pixels_per_point(), + pixels_per_point, [0.0, 0.0, 0.0, 0.0], &clipped_primitives, &output.textures_delta, false, ); - winit_state.handle_platform_output(&win, egui_ctx, output.platform_output); + winit_state.handle_platform_output(&win, pair.this, egui_ctx, output.platform_output); } } @@ -2341,21 +2351,26 @@ mod wgpu_integration { integration.write().handle_platform_output( &window.read(), + viewport_id, platform_output, state.write().as_mut().unwrap(), ); let clipped_primitives = { crate::profile_scope!("tessellate"); - integration.read().egui_ctx.tessellate(shapes) + integration.read().egui_ctx.tessellate(shapes, viewport_id) }; let integration = &mut *integration.write(); let screenshot_requested = &mut integration.frame.output.screenshot_requested; + let pixels_per_point = integration + .egui_ctx + .input_for(viewport_id, |i| i.pixels_per_point()); + let screenshot = painter.write().paint_and_update_textures( viewport_id, - integration.egui_ctx.pixels_per_point(), + pixels_per_point, app.clear_color(&integration.egui_ctx.style().visuals), &clipped_primitives, &textures_delta, diff --git a/crates/eframe/src/web/app_runner.rs b/crates/eframe/src/web/app_runner.rs index a750c1334..2d884a515 100644 --- a/crates/eframe/src/web/app_runner.rs +++ b/crates/eframe/src/web/app_runner.rs @@ -1,5 +1,5 @@ use egui::TexturesDelta; -use egui::ViewportIdPair; +use egui::{ViewportId, ViewportIdPair}; use wasm_bindgen::JsValue; use crate::{epi, App}; @@ -195,7 +195,7 @@ impl AppRunner { self.handle_platform_output(platform_output); self.textures_delta.append(textures_delta); - let clipped_primitives = self.egui_ctx.tessellate(shapes); + let clipped_primitives = self.egui_ctx.tessellate(shapes, ViewportId::MAIN); { let app_output = self.frame.take_app_output(); diff --git a/crates/egui-winit/Cargo.toml b/crates/egui-winit/Cargo.toml index e48c2b074..4a13d23a8 100644 --- a/crates/egui-winit/Cargo.toml +++ b/crates/egui-winit/Cargo.toml @@ -49,10 +49,10 @@ puffin = ["dep:puffin", "egui/puffin"] serde = ["egui/serde", "dep:serde"] ## Enables Wayland support. -wayland = ["winit/wayland"] +wayland = ["winit/wayland", "bytemuck"] ## Enables compiling for x11. -x11 = ["winit/x11"] +x11 = ["winit/x11", "bytemuck"] [dependencies] egui = { version = "0.23.0", path = "../egui", default-features = false, features = [ diff --git a/crates/egui-winit/src/lib.rs b/crates/egui-winit/src/lib.rs index 9ba253407..9105f6713 100644 --- a/crates/egui-winit/src/lib.rs +++ b/crates/egui-winit/src/lib.rs @@ -706,6 +706,7 @@ impl State { pub fn handle_platform_output( &mut self, window: &winit::window::Window, + viewport_id: ViewportId, egui_ctx: &egui::Context, platform_output: egui::PlatformOutput, ) { @@ -719,7 +720,7 @@ impl State { #[cfg(feature = "accesskit")] accesskit_update, } = platform_output; - self.current_pixels_per_point = egui_ctx.pixels_per_point(); // someone can have changed it to scale the UI + self.current_pixels_per_point = egui_ctx.input_for(viewport_id, |i| i.pixels_per_point); // someone can have changed it to scale the UI self.set_cursor_icon(window, cursor_icon); diff --git a/crates/egui/src/context.rs b/crates/egui/src/context.rs index 70c2f02a6..96034bb56 100644 --- a/crates/egui/src/context.rs +++ b/crates/egui/src/context.rs @@ -85,7 +85,7 @@ impl Repaint { }; (callback)(info); } else { - log::warn!("request_repaint_callback is not implemented by egui integration!\nIf is your integration you need to call `Context::set_request_repaint_callback`"); + eprint!("request_repaint_callback is not implemented by egui integration!\nIf is your integration you need to call `Context::set_request_repaint_callback`"); } } @@ -213,15 +213,12 @@ impl ContextImpl { if let Some(new_pixels_per_point) = self.memory.override_pixels_per_point { if self - .memory - .pixels_per_point_viewports + .input .get(&pair) - .map_or(true, |pixels| *pixels != new_pixels_per_point) + .map(|input| input.pixels_per_point) + .map_or(true, |pixels| pixels != new_pixels_per_point) { new_raw_input.pixels_per_point = Some(new_pixels_per_point); - self.memory - .pixels_per_point_viewports - .insert(pair.this, new_pixels_per_point); let input = self.input.entry(pair.this).or_default(); // This is a bit hacky, but is required to avoid jitter: @@ -230,7 +227,6 @@ impl ContextImpl { rect.min = (ratio * rect.min.to_vec2()).to_pos2(); rect.max = (ratio * rect.max.to_vec2()).to_pos2(); new_raw_input.screen_rect = Some(rect); - self.repaint.request_repaint_settle(pair.this); } } @@ -409,7 +405,7 @@ impl ContextImpl { /// }); /// }); /// handle_platform_output(full_output.platform_output); -/// let clipped_primitives = ctx.tessellate(full_output.shapes); // create triangles to paint +/// let clipped_primitives = ctx.tessellate(full_output.shapes, egui::ViewportId::MAIN); // create triangles to paint /// paint(full_output.textures_delta, clipped_primitives); /// } /// ``` @@ -1645,9 +1641,6 @@ impl Context { .retain(|id, _| avalibile_viewports.contains(id)); ctx.graphics .retain(|id, _| avalibile_viewports.contains(id)); - ctx.memory - .pixels_per_point_viewports - .retain(|id, _| avalibile_viewports.contains(id)); }); } @@ -1679,7 +1672,11 @@ impl Context { } /// Tessellate the given shapes into triangle meshes. - pub fn tessellate(&self, shapes: Vec) -> Vec { + pub fn tessellate( + &self, + shapes: Vec, + viewport_id: ViewportId, + ) -> Vec { crate::profile_function!(); // A tempting optimization is to reuse the tessellation from last frame if the @@ -1687,12 +1684,8 @@ impl Context { // it takes to tessellate them, so it is not a worth optimization. // here we expect that we are the only user of context, since frame is ended + let pixels_per_point = self.input_for(viewport_id, |i| i.pixels_per_point()); self.write(|ctx| { - let pixels_per_point = ctx - .input - .entry(ctx.viewport_id()) - .or_default() - .pixels_per_point(); let tessellation_options = ctx.memory.options.tessellation_options; let texture_atlas = ctx .fonts diff --git a/crates/egui/src/lib.rs b/crates/egui/src/lib.rs index fe3c91223..029311ecd 100644 --- a/crates/egui/src/lib.rs +++ b/crates/egui/src/lib.rs @@ -134,7 +134,7 @@ //! }); //! }); //! handle_platform_output(full_output.platform_output); -//! let clipped_primitives = ctx.tessellate(full_output.shapes); // create triangles to paint +//! let clipped_primitives = ctx.tessellate(full_output.shapes, egui::ViewportId::MAIN); // create triangles to paint //! paint(full_output.textures_delta, clipped_primitives); //! } //! ``` diff --git a/crates/egui/src/memory.rs b/crates/egui/src/memory.rs index 63bd1f457..8dcfe1365 100644 --- a/crates/egui/src/memory.rs +++ b/crates/egui/src/memory.rs @@ -72,9 +72,6 @@ pub struct Memory { #[cfg_attr(feature = "persistence", serde(skip))] pub(crate) override_pixels_per_point: Option, - #[cfg_attr(feature = "persistence", serde(skip))] - pub(crate) pixels_per_point_viewports: HashMap, - /// new fonts that will be applied at the start of the next frame #[cfg_attr(feature = "persistence", serde(skip))] pub(crate) new_font_definitions: Option, diff --git a/crates/egui_demo_lib/benches/benchmark.rs b/crates/egui_demo_lib/benches/benchmark.rs index f8ed63dbf..b1dda1a05 100644 --- a/crates/egui_demo_lib/benches/benchmark.rs +++ b/crates/egui_demo_lib/benches/benchmark.rs @@ -1,6 +1,6 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use egui::{epaint::TextShape, ViewportIdPair}; +use egui::{epaint::TextShape, ViewportId, ViewportIdPair}; use egui_demo_lib::LOREM_IPSUM_LONG; pub fn criterion_benchmark(c: &mut Criterion) { @@ -16,7 +16,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { let full_output = ctx.run(RawInput::default(), ViewportIdPair::MAIN, |ctx| { demo_windows.ui(ctx); }); - ctx.tessellate(full_output.shapes) + ctx.tessellate(full_output.shapes, ViewportId::MAIN) }); }); @@ -32,7 +32,7 @@ pub fn criterion_benchmark(c: &mut Criterion) { demo_windows.ui(ctx); }); c.bench_function("demo_only_tessellate", |b| { - b.iter(|| ctx.tessellate(full_output.shapes.clone())); + b.iter(|| ctx.tessellate(full_output.shapes.clone(), ViewportId::MAIN)); }); } diff --git a/crates/egui_demo_lib/src/lib.rs b/crates/egui_demo_lib/src/lib.rs index 578fd92b9..471550fe4 100644 --- a/crates/egui_demo_lib/src/lib.rs +++ b/crates/egui_demo_lib/src/lib.rs @@ -19,7 +19,7 @@ pub mod easy_mark; pub use color_test::ColorTest; pub use demo::DemoWindows; #[cfg(test)] -use egui::ViewportIdPair; +use egui::{ViewportId, ViewportIdPair}; /// View some Rust code with syntax highlighting and selection. pub(crate) fn rust_view_ui(ui: &mut egui::Ui, code: &str) { @@ -79,7 +79,7 @@ fn test_egui_e2e() { let full_output = ctx.run(raw_input.clone(), ViewportIdPair::MAIN, |ctx| { demo_windows.ui(ctx); }); - let clipped_primitives = ctx.tessellate(full_output.shapes); + let clipped_primitives = ctx.tessellate(full_output.shapes, ViewportId::MAIN); assert!(!clipped_primitives.is_empty()); } } @@ -98,7 +98,7 @@ fn test_egui_zero_window_size() { let full_output = ctx.run(raw_input.clone(), ViewportIdPair::MAIN, |ctx| { demo_windows.ui(ctx); }); - let clipped_primitives = ctx.tessellate(full_output.shapes); + let clipped_primitives = ctx.tessellate(full_output.shapes, ViewportId::MAIN); assert!( clipped_primitives.is_empty(), "There should be nothing to show, has at least one primitive with clip_rect: {:?}", diff --git a/crates/egui_glow/src/winit.rs b/crates/egui_glow/src/winit.rs index 7dee347eb..1c2885958 100644 --- a/crates/egui_glow/src/winit.rs +++ b/crates/egui_glow/src/winit.rs @@ -1,5 +1,5 @@ use crate::shader_version::ShaderVersion; -use egui::ViewportIdPair; +use egui::{ViewportId, ViewportIdPair}; pub use egui_winit; use egui_winit::winit; pub use egui_winit::EventResponse; @@ -52,8 +52,12 @@ impl EguiGlow { .. } = self.egui_ctx.run(raw_input, ViewportIdPair::MAIN, run_ui); - self.egui_winit - .handle_platform_output(window, &self.egui_ctx, platform_output); + self.egui_winit.handle_platform_output( + window, + ViewportId::MAIN, + &self.egui_ctx, + platform_output, + ); self.shapes = shapes; self.textures_delta.append(textures_delta); @@ -68,7 +72,7 @@ impl EguiGlow { self.painter.set_texture(id, &image_delta); } - let clipped_primitives = self.egui_ctx.tessellate(shapes); + let clipped_primitives = self.egui_ctx.tessellate(shapes, ViewportId::MAIN); let dimensions: [u32; 2] = window.inner_size().into(); self.painter.paint_primitives( dimensions, diff --git a/scripts/check.sh b/scripts/check.sh index f0491f0d2..4ceb47d49 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -37,7 +37,7 @@ cargo doc --document-private-items --no-deps --all-features (cd crates/egui_extras && cargo check --no-default-features) (cd crates/egui_glow && cargo check --no-default-features) (cd crates/egui-winit && cargo check --no-default-features --features "wayland") -(cd crates/egui-winit && cargo check --no-default-features --features "winit/x11") +(cd crates/egui-winit && cargo check --no-default-features --features "x11") (cd crates/emath && cargo check --no-default-features) (cd crates/epaint && cargo check --no-default-features --release) (cd crates/epaint && cargo check --no-default-features)