1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-29 21:00:03 -04:00

* Fix posibile deadlock when sending a viewport command from a sync viewport

* Improve viewports example
This commit is contained in:
Konkitoman
2023-09-06 16:30:20 +03:00
parent b1189c14ae
commit fb80880ff8
3 changed files with 59 additions and 21 deletions

View File

@@ -1030,8 +1030,6 @@ mod glow_integration {
let _painter = painter.clone();
let time = integration.beginning;
let focused = self.is_focused.clone();
// ## Sync Rendering
integration.egui_ctx.set_render_sync_callback(
move |viewport_builder, viewport_id, parent_id, render| {
@@ -1129,17 +1127,6 @@ mod glow_integration {
break 'try_render;
}
}
egui_winit::process_viewports_commands(
output.viewport_commands,
*focused.read(),
|id| {
glutin
.read()
.windows
.get(&id)
.and_then(|w| w.read().window.clone())
},
);
}
}
},
@@ -2124,12 +2111,6 @@ mod wgpu_integration {
break 'try_render;
}
}
egui_winit::process_viewports_commands(
output.viewport_commands,
*focused.read(),
|id| _windows.read().get(&id).and_then(|w| w.window.clone()),
);
}
}
},

View File

@@ -1570,9 +1570,13 @@ impl Context {
avalibile_viewports
});
let viewport_id = self.get_viewport_id();
// We should not process viewport commands when we are a sync viewport, because that will cause a deadlock or a memory race
let mut is_async = viewport_id == ViewportId::MAIN;
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;
@@ -1581,6 +1585,10 @@ impl Context {
*used = false;
}
if !is_async && viewport_id == *id {
is_async = render.is_some();
}
viewports.push((*id, *parent, builder.clone(), render.clone()));
(out || viewport_id != *parent) && avalibile_viewports.contains(parent)
});
@@ -1601,13 +1609,18 @@ impl Context {
ctx.memory.resume_frame(viewport_id);
});
}
FullOutput {
platform_output,
repaint_after,
textures_delta,
shapes,
viewports,
viewport_commands: self.write(|ctx| std::mem::take(&mut ctx.viewport_commands)),
viewport_commands: if is_async {
self.write(|ctx| std::mem::take(&mut ctx.viewport_commands))
} else {
Vec::new()
},
}
}

View File

@@ -86,6 +86,17 @@ impl eframe::App for App {
if ui.button("Add").clicked() {
*state += 1;
}
if ui.button("Set parent pos {0, 0}").clicked() {
let ctx = ui.ctx().clone();
let parent_id = ctx.get_parent_viewport_id();
ctx.viewport_command_for(
parent_id,
egui::ViewportCommand::OuterPosition(
egui::pos2(0.0, 0.0),
),
);
}
};
show_as_popup(
@@ -111,6 +122,17 @@ impl eframe::App for App {
if ui.button("Add").clicked() {
*state += 1;
}
if ui.button("Set parent pos {0, 0}").clicked() {
let ctx = ui.ctx().clone();
let parent_id = ctx.get_parent_viewport_id();
ctx.viewport_command_for(
parent_id,
egui::ViewportCommand::OuterPosition(
egui::pos2(0.0, 0.0),
),
);
}
};
show_as_popup(
@@ -160,6 +182,17 @@ impl eframe::App for App {
if ui.button("Add").clicked() {
*state += 1;
}
if ui.button("Set parent pos {0, 0}").clicked() {
let ctx = ui.ctx().clone();
let parent_id = ctx.get_parent_viewport_id();
ctx.viewport_command_for(
parent_id,
egui::ViewportCommand::OuterPosition(
egui::pos2(0.0, 0.0),
),
);
}
};
show_as_popup(
@@ -185,6 +218,17 @@ impl eframe::App for App {
if ui.button("Add").clicked() {
*state += 1;
}
if ui.button("Set parent pos {0, 0}").clicked() {
let ctx = ui.ctx().clone();
let parent_id = ctx.get_parent_viewport_id();
ctx.viewport_command_for(
parent_id,
egui::ViewportCommand::OuterPosition(
egui::pos2(0.0, 0.0),
),
);
}
};
show_as_popup(