Split out tesselation from Context::end_frame()
This commit is contained in:
parent
901a6920be
commit
af11d766fc
9 changed files with 59 additions and 29 deletions
|
@ -13,6 +13,7 @@
|
|||
* You can no longer throw windows
|
||||
* `Context::begin_frame()` no longer returns anything.
|
||||
* Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
|
||||
* `Context::end_frame()` now returns "paint jobs" that need to be converted to triangles with `Context::tesselate()`.
|
||||
|
||||
## 0.2.0 - 2020-10-10
|
||||
|
||||
|
|
|
@ -154,7 +154,8 @@ loop {
|
|||
let raw_input: egui::RawInput = my_integration.gather_input();
|
||||
egui_ctx.begin_frame(raw_input);
|
||||
my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
||||
let (output, paint_jobs) = egui_ctx.end_frame();
|
||||
let (output, paint_commands) = egui_ctx.end_frame();
|
||||
let paint_jobs = self.ctx.tesselate(paint_commands); // create triangles to paint
|
||||
my_integration.paint(paint_jobs);
|
||||
my_integration.set_cursor_icon(output.cursor_icon);
|
||||
// Also see `egui::Output` for more
|
||||
|
|
|
@ -33,6 +33,19 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
});
|
||||
}
|
||||
|
||||
{
|
||||
let mut ctx = egui::Context::new();
|
||||
ctx.memory().all_collpasing_are_open = true; // expand the demo window with everything
|
||||
let mut demo_windows = egui::demos::DemoWindows::default();
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx, &Default::default(), &mut None);
|
||||
let (_, paint_commands) = ctx.end_frame();
|
||||
|
||||
c.bench_function("tesselate", |b| {
|
||||
b.iter(|| ctx.tesselate(paint_commands.clone()))
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
let mut ctx = egui::Context::new();
|
||||
ctx.begin_frame(raw_input);
|
||||
|
@ -43,7 +56,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
|
|||
})
|
||||
});
|
||||
});
|
||||
// let _ = ctx.end_frame(); // skip, because tessellating all that text is slow
|
||||
let _ = ctx.end_frame();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ struct Options {
|
|||
/// The default style for new `Ui`:s.
|
||||
style: Arc<Style>,
|
||||
/// Controls the tessellator.
|
||||
paint_options: paint::PaintOptions,
|
||||
tesselation_options: paint::TesselationOptions,
|
||||
/// Font sizes etc.
|
||||
font_definitions: FontDefinitions,
|
||||
}
|
||||
|
@ -242,8 +242,10 @@ impl Context {
|
|||
|
||||
/// Call at the end of each frame.
|
||||
/// Returns what has happened this frame (`Output`) as well as what you need to paint.
|
||||
/// You can transform the returned paint commands into triangles with a call to
|
||||
/// `Context::tesselate`.
|
||||
#[must_use]
|
||||
pub fn end_frame(&self) -> (Output, PaintJobs) {
|
||||
pub fn end_frame(&self) -> (Output, Vec<(Rect, PaintCmd)>) {
|
||||
if self.input.wants_repaint() {
|
||||
self.request_repaint();
|
||||
}
|
||||
|
@ -256,8 +258,8 @@ impl Context {
|
|||
output.needs_repaint = true;
|
||||
}
|
||||
|
||||
let paint_jobs = self.paint();
|
||||
(output, paint_jobs)
|
||||
let paint_commands = self.drain_paint_lists();
|
||||
(output, paint_commands)
|
||||
}
|
||||
|
||||
fn drain_paint_lists(&self) -> Vec<(Rect, PaintCmd)> {
|
||||
|
@ -265,15 +267,17 @@ impl Context {
|
|||
self.graphics().drain(memory.areas.order()).collect()
|
||||
}
|
||||
|
||||
fn paint(&self) -> PaintJobs {
|
||||
let mut paint_options = self.options.lock().paint_options;
|
||||
paint_options.aa_size = 1.0 / self.pixels_per_point();
|
||||
let paint_commands = self.drain_paint_lists();
|
||||
/// Tesselate the given paint commands into triangle meshes.
|
||||
pub fn tesselate(&self, paint_commands: Vec<(Rect, PaintCmd)>) -> PaintJobs {
|
||||
let mut tesselation_options = self.options.lock().tesselation_options;
|
||||
tesselation_options.aa_size = 1.0 / self.pixels_per_point();
|
||||
let paint_stats = PaintStats::from_paint_commands(&paint_commands); // TODO: internal allocations
|
||||
let paint_jobs =
|
||||
tessellator::tessellate_paint_commands(paint_commands, paint_options, self.fonts());
|
||||
let paint_jobs = tessellator::tessellate_paint_commands(
|
||||
paint_commands,
|
||||
tesselation_options,
|
||||
self.fonts(),
|
||||
);
|
||||
*self.paint_stats.lock() = paint_stats.with_paint_jobs(&paint_jobs);
|
||||
|
||||
paint_jobs
|
||||
}
|
||||
|
||||
|
@ -591,9 +595,9 @@ impl Context {
|
|||
CollapsingHeader::new("Painting")
|
||||
.default_open(true)
|
||||
.show(ui, |ui| {
|
||||
let mut paint_options = self.options.lock().paint_options;
|
||||
paint_options.ui(ui);
|
||||
self.options.lock().paint_options = paint_options;
|
||||
let mut tesselation_options = self.options.lock().tesselation_options;
|
||||
tesselation_options.ui(ui);
|
||||
self.options.lock().tesselation_options = tesselation_options;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -708,7 +712,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
impl paint::PaintOptions {
|
||||
impl paint::TesselationOptions {
|
||||
pub fn ui(&mut self, ui: &mut Ui) {
|
||||
let Self {
|
||||
aa_size: _,
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
//! let raw_input: egui::RawInput = my_integration.gather_input();
|
||||
//! egui_ctx.begin_frame(raw_input);
|
||||
//! my_app.ui(&egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
||||
//! let (output, paint_jobs) = egui_ctx.end_frame();
|
||||
//! let (output, paint_commands) = egui_ctx.end_frame();
|
||||
//! let paint_jobs = self.ctx.tesselate(paint_commands); // create triangles to paint
|
||||
//! my_integration.paint(paint_jobs);
|
||||
//! my_integration.set_cursor_icon(output.cursor_icon);
|
||||
//! // Also see `egui::Output` for more
|
||||
|
@ -116,7 +117,8 @@ pub fn text_egui_e2e() {
|
|||
for _ in 0..NUM_FRAMES {
|
||||
ctx.begin_frame(raw_input.clone());
|
||||
demo_windows.ui(&ctx, &Default::default(), &mut None);
|
||||
let (_output, paint_jobs) = ctx.end_frame();
|
||||
let (_output, paint_commands) = ctx.end_frame();
|
||||
let paint_jobs = ctx.tesselate(paint_commands);
|
||||
assert!(!paint_jobs.is_empty());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ pub use {
|
|||
command::{PaintCmd, Stroke},
|
||||
fonts::{FontDefinitions, FontFamily, Fonts, TextStyle},
|
||||
stats::PaintStats,
|
||||
tessellator::{PaintJob, PaintJobs, PaintOptions, TextureId, Triangles, Vertex, WHITE_UV},
|
||||
tessellator::{
|
||||
PaintJob, PaintJobs, TesselationOptions, TextureId, Triangles, Vertex, WHITE_UV,
|
||||
},
|
||||
texture_atlas::Texture,
|
||||
};
|
||||
|
|
|
@ -446,7 +446,7 @@ use self::PathType::{Closed, Open};
|
|||
|
||||
/// Tesselation quality options
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct PaintOptions {
|
||||
pub struct TesselationOptions {
|
||||
/// Size of a pixel in points, e.g. 0.5
|
||||
pub aa_size: f32,
|
||||
/// Anti-aliasing makes shapes appear smoother, but requires more triangles and is therefore slower.
|
||||
|
@ -459,20 +459,25 @@ pub struct PaintOptions {
|
|||
pub debug_ignore_clip_rects: bool,
|
||||
}
|
||||
|
||||
impl Default for PaintOptions {
|
||||
impl Default for TesselationOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
aa_size: 1.0,
|
||||
anti_alias: true,
|
||||
coarse_tessellation_culling: true,
|
||||
debug_paint_clip_rects: false,
|
||||
debug_ignore_clip_rects: false,
|
||||
coarse_tessellation_culling: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Tesselate the given convex area into a polygon.
|
||||
fn fill_closed_path(path: &[PathPoint], color: Srgba, options: PaintOptions, out: &mut Triangles) {
|
||||
fn fill_closed_path(
|
||||
path: &[PathPoint],
|
||||
color: Srgba,
|
||||
options: TesselationOptions,
|
||||
out: &mut Triangles,
|
||||
) {
|
||||
if color == color::TRANSPARENT {
|
||||
return;
|
||||
}
|
||||
|
@ -516,7 +521,7 @@ fn stroke_path(
|
|||
path: &[PathPoint],
|
||||
path_type: PathType,
|
||||
stroke: Stroke,
|
||||
options: PaintOptions,
|
||||
options: TesselationOptions,
|
||||
out: &mut Triangles,
|
||||
) {
|
||||
if stroke.width <= 0.0 || stroke.color == color::TRANSPARENT {
|
||||
|
@ -669,7 +674,7 @@ fn mul_color(color: Srgba, factor: f32) -> Srgba {
|
|||
fn tessellate_paint_command(
|
||||
clip_rect: Rect,
|
||||
command: PaintCmd,
|
||||
options: PaintOptions,
|
||||
options: TesselationOptions,
|
||||
fonts: &Fonts,
|
||||
out: &mut Triangles,
|
||||
scratchpad_points: &mut Vec<Pos2>,
|
||||
|
@ -833,7 +838,7 @@ fn tessellate_paint_command(
|
|||
/// A list of clip rectangles with matching `Triangles`.
|
||||
pub fn tessellate_paint_commands(
|
||||
commands: Vec<(Rect, PaintCmd)>,
|
||||
options: PaintOptions,
|
||||
options: TesselationOptions,
|
||||
fonts: &Fonts,
|
||||
) -> Vec<(Rect, Triangles)> {
|
||||
let mut scratchpad_points = Vec::new();
|
||||
|
|
|
@ -89,7 +89,8 @@ pub fn run(
|
|||
};
|
||||
app.ui(&ctx, &mut integration_context);
|
||||
let app_output = integration_context.output;
|
||||
let (egui_output, paint_jobs) = ctx.end_frame();
|
||||
let (egui_output, paint_commands) = ctx.end_frame();
|
||||
let paint_jobs = ctx.tesselate(paint_commands);
|
||||
|
||||
let frame_time = (Instant::now() - egui_start).as_secs_f64() as f32;
|
||||
previous_frame_time = Some(frame_time);
|
||||
|
|
|
@ -44,7 +44,8 @@ impl WebBackend {
|
|||
.take()
|
||||
.expect("unmatched calls to begin_frame/end_frame");
|
||||
|
||||
let (output, paint_jobs) = self.ctx.end_frame();
|
||||
let (output, paint_commands) = self.ctx.end_frame();
|
||||
let paint_jobs = self.ctx.tesselate(paint_commands);
|
||||
|
||||
self.auto_save();
|
||||
|
||||
|
|
Loading…
Reference in a new issue