mirror of
https://github.com/emilk/egui.git
synced 2026-09-01 06:10:06 -04:00
"Final" touch-ups on wgpu integration
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
//! Note that this file contains two similar paths - one for [`glow`], one for [`wgpu`].
|
//! Note that this file contains two similar paths - one for [`glow`], one for [`wgpu`].
|
||||||
//! When making changes to one you often also want to apply it to the other.
|
//! When making changes to one you often also want to apply it to the other.
|
||||||
|
//!
|
||||||
|
//! This is also very complex code, and not very pretty.
|
||||||
|
//! There is a bunch of improvements we could do,
|
||||||
|
//! like removing a bunch of `unwraps`.
|
||||||
|
|
||||||
use std::{cell::RefCell, rc::Rc, sync::Arc, time::Instant};
|
use std::{cell::RefCell, rc::Rc, sync::Arc, time::Instant};
|
||||||
|
|
||||||
@@ -96,8 +100,6 @@ trait WinitApp {
|
|||||||
|
|
||||||
fn window_id_from_viewport_id(&self, id: ViewportId) -> Option<WindowId>;
|
fn window_id_from_viewport_id(&self, id: ViewportId) -> Option<WindowId>;
|
||||||
|
|
||||||
fn viewport_id_from_window_id(&self, id: &WindowId) -> Option<ViewportId>;
|
|
||||||
|
|
||||||
fn save_and_destroy(&mut self);
|
fn save_and_destroy(&mut self);
|
||||||
|
|
||||||
fn run_ui_and_paint(&mut self, window_id: WindowId) -> EventResult;
|
fn run_ui_and_paint(&mut self, window_id: WindowId) -> EventResult;
|
||||||
@@ -492,12 +494,7 @@ mod glow_integration {
|
|||||||
window_id: WindowId,
|
window_id: WindowId,
|
||||||
focused_viewport: Option<ViewportId>,
|
focused_viewport: Option<ViewportId>,
|
||||||
) -> EventResult {
|
) -> EventResult {
|
||||||
let Some(viewport_id) = self
|
let Some(viewport_id) = self.glutin.borrow().viewport_from_window.get(&window_id).copied()
|
||||||
.glutin
|
|
||||||
.borrow()
|
|
||||||
.viewport_maps
|
|
||||||
.get(&window_id)
|
|
||||||
.copied()
|
|
||||||
else {
|
else {
|
||||||
return EventResult::Wait;
|
return EventResult::Wait;
|
||||||
};
|
};
|
||||||
@@ -511,10 +508,10 @@ mod glow_integration {
|
|||||||
let viewport = &glutin.viewports[&viewport_id];
|
let viewport = &glutin.viewports[&viewport_id];
|
||||||
let is_immediate = viewport.viewport_ui_cb.is_none();
|
let is_immediate = viewport.viewport_ui_cb.is_none();
|
||||||
if is_immediate && viewport_id != ViewportId::ROOT {
|
if is_immediate && viewport_id != ViewportId::ROOT {
|
||||||
|
// 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(parent_viewport) = glutin.viewports.get(&viewport.ids.parent) {
|
if let Some(parent_viewport) = glutin.viewports.get(&viewport.ids.parent) {
|
||||||
if let Some(window) = parent_viewport.window.as_ref() {
|
if let Some(window) = parent_viewport.window.as_ref() {
|
||||||
// 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.
|
|
||||||
return EventResult::RepaintNext(window.id());
|
return EventResult::RepaintNext(window.id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -553,6 +550,9 @@ mod glow_integration {
|
|||||||
..
|
..
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
|
let mut glutin = glutin.borrow_mut();
|
||||||
|
let mut painter = painter.borrow_mut();
|
||||||
|
|
||||||
let egui::FullOutput {
|
let egui::FullOutput {
|
||||||
platform_output,
|
platform_output,
|
||||||
textures_delta,
|
textures_delta,
|
||||||
@@ -561,7 +561,6 @@ mod glow_integration {
|
|||||||
viewport_commands,
|
viewport_commands,
|
||||||
} = full_output;
|
} = full_output;
|
||||||
|
|
||||||
let mut glutin = glutin.borrow_mut();
|
|
||||||
let GlutinWindowContext {
|
let GlutinWindowContext {
|
||||||
viewports,
|
viewports,
|
||||||
current_gl_context,
|
current_gl_context,
|
||||||
@@ -569,41 +568,36 @@ mod glow_integration {
|
|||||||
} = &mut *glutin;
|
} = &mut *glutin;
|
||||||
let viewport = viewports.get_mut(&viewport_id).unwrap();
|
let viewport = viewports.get_mut(&viewport_id).unwrap();
|
||||||
let window = viewport.window.as_ref().unwrap();
|
let window = viewport.window.as_ref().unwrap();
|
||||||
|
let gl_surface = viewport.gl_surface.as_ref().unwrap();
|
||||||
|
let egui_winit = viewport.egui_winit.as_mut().unwrap();
|
||||||
|
|
||||||
integration.post_update(app.as_mut(), window);
|
integration.post_update(app.as_mut(), window);
|
||||||
integration.handle_platform_output(
|
integration.handle_platform_output(window, viewport_id, platform_output, egui_winit);
|
||||||
window,
|
|
||||||
viewport_id,
|
|
||||||
platform_output,
|
|
||||||
viewport.egui_winit.as_mut().unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let clipped_primitives = integration.egui_ctx.tessellate(shapes);
|
|
||||||
|
|
||||||
if let Some(gl_surface) = &viewport.gl_surface {
|
|
||||||
*current_gl_context = Some(
|
|
||||||
current_gl_context
|
|
||||||
.take()
|
|
||||||
.unwrap()
|
|
||||||
.make_not_current()
|
|
||||||
.unwrap()
|
|
||||||
.make_current(gl_surface)
|
|
||||||
.unwrap(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let screen_size_in_pixels: [u32; 2] = window.inner_size().into();
|
|
||||||
|
|
||||||
painter.borrow().clear(
|
|
||||||
screen_size_in_pixels,
|
|
||||||
app.clear_color(&integration.egui_ctx.style().visuals),
|
|
||||||
);
|
|
||||||
|
|
||||||
let pixels_per_point = integration
|
let pixels_per_point = integration
|
||||||
.egui_ctx
|
.egui_ctx
|
||||||
.input_for(viewport_id, |i| i.pixels_per_point());
|
.input_for(viewport_id, |i| i.pixels_per_point());
|
||||||
|
|
||||||
painter.borrow_mut().paint_and_update_textures(
|
let clipped_primitives = integration.egui_ctx.tessellate(shapes, pixels_per_point);
|
||||||
|
|
||||||
|
*current_gl_context = Some(
|
||||||
|
current_gl_context
|
||||||
|
.take()
|
||||||
|
.unwrap()
|
||||||
|
.make_not_current()
|
||||||
|
.unwrap()
|
||||||
|
.make_current(gl_surface)
|
||||||
|
.unwrap(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let screen_size_in_pixels: [u32; 2] = window.inner_size().into();
|
||||||
|
|
||||||
|
painter.clear(
|
||||||
|
screen_size_in_pixels,
|
||||||
|
app.clear_color(&integration.egui_ctx.style().visuals),
|
||||||
|
);
|
||||||
|
|
||||||
|
painter.paint_and_update_textures(
|
||||||
screen_size_in_pixels,
|
screen_size_in_pixels,
|
||||||
pixels_per_point,
|
pixels_per_point,
|
||||||
&clipped_primitives,
|
&clipped_primitives,
|
||||||
@@ -612,39 +606,32 @@ mod glow_integration {
|
|||||||
|
|
||||||
{
|
{
|
||||||
let screenshot_requested = &mut integration.frame.output.screenshot_requested;
|
let screenshot_requested = &mut integration.frame.output.screenshot_requested;
|
||||||
|
|
||||||
if *screenshot_requested {
|
if *screenshot_requested {
|
||||||
*screenshot_requested = false;
|
*screenshot_requested = false;
|
||||||
let screenshot = painter.borrow().read_screen_rgba(screen_size_in_pixels);
|
let screenshot = painter.read_screen_rgba(screen_size_in_pixels);
|
||||||
integration.frame.screenshot.set(Some(screenshot));
|
integration.frame.screenshot.set(Some(screenshot));
|
||||||
}
|
}
|
||||||
|
integration.post_rendering(app.as_mut(), window);
|
||||||
integration.post_rendering(app.as_mut(), viewport.window.as_ref().unwrap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
crate::profile_scope!("swap_buffers");
|
crate::profile_scope!("swap_buffers");
|
||||||
if let Err(err) = viewport
|
if let Err(err) = gl_surface.swap_buffers(
|
||||||
.gl_surface
|
current_gl_context
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.expect("failed to get surface to swap buffers")
|
.expect("failed to get current context to swap buffers"),
|
||||||
.swap_buffers(
|
) {
|
||||||
current_gl_context
|
|
||||||
.as_ref()
|
|
||||||
.expect("failed to get current context to swap buffers"),
|
|
||||||
)
|
|
||||||
{
|
|
||||||
log::error!("swap_buffers failed: {err}");
|
log::error!("swap_buffers failed: {err}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
integration.post_present(viewport.window.as_ref().unwrap());
|
integration.post_present(window);
|
||||||
|
|
||||||
// give it time to settle:
|
// give it time to settle:
|
||||||
#[cfg(feature = "__screenshot")]
|
#[cfg(feature = "__screenshot")]
|
||||||
if integration.egui_ctx.frame_nr() == 2 {
|
if integration.egui_ctx.frame_nr() == 2 {
|
||||||
if let Ok(path) = std::env::var("EFRAME_SCREENSHOT_TO") {
|
if let Ok(path) = std::env::var("EFRAME_SCREENSHOT_TO") {
|
||||||
save_screeshot_and_exit(&path, painter, screen_size_in_pixels);
|
save_screeshot_and_exit(&path, &painter, screen_size_in_pixels);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,14 +669,14 @@ mod glow_integration {
|
|||||||
|
|
||||||
fn save_screeshot_and_exit(
|
fn save_screeshot_and_exit(
|
||||||
path: &str,
|
path: &str,
|
||||||
painter: &mut Rc<RefCell<egui_glow::Painter>>,
|
painter: &egui_glow::Painter,
|
||||||
screen_size_in_pixels: [u32; 2],
|
screen_size_in_pixels: [u32; 2],
|
||||||
) {
|
) {
|
||||||
assert!(
|
assert!(
|
||||||
path.ends_with(".png"),
|
path.ends_with(".png"),
|
||||||
"Expected EFRAME_SCREENSHOT_TO to end with '.png', got {path:?}"
|
"Expected EFRAME_SCREENSHOT_TO to end with '.png', got {path:?}"
|
||||||
);
|
);
|
||||||
let screenshot = painter.borrow().read_screen_rgba(screen_size_in_pixels);
|
let screenshot = painter.read_screen_rgba(screen_size_in_pixels);
|
||||||
image::save_buffer(
|
image::save_buffer(
|
||||||
path,
|
path,
|
||||||
screenshot.as_raw(),
|
screenshot.as_raw(),
|
||||||
@@ -742,7 +729,7 @@ mod glow_integration {
|
|||||||
not_current_gl_context: Option<glutin::context::NotCurrentContext>,
|
not_current_gl_context: Option<glutin::context::NotCurrentContext>,
|
||||||
|
|
||||||
viewports: ViewportIdMap<Viewport>,
|
viewports: ViewportIdMap<Viewport>,
|
||||||
viewport_maps: HashMap<WindowId, ViewportId>,
|
viewport_from_window: HashMap<WindowId, ViewportId>,
|
||||||
window_maps: ViewportIdMap<WindowId>,
|
window_maps: ViewportIdMap<WindowId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -859,10 +846,10 @@ mod glow_integration {
|
|||||||
};
|
};
|
||||||
let not_current_gl_context = Some(gl_context);
|
let not_current_gl_context = Some(gl_context);
|
||||||
|
|
||||||
let mut viewport_maps = HashMap::default();
|
let mut viewport_from_window = HashMap::default();
|
||||||
let mut window_maps = ViewportIdMap::default();
|
let mut window_maps = ViewportIdMap::default();
|
||||||
if let Some(window) = &window {
|
if let Some(window) = &window {
|
||||||
viewport_maps.insert(window.id(), ViewportId::ROOT);
|
viewport_from_window.insert(window.id(), ViewportId::ROOT);
|
||||||
window_maps.insert(ViewportId::ROOT, window.id());
|
window_maps.insert(ViewportId::ROOT, window.id());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,7 +877,7 @@ mod glow_integration {
|
|||||||
current_gl_context: None,
|
current_gl_context: None,
|
||||||
not_current_gl_context,
|
not_current_gl_context,
|
||||||
viewports,
|
viewports,
|
||||||
viewport_maps,
|
viewport_from_window,
|
||||||
max_texture_side: None,
|
max_texture_side: None,
|
||||||
window_maps,
|
window_maps,
|
||||||
};
|
};
|
||||||
@@ -998,7 +985,8 @@ mod glow_integration {
|
|||||||
|
|
||||||
viewport.gl_surface = Some(gl_surface);
|
viewport.gl_surface = Some(gl_surface);
|
||||||
self.current_gl_context = Some(current_gl_context);
|
self.current_gl_context = Some(current_gl_context);
|
||||||
self.viewport_maps.insert(window.id(), viewport.ids.this);
|
self.viewport_from_window
|
||||||
|
.insert(window.id(), viewport.ids.this);
|
||||||
self.window_maps.insert(viewport.ids.this, window.id());
|
self.window_maps.insert(viewport.ids.this, window.id());
|
||||||
}
|
}
|
||||||
viewport.window = Some(window);
|
viewport.window = Some(window);
|
||||||
@@ -1102,7 +1090,7 @@ mod glow_integration {
|
|||||||
// GC old viewports
|
// GC old viewports
|
||||||
self.viewports
|
self.viewports
|
||||||
.retain(|id, _| active_viewports_ids.contains(id));
|
.retain(|id, _| active_viewports_ids.contains(id));
|
||||||
self.viewport_maps
|
self.viewport_from_window
|
||||||
.retain(|_, id| active_viewports_ids.contains(id));
|
.retain(|_, id| active_viewports_ids.contains(id));
|
||||||
self.window_maps
|
self.window_maps
|
||||||
.retain(|id, _| active_viewports_ids.contains(id));
|
.retain(|id, _| active_viewports_ids.contains(id));
|
||||||
@@ -1479,7 +1467,8 @@ mod glow_integration {
|
|||||||
|
|
||||||
let screen_size_in_pixels: [u32; 2] = window.inner_size().into();
|
let screen_size_in_pixels: [u32; 2] = window.inner_size().into();
|
||||||
|
|
||||||
let clipped_primitives = egui_ctx.tessellate(output.shapes);
|
let pixels_per_point = egui_ctx.input_for(ids.this, |i| i.pixels_per_point());
|
||||||
|
let clipped_primitives = egui_ctx.tessellate(output.shapes, pixels_per_point);
|
||||||
|
|
||||||
let mut painter = painter.borrow_mut();
|
let mut painter = painter.borrow_mut();
|
||||||
|
|
||||||
@@ -1507,7 +1496,6 @@ mod glow_integration {
|
|||||||
let gl = &painter.gl().clone();
|
let gl = &painter.gl().clone();
|
||||||
egui_glow::painter::clear(gl, screen_size_in_pixels, [0.0, 0.0, 0.0, 0.0]);
|
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(ids.this, |i| i.pixels_per_point());
|
|
||||||
painter.paint_and_update_textures(
|
painter.paint_and_update_textures(
|
||||||
screen_size_in_pixels,
|
screen_size_in_pixels,
|
||||||
pixels_per_point,
|
pixels_per_point,
|
||||||
@@ -1540,7 +1528,9 @@ mod glow_integration {
|
|||||||
fn is_focused(&self, window_id: WindowId) -> bool {
|
fn is_focused(&self, window_id: WindowId) -> bool {
|
||||||
if let Some(focused_viewport) = self.focused_viewport {
|
if let Some(focused_viewport) = self.focused_viewport {
|
||||||
if let Some(running) = self.running.as_ref() {
|
if let Some(running) = self.running.as_ref() {
|
||||||
if let Some(window_id) = running.glutin.borrow().viewport_maps.get(&window_id) {
|
if let Some(window_id) =
|
||||||
|
running.glutin.borrow().viewport_from_window.get(&window_id)
|
||||||
|
{
|
||||||
return focused_viewport == *window_id;
|
return focused_viewport == *window_id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1555,7 +1545,7 @@ mod glow_integration {
|
|||||||
fn window(&self, window_id: WindowId) -> Option<Rc<Window>> {
|
fn window(&self, window_id: WindowId) -> Option<Rc<Window>> {
|
||||||
let running = self.running.as_ref()?;
|
let running = self.running.as_ref()?;
|
||||||
let glutin = running.glutin.borrow();
|
let glutin = running.glutin.borrow();
|
||||||
let viewport_id = *glutin.viewport_maps.get(&window_id)?;
|
let viewport_id = *glutin.viewport_from_window.get(&window_id)?;
|
||||||
if let Some(viewport) = glutin.viewports.get(&viewport_id) {
|
if let Some(viewport) = glutin.viewports.get(&viewport_id) {
|
||||||
viewport.window.clone()
|
viewport.window.clone()
|
||||||
} else {
|
} else {
|
||||||
@@ -1569,12 +1559,6 @@ mod glow_integration {
|
|||||||
.and_then(|r| r.glutin.borrow().window_maps.get(&id).copied())
|
.and_then(|r| r.glutin.borrow().window_maps.get(&id).copied())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn viewport_id_from_window_id(&self, id: &WindowId) -> Option<ViewportId> {
|
|
||||||
self.running
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|r| r.glutin.borrow().viewport_maps.get(id).copied())
|
|
||||||
}
|
|
||||||
|
|
||||||
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() {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
@@ -1670,7 +1654,7 @@ mod glow_integration {
|
|||||||
running
|
running
|
||||||
.glutin
|
.glutin
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.viewport_maps
|
.viewport_from_window
|
||||||
.get(window_id)
|
.get(window_id)
|
||||||
.copied()
|
.copied()
|
||||||
})
|
})
|
||||||
@@ -1684,7 +1668,7 @@ mod glow_integration {
|
|||||||
// This solves an issue where the app would panic when minimizing on Windows.
|
// This solves an issue where the app would panic when minimizing on Windows.
|
||||||
let glutin = &mut *running.glutin.borrow_mut();
|
let glutin = &mut *running.glutin.borrow_mut();
|
||||||
if 0 < physical_size.width && 0 < physical_size.height {
|
if 0 < physical_size.width && 0 < physical_size.height {
|
||||||
if let Some(id) = glutin.viewport_maps.get(window_id) {
|
if let Some(id) = glutin.viewport_from_window.get(window_id) {
|
||||||
glutin.resize(*id, *physical_size);
|
glutin.resize(*id, *physical_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1695,7 +1679,7 @@ mod glow_integration {
|
|||||||
} => {
|
} => {
|
||||||
let glutin = &mut *running.glutin.borrow_mut();
|
let glutin = &mut *running.glutin.borrow_mut();
|
||||||
repaint_asap = true;
|
repaint_asap = true;
|
||||||
if let Some(id) = glutin.viewport_maps.get(window_id) {
|
if let Some(id) = glutin.viewport_from_window.get(window_id) {
|
||||||
glutin.resize(*id, **new_inner_size);
|
glutin.resize(*id, **new_inner_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1703,7 +1687,7 @@ mod glow_integration {
|
|||||||
if running
|
if running
|
||||||
.glutin
|
.glutin
|
||||||
.borrow()
|
.borrow()
|
||||||
.viewport_maps
|
.viewport_from_window
|
||||||
.get(window_id)
|
.get(window_id)
|
||||||
.map_or(false, |id| *id == ViewportId::ROOT)
|
.map_or(false, |id| *id == ViewportId::ROOT)
|
||||||
&& running.integration.should_close() =>
|
&& running.integration.should_close() =>
|
||||||
@@ -1716,7 +1700,8 @@ mod glow_integration {
|
|||||||
|
|
||||||
let event_response = 'res: {
|
let event_response = 'res: {
|
||||||
let mut glutin = running.glutin.borrow_mut();
|
let mut glutin = running.glutin.borrow_mut();
|
||||||
if let Some(viewport_id) = glutin.viewport_maps.get(window_id).copied()
|
if let Some(viewport_id) =
|
||||||
|
glutin.viewport_from_window.get(window_id).copied()
|
||||||
{
|
{
|
||||||
if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) {
|
if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) {
|
||||||
break 'res running.integration.on_event(
|
break 'res running.integration.on_event(
|
||||||
@@ -1758,7 +1743,9 @@ mod glow_integration {
|
|||||||
crate::profile_scope!("on_accesskit_action_request");
|
crate::profile_scope!("on_accesskit_action_request");
|
||||||
|
|
||||||
let mut glutin = running.glutin.borrow_mut();
|
let mut glutin = running.glutin.borrow_mut();
|
||||||
if let Some(viewport_id) = glutin.viewport_maps.get(window_id).copied() {
|
if let Some(viewport_id) =
|
||||||
|
glutin.viewport_from_window.get(window_id).copied()
|
||||||
|
{
|
||||||
if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) {
|
if let Some(viewport) = glutin.viewports.get_mut(&viewport_id) {
|
||||||
viewport
|
viewport
|
||||||
.egui_winit
|
.egui_winit
|
||||||
@@ -1823,8 +1810,11 @@ mod wgpu_integration {
|
|||||||
/// `None` for sync viewports.
|
/// `None` for sync viewports.
|
||||||
viewport_ui_cb: Option<Arc<ViewportUiCallback>>,
|
viewport_ui_cb: Option<Arc<ViewportUiCallback>>,
|
||||||
|
|
||||||
// `window` and `egui_winit` are initialized together.
|
/// 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.
|
||||||
window: Option<Rc<Window>>,
|
window: Option<Rc<Window>>,
|
||||||
|
|
||||||
|
/// `window` and `egui_winit` are initialized together.
|
||||||
egui_winit: Option<egui_winit::State>,
|
egui_winit: Option<egui_winit::State>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1837,13 +1827,15 @@ mod wgpu_integration {
|
|||||||
) {
|
) {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
|
|
||||||
let id = self.ids.this;
|
let viewport_id = self.ids.this;
|
||||||
|
|
||||||
if let Ok(new_window) = create_winit_window_builder(&self.builder).build(event_loop) {
|
if let Ok(new_window) = create_winit_window_builder(&self.builder).build(event_loop) {
|
||||||
windows_id.insert(new_window.id(), id);
|
windows_id.insert(new_window.id(), viewport_id);
|
||||||
|
|
||||||
if let Err(err) = pollster::block_on(painter.set_window(id, Some(&new_window))) {
|
if let Err(err) =
|
||||||
log::error!("on set_window: viewport_id {id:?} {err}");
|
pollster::block_on(painter.set_window(viewport_id, Some(&new_window)))
|
||||||
|
{
|
||||||
|
log::error!("on set_window: viewport_id {viewport_id:?} {err}");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.egui_winit = Some(egui_winit::State::new(
|
self.egui_winit = Some(egui_winit::State::new(
|
||||||
@@ -1865,7 +1857,7 @@ mod wgpu_integration {
|
|||||||
pub struct SharedState {
|
pub struct SharedState {
|
||||||
viewports: Viewports,
|
viewports: Viewports,
|
||||||
painter: egui_wgpu::winit::Painter,
|
painter: egui_wgpu::winit::Painter,
|
||||||
viewport_maps: HashMap<WindowId, ViewportId>,
|
viewport_from_window: HashMap<WindowId, ViewportId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// State that is initialized when the application is first starts running via
|
/// State that is initialized when the application is first starts running via
|
||||||
@@ -1873,20 +1865,25 @@ mod wgpu_integration {
|
|||||||
/// initialized once the application has an associated `SurfaceView`.
|
/// initialized once the application has an associated `SurfaceView`.
|
||||||
struct WgpuWinitRunning {
|
struct WgpuWinitRunning {
|
||||||
integration: epi_integration::EpiIntegration,
|
integration: epi_integration::EpiIntegration,
|
||||||
|
|
||||||
|
/// The users application.
|
||||||
app: Box<dyn epi::App>,
|
app: Box<dyn epi::App>,
|
||||||
|
|
||||||
/// Wrapped in an `Rc<RefCell<…>>` so it can be re-entrantly shared via a weak-pointer.
|
/// Wrapped in an `Rc<RefCell<…>>` so it can be re-entrantly shared via a weak-pointer.
|
||||||
shared: Rc<RefCell<SharedState>>,
|
shared: Rc<RefCell<SharedState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WgpuWinitApp {
|
struct WgpuWinitApp {
|
||||||
repaint_proxy: Arc<Mutex<EventLoopProxy<UserEvent>>>,
|
repaint_proxy: Arc<Mutex<EventLoopProxy<UserEvent>>>,
|
||||||
app_name: String,
|
app_name: String,
|
||||||
native_options: epi::NativeOptions,
|
native_options: epi::NativeOptions,
|
||||||
|
|
||||||
|
/// Set at initialization, then taken and set to `None` in `init_run_state`.
|
||||||
app_creator: Option<epi::AppCreator>,
|
app_creator: Option<epi::AppCreator>,
|
||||||
|
|
||||||
|
/// Set when we are actually up and running.
|
||||||
running: Option<WgpuWinitRunning>,
|
running: Option<WgpuWinitRunning>,
|
||||||
|
|
||||||
/// 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.
|
|
||||||
focused_viewport: Option<ViewportId>,
|
focused_viewport: Option<ViewportId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1898,6 +1895,7 @@ mod wgpu_integration {
|
|||||||
app_creator: epi::AppCreator,
|
app_creator: epi::AppCreator,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
crate::profile_function!();
|
crate::profile_function!();
|
||||||
|
|
||||||
#[cfg(feature = "__screenshot")]
|
#[cfg(feature = "__screenshot")]
|
||||||
assert!(
|
assert!(
|
||||||
std::env::var("EFRAME_SCREENSHOT_TO").is_err(),
|
std::env::var("EFRAME_SCREENSHOT_TO").is_err(),
|
||||||
@@ -1922,12 +1920,12 @@ mod wgpu_integration {
|
|||||||
let SharedState {
|
let SharedState {
|
||||||
viewports,
|
viewports,
|
||||||
painter,
|
painter,
|
||||||
viewport_maps,
|
viewport_from_window,
|
||||||
} = &mut *shared;
|
} = &mut *shared;
|
||||||
|
|
||||||
for viewport in viewports.values_mut() {
|
for viewport in viewports.values_mut() {
|
||||||
if viewport.window.is_none() {
|
if viewport.window.is_none() {
|
||||||
viewport.init_window(viewport_maps, painter, event_loop);
|
viewport.init_window(viewport_from_window, painter, event_loop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2034,8 +2032,8 @@ mod wgpu_integration {
|
|||||||
integration.warm_up(app.as_mut(), &window, &mut egui_winit);
|
integration.warm_up(app.as_mut(), &window, &mut egui_winit);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut viewport_maps = HashMap::default();
|
let mut viewport_from_window = HashMap::default();
|
||||||
viewport_maps.insert(window.id(), ViewportId::ROOT);
|
viewport_from_window.insert(window.id(), ViewportId::ROOT);
|
||||||
|
|
||||||
let mut viewports = Viewports::default();
|
let mut viewports = Viewports::default();
|
||||||
viewports.insert(
|
viewports.insert(
|
||||||
@@ -2050,7 +2048,7 @@ mod wgpu_integration {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let shared = Rc::new(RefCell::new(SharedState {
|
let shared = Rc::new(RefCell::new(SharedState {
|
||||||
viewport_maps,
|
viewport_from_window,
|
||||||
viewports,
|
viewports,
|
||||||
painter,
|
painter,
|
||||||
}));
|
}));
|
||||||
@@ -2127,22 +2125,18 @@ mod wgpu_integration {
|
|||||||
} = immediate_viewport;
|
} = immediate_viewport;
|
||||||
|
|
||||||
let input = {
|
let input = {
|
||||||
let mut shared = shared.borrow_mut();
|
|
||||||
let SharedState {
|
let SharedState {
|
||||||
viewports,
|
viewports,
|
||||||
painter,
|
painter,
|
||||||
viewport_maps,
|
viewport_from_window,
|
||||||
} = &mut *shared;
|
} = &mut *shared.borrow_mut();
|
||||||
let viewport = initialize_or_update_viewport(viewports, ids, builder, None, None);
|
let viewport = initialize_or_update_viewport(viewports, ids, builder, None, None);
|
||||||
|
|
||||||
if viewport.window.is_none() {
|
if viewport.window.is_none() {
|
||||||
viewport.init_window(viewport_maps, painter, event_loop);
|
viewport.init_window(viewport_from_window, painter, event_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some(winit_state) = &mut viewport.egui_winit else {
|
let (Some(window), Some(winit_state)) = (&viewport.window, &mut viewport.egui_winit) else {
|
||||||
return;
|
|
||||||
};
|
|
||||||
let Some(window) = &viewport.window else {
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2153,7 +2147,8 @@ mod wgpu_integration {
|
|||||||
|
|
||||||
// ------------------------------------------
|
// ------------------------------------------
|
||||||
|
|
||||||
// Run the user code, which could re-entrantly call this function again (!)
|
// Run the user code, which could re-entrantly call this function again (!).
|
||||||
|
// Make sure no locks are held during this call.
|
||||||
let output = egui_ctx.run(input, |ctx| {
|
let output = egui_ctx.run(input, |ctx| {
|
||||||
viewport_ui_cb(ctx);
|
viewport_ui_cb(ctx);
|
||||||
});
|
});
|
||||||
@@ -2183,7 +2178,7 @@ mod wgpu_integration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let pixels_per_point = egui_ctx.input_for(ids.this, |i| i.pixels_per_point());
|
let pixels_per_point = egui_ctx.input_for(ids.this, |i| i.pixels_per_point());
|
||||||
let clipped_primitives = egui_ctx.tessellate(output.shapes);
|
let clipped_primitives = egui_ctx.tessellate(output.shapes, pixels_per_point);
|
||||||
painter.paint_and_update_textures(
|
painter.paint_and_update_textures(
|
||||||
ids.this,
|
ids.this,
|
||||||
pixels_per_point,
|
pixels_per_point,
|
||||||
@@ -2204,12 +2199,15 @@ mod wgpu_integration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_focused(&self, window_id: WindowId) -> bool {
|
fn is_focused(&self, window_id: WindowId) -> bool {
|
||||||
if let Some(focus) = self.focused_viewport {
|
let viewport_id = self.running.as_ref().and_then(|r| {
|
||||||
self.viewport_id_from_window_id(&window_id)
|
r.shared
|
||||||
.map_or(false, |i| i == focus)
|
.borrow()
|
||||||
} else {
|
.viewport_from_window
|
||||||
false
|
.get(&window_id)
|
||||||
}
|
.copied()
|
||||||
|
});
|
||||||
|
|
||||||
|
self.focused_viewport.is_some() && self.focused_viewport == viewport_id
|
||||||
}
|
}
|
||||||
|
|
||||||
fn integration(&self) -> Option<&EpiIntegration> {
|
fn integration(&self) -> Option<&EpiIntegration> {
|
||||||
@@ -2222,7 +2220,7 @@ mod wgpu_integration {
|
|||||||
.and_then(|r| {
|
.and_then(|r| {
|
||||||
let shared = r.shared.borrow();
|
let shared = r.shared.borrow();
|
||||||
shared
|
shared
|
||||||
.viewport_maps
|
.viewport_from_window
|
||||||
.get(&window_id)
|
.get(&window_id)
|
||||||
.and_then(|id| shared.viewports.get(id).map(|v| v.window.clone()))
|
.and_then(|id| shared.viewports.get(id).map(|v| v.window.clone()))
|
||||||
})
|
})
|
||||||
@@ -2230,13 +2228,17 @@ mod wgpu_integration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn window_id_from_viewport_id(&self, id: ViewportId) -> Option<WindowId> {
|
fn window_id_from_viewport_id(&self, id: ViewportId) -> Option<WindowId> {
|
||||||
self.running.as_ref().and_then(|r| {
|
Some(
|
||||||
r.shared
|
self.running
|
||||||
|
.as_ref()?
|
||||||
|
.shared
|
||||||
.borrow()
|
.borrow()
|
||||||
.viewports
|
.viewports
|
||||||
.get(&id)
|
.get(&id)?
|
||||||
.and_then(|v| v.window.as_ref().map(|w| w.id()))
|
.window
|
||||||
})
|
.as_ref()?
|
||||||
|
.id(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn save_and_destroy(&mut self) {
|
fn save_and_destroy(&mut self) {
|
||||||
@@ -2295,6 +2297,7 @@ mod wgpu_integration {
|
|||||||
)?;
|
)?;
|
||||||
self.init_run_state(event_loop, storage, window, builder)?
|
self.init_run_state(event_loop, storage, window, builder)?
|
||||||
};
|
};
|
||||||
|
|
||||||
EventResult::RepaintNow(
|
EventResult::RepaintNow(
|
||||||
running.shared.borrow().viewports[&ViewportId::ROOT]
|
running.shared.borrow().viewports[&ViewportId::ROOT]
|
||||||
.window
|
.window
|
||||||
@@ -2325,11 +2328,11 @@ mod wgpu_integration {
|
|||||||
if let Some(running) = &mut self.running {
|
if let Some(running) = &mut self.running {
|
||||||
let mut shared_lock = running.shared.borrow_mut();
|
let mut shared_lock = running.shared.borrow_mut();
|
||||||
let SharedState {
|
let SharedState {
|
||||||
viewport_maps,
|
viewport_from_window,
|
||||||
viewports,
|
viewports,
|
||||||
..
|
..
|
||||||
} = &mut *shared_lock;
|
} = &mut *shared_lock;
|
||||||
if let Some(viewport) = viewport_maps
|
if let Some(viewport) = viewport_from_window
|
||||||
.get(window_id)
|
.get(window_id)
|
||||||
.and_then(|id| viewports.get_mut(id))
|
.and_then(|id| viewports.get_mut(id))
|
||||||
{
|
{
|
||||||
@@ -2347,12 +2350,6 @@ mod wgpu_integration {
|
|||||||
_ => EventResult::Wait,
|
_ => EventResult::Wait,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn viewport_id_from_window_id(&self, id: &WindowId) -> Option<ViewportId> {
|
|
||||||
self.running
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|r| r.shared.borrow().viewport_maps.get(id).copied())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuWinitRunning {
|
impl WgpuWinitRunning {
|
||||||
@@ -2391,6 +2388,11 @@ mod wgpu_integration {
|
|||||||
window_id: WindowId,
|
window_id: WindowId,
|
||||||
focused_viewport: Option<ViewportId>,
|
focused_viewport: Option<ViewportId>,
|
||||||
) -> EventResult {
|
) -> EventResult {
|
||||||
|
let Some(viewport_id) = self.shared.borrow().viewport_from_window.get(&window_id).copied()
|
||||||
|
else {
|
||||||
|
return EventResult::Wait;
|
||||||
|
};
|
||||||
|
|
||||||
#[cfg(feature = "puffin")]
|
#[cfg(feature = "puffin")]
|
||||||
puffin::GlobalProfiler::lock().new_frame();
|
puffin::GlobalProfiler::lock().new_frame();
|
||||||
|
|
||||||
@@ -2406,21 +2408,16 @@ mod wgpu_integration {
|
|||||||
let mut shared_lock = shared.borrow_mut();
|
let mut shared_lock = shared.borrow_mut();
|
||||||
|
|
||||||
let SharedState {
|
let SharedState {
|
||||||
viewports,
|
viewports, painter, ..
|
||||||
painter,
|
|
||||||
viewport_maps,
|
|
||||||
} = &mut *shared_lock;
|
} = &mut *shared_lock;
|
||||||
|
|
||||||
let Some(viewport_id) = viewport_maps.get(&window_id).copied() else {
|
|
||||||
return EventResult::Wait;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(viewport) = viewports.get(&viewport_id) else {
|
let Some(viewport) = viewports.get(&viewport_id) else {
|
||||||
return EventResult::Wait;
|
return EventResult::Wait;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is used to not render a viewport if is sync
|
|
||||||
if viewport_id != ViewportId::ROOT && viewport.viewport_ui_cb.is_none() {
|
if viewport_id != ViewportId::ROOT && 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(viewport) = viewports.get(&viewport.ids.parent) {
|
||||||
if let Some(window) = viewport.window.as_ref() {
|
if let Some(window) = viewport.window.as_ref() {
|
||||||
return EventResult::RepaintNext(window.id());
|
return EventResult::RepaintNext(window.id());
|
||||||
@@ -2477,22 +2474,19 @@ mod wgpu_integration {
|
|||||||
let SharedState {
|
let SharedState {
|
||||||
viewports,
|
viewports,
|
||||||
painter,
|
painter,
|
||||||
viewport_maps,
|
viewport_from_window,
|
||||||
} = &mut *shared;
|
} = &mut *shared;
|
||||||
|
|
||||||
let Some(viewport_id) = viewport_maps.get(&window_id).copied() else {
|
|
||||||
return EventResult::Wait;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(viewport) = viewports.get_mut(&viewport_id) else {
|
let Some(viewport) = viewports.get_mut(&viewport_id) else {
|
||||||
return EventResult::Wait;
|
return EventResult::Wait;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Viewport {
|
let Viewport {
|
||||||
window, egui_winit, ..
|
window: Some(window),
|
||||||
} = viewport;
|
egui_winit: Some(egui_winit),
|
||||||
|
..
|
||||||
let Some(window) = window else {
|
} = viewport
|
||||||
|
else {
|
||||||
return EventResult::Wait;
|
return EventResult::Wait;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2502,35 +2496,31 @@ mod wgpu_integration {
|
|||||||
platform_output,
|
platform_output,
|
||||||
textures_delta,
|
textures_delta,
|
||||||
shapes,
|
shapes,
|
||||||
viewports: mut out_viewports,
|
viewports: out_viewports,
|
||||||
viewport_commands,
|
viewport_commands,
|
||||||
} = full_output;
|
} = full_output;
|
||||||
|
|
||||||
integration.handle_platform_output(
|
integration.handle_platform_output(window, viewport_id, platform_output, egui_winit);
|
||||||
window,
|
|
||||||
viewport_id,
|
|
||||||
platform_output,
|
|
||||||
egui_winit.as_mut().unwrap(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let clipped_primitives = integration.egui_ctx.tessellate(shapes);
|
{
|
||||||
|
let pixels_per_point = integration
|
||||||
|
.egui_ctx
|
||||||
|
.input_for(viewport_id, |i| i.pixels_per_point());
|
||||||
|
|
||||||
let screenshot_requested = &mut integration.frame.output.screenshot_requested;
|
let clipped_primitives = integration.egui_ctx.tessellate(shapes, pixels_per_point);
|
||||||
|
|
||||||
let pixels_per_point = integration
|
let screenshot_requested = &mut integration.frame.output.screenshot_requested;
|
||||||
.egui_ctx
|
let screenshot = painter.paint_and_update_textures(
|
||||||
.input_for(viewport_id, |i| i.pixels_per_point());
|
viewport_id,
|
||||||
|
pixels_per_point,
|
||||||
let screenshot = painter.paint_and_update_textures(
|
app.clear_color(&integration.egui_ctx.style().visuals),
|
||||||
viewport_id,
|
&clipped_primitives,
|
||||||
pixels_per_point,
|
&textures_delta,
|
||||||
app.clear_color(&integration.egui_ctx.style().visuals),
|
*screenshot_requested,
|
||||||
&clipped_primitives,
|
);
|
||||||
&textures_delta,
|
*screenshot_requested = false;
|
||||||
*screenshot_requested,
|
integration.frame.screenshot.set(screenshot);
|
||||||
);
|
}
|
||||||
*screenshot_requested = false;
|
|
||||||
integration.frame.screenshot.set(screenshot);
|
|
||||||
|
|
||||||
integration.post_rendering(app.as_mut(), window);
|
integration.post_rendering(app.as_mut(), window);
|
||||||
integration.post_present(window);
|
integration.post_present(window);
|
||||||
@@ -2538,24 +2528,6 @@ mod wgpu_integration {
|
|||||||
let mut active_viewports_ids = ViewportIdSet::default();
|
let mut active_viewports_ids = ViewportIdSet::default();
|
||||||
active_viewports_ids.insert(ViewportId::ROOT);
|
active_viewports_ids.insert(ViewportId::ROOT);
|
||||||
|
|
||||||
// Update exisitng viewports:
|
|
||||||
out_viewports.retain_mut(
|
|
||||||
|ViewportOutput {
|
|
||||||
ids: ViewportIdPair { this, parent },
|
|
||||||
viewport_ui_cb,
|
|
||||||
..
|
|
||||||
}| {
|
|
||||||
if let Some(viewport) = viewports.get_mut(this) {
|
|
||||||
viewport.viewport_ui_cb = viewport_ui_cb.clone();
|
|
||||||
viewport.ids.parent = *parent;
|
|
||||||
active_viewports_ids.insert(*this);
|
|
||||||
false
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Add new viewports, and update existing ones:
|
// Add new viewports, and update existing ones:
|
||||||
for ViewportOutput {
|
for ViewportOutput {
|
||||||
ids,
|
ids,
|
||||||
@@ -2574,6 +2546,7 @@ mod wgpu_integration {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle viewport commands:
|
||||||
for (viewport_id, command) in viewport_commands {
|
for (viewport_id, command) in viewport_commands {
|
||||||
if let Some(window) = viewports
|
if let Some(window) = viewports
|
||||||
.get(&viewport_id)
|
.get(&viewport_id)
|
||||||
@@ -2590,10 +2563,10 @@ mod wgpu_integration {
|
|||||||
|
|
||||||
// Prune dead viewports:
|
// Prune dead viewports:
|
||||||
viewports.retain(|id, _| active_viewports_ids.contains(id));
|
viewports.retain(|id, _| active_viewports_ids.contains(id));
|
||||||
viewport_maps.retain(|_, id| active_viewports_ids.contains(id));
|
viewport_from_window.retain(|_, id| active_viewports_ids.contains(id));
|
||||||
painter.gc_viewports(&active_viewports_ids);
|
painter.gc_viewports(&active_viewports_ids);
|
||||||
|
|
||||||
let window = viewport_maps
|
let window = viewport_from_window
|
||||||
.get(&window_id)
|
.get(&window_id)
|
||||||
.and_then(|id| viewports.get(id))
|
.and_then(|id| viewports.get(id))
|
||||||
.and_then(|vp| vp.window.as_ref());
|
.and_then(|vp| vp.window.as_ref());
|
||||||
@@ -2629,7 +2602,7 @@ mod wgpu_integration {
|
|||||||
} = self;
|
} = self;
|
||||||
let mut shared = shared.borrow_mut();
|
let mut shared = shared.borrow_mut();
|
||||||
|
|
||||||
let viewport_id = shared.viewport_maps.get(&window_id).copied();
|
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
|
// On Windows, if a window is resized by the user, it should repaint synchronously, inside the
|
||||||
// event handler.
|
// event handler.
|
||||||
@@ -2671,7 +2644,7 @@ mod wgpu_integration {
|
|||||||
if let (Some(width), Some(height), Some(viewport_id)) = (
|
if let (Some(width), Some(height), Some(viewport_id)) = (
|
||||||
NonZeroU32::new(new_inner_size.width),
|
NonZeroU32::new(new_inner_size.width),
|
||||||
NonZeroU32::new(new_inner_size.height),
|
NonZeroU32::new(new_inner_size.height),
|
||||||
shared.viewport_maps.get(&window_id).copied(),
|
shared.viewport_from_window.get(&window_id).copied(),
|
||||||
) {
|
) {
|
||||||
repaint_asap = true;
|
repaint_asap = true;
|
||||||
shared.painter.on_window_resized(viewport_id, width, height);
|
shared.painter.on_window_resized(viewport_id, width, height);
|
||||||
|
|||||||
@@ -1631,22 +1631,12 @@ impl Context {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tessellate the given shapes into triangle meshes.
|
|
||||||
///
|
|
||||||
/// Will use the `pixels_per_point` of the last viewport for feathering (anti-aliasing).
|
|
||||||
pub fn tessellate(&self, shapes: Vec<ClippedShape>) -> Vec<ClippedPrimitive> {
|
|
||||||
let last_viewport = self.read(|ctx| ctx.last_viewport);
|
|
||||||
|
|
||||||
// here we expect that we are the only user of context, since frame is ended
|
|
||||||
let pixels_per_point = self.input_for(last_viewport, |i| i.pixels_per_point());
|
|
||||||
|
|
||||||
self.tessellate_with_pixels_per_point(shapes, pixels_per_point)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Tessellate the given shapes into triangle meshes.
|
/// Tessellate the given shapes into triangle meshes.
|
||||||
///
|
///
|
||||||
/// `pixels_per_point` is used for feathering (anti-aliasing).
|
/// `pixels_per_point` is used for feathering (anti-aliasing).
|
||||||
pub fn tessellate_with_pixels_per_point(
|
/// You can use [`Self::pixels_per_point`] for this,
|
||||||
|
/// or whatever is appropiate for your viewport.
|
||||||
|
pub fn tessellate(
|
||||||
&self,
|
&self,
|
||||||
shapes: Vec<ClippedShape>,
|
shapes: Vec<ClippedShape>,
|
||||||
pixels_per_point: f32,
|
pixels_per_point: f32,
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
{
|
{
|
||||||
let ctx = egui::Context::default();
|
let ctx = egui::Context::default();
|
||||||
let mut demo_windows = egui_demo_lib::DemoWindows::default();
|
let mut demo_windows = egui_demo_lib::DemoWindows::default();
|
||||||
|
let pixels_per_point = 1.0;
|
||||||
|
|
||||||
// The most end-to-end benchmark.
|
// The most end-to-end benchmark.
|
||||||
c.bench_function("demo_with_tessellate__realistic", |b| {
|
c.bench_function("demo_with_tessellate__realistic", |b| {
|
||||||
@@ -16,7 +17,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
let full_output = ctx.run(RawInput::default(), |ctx| {
|
let full_output = ctx.run(RawInput::default(), |ctx| {
|
||||||
demo_windows.ui(ctx);
|
demo_windows.ui(ctx);
|
||||||
});
|
});
|
||||||
ctx.tessellate(full_output.shapes)
|
ctx.tessellate(full_output.shapes, pixels_per_point)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||||||
demo_windows.ui(ctx);
|
demo_windows.ui(ctx);
|
||||||
});
|
});
|
||||||
c.bench_function("demo_only_tessellate", |b| {
|
c.bench_function("demo_only_tessellate", |b| {
|
||||||
b.iter(|| ctx.tessellate(full_output.shapes.clone()));
|
b.iter(|| ctx.tessellate(full_output.shapes.clone(), pixels_per_point));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,13 +71,14 @@ fn test_egui_e2e() {
|
|||||||
let mut demo_windows = crate::DemoWindows::default();
|
let mut demo_windows = crate::DemoWindows::default();
|
||||||
let ctx = egui::Context::default();
|
let ctx = egui::Context::default();
|
||||||
let raw_input = egui::RawInput::default();
|
let raw_input = egui::RawInput::default();
|
||||||
|
let pixels_per_point = 1.0;
|
||||||
|
|
||||||
const NUM_FRAMES: usize = 5;
|
const NUM_FRAMES: usize = 5;
|
||||||
for _ in 0..NUM_FRAMES {
|
for _ in 0..NUM_FRAMES {
|
||||||
let full_output = ctx.run(raw_input.clone(), |ctx| {
|
let full_output = ctx.run(raw_input.clone(), |ctx| {
|
||||||
demo_windows.ui(ctx);
|
demo_windows.ui(ctx);
|
||||||
});
|
});
|
||||||
let clipped_primitives = ctx.tessellate(full_output.shapes);
|
let clipped_primitives = ctx.tessellate(full_output.shapes, pixels_per_point);
|
||||||
assert!(!clipped_primitives.is_empty());
|
assert!(!clipped_primitives.is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,13 +91,14 @@ fn test_egui_zero_window_size() {
|
|||||||
screen_rect: Some(egui::Rect::from_min_max(egui::Pos2::ZERO, egui::Pos2::ZERO)),
|
screen_rect: Some(egui::Rect::from_min_max(egui::Pos2::ZERO, egui::Pos2::ZERO)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
let pixels_per_point = 1.0;
|
||||||
|
|
||||||
const NUM_FRAMES: usize = 5;
|
const NUM_FRAMES: usize = 5;
|
||||||
for _ in 0..NUM_FRAMES {
|
for _ in 0..NUM_FRAMES {
|
||||||
let full_output = ctx.run(raw_input.clone(), |ctx| {
|
let full_output = ctx.run(raw_input.clone(), |ctx| {
|
||||||
demo_windows.ui(ctx);
|
demo_windows.ui(ctx);
|
||||||
});
|
});
|
||||||
let clipped_primitives = ctx.tessellate(full_output.shapes);
|
let clipped_primitives = ctx.tessellate(full_output.shapes, pixels_per_point);
|
||||||
assert!(
|
assert!(
|
||||||
clipped_primitives.is_empty(),
|
clipped_primitives.is_empty(),
|
||||||
"There should be nothing to show, has at least one primitive with clip_rect: {:?}",
|
"There should be nothing to show, has at least one primitive with clip_rect: {:?}",
|
||||||
|
|||||||
@@ -88,13 +88,11 @@ impl EguiGlow {
|
|||||||
self.painter.set_texture(id, &image_delta);
|
self.painter.set_texture(id, &image_delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
let clipped_primitives = self.egui_ctx.tessellate(shapes);
|
let pixels_per_point = self.egui_ctx.pixels_per_point();
|
||||||
|
let clipped_primitives = self.egui_ctx.tessellate(shapes, pixels_per_point);
|
||||||
let dimensions: [u32; 2] = window.inner_size().into();
|
let dimensions: [u32; 2] = window.inner_size().into();
|
||||||
self.painter.paint_primitives(
|
self.painter
|
||||||
dimensions,
|
.paint_primitives(dimensions, pixels_per_point, &clipped_primitives);
|
||||||
self.egui_ctx.pixels_per_point(),
|
|
||||||
&clipped_primitives,
|
|
||||||
);
|
|
||||||
|
|
||||||
for id in textures_delta.free.drain(..) {
|
for id in textures_delta.free.drain(..) {
|
||||||
self.painter.free_texture(id);
|
self.painter.free_texture(id);
|
||||||
|
|||||||
Reference in New Issue
Block a user