Wrap tesselated output in struct ClippedMesh(Rect, Mesh)
This commit is contained in:
parent
75fa77e040
commit
b493bc6efc
|
|
@ -23,6 +23,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
* Backend: pointer (mouse/touch) position and buttons are now passed to egui in the event stream.
|
* Backend: pointer (mouse/touch) position and buttons are now passed to egui in the event stream.
|
||||||
* `DragValue::range` is now called `clamp_range` and also clamps incoming values.
|
* `DragValue::range` is now called `clamp_range` and also clamps incoming values.
|
||||||
* Renamed `Triangles` to `Mesh`.
|
* Renamed `Triangles` to `Mesh`.
|
||||||
|
* The tesselator now wraps the clip rectangle and mesh in `struct ClippedMesh(Rect, Mesh)`.
|
||||||
|
|
||||||
### Fixed 🐛
|
### Fixed 🐛
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ The same code can be compiled to a native app or a web app.
|
||||||
|
|
||||||
### Writing your own egui integration
|
### Writing your own egui integration
|
||||||
|
|
||||||
You need to collect [`egui::RawInput`](https://docs.rs/egui/latest/egui/struct.RawInput.html), paint [`egui::PaintJobs`](https://docs.rs/egui/latest/egui/paint/tessellator/type.PaintJobs.html) and handle [`egui::Output`](https://docs.rs/egui/latest/egui/struct.Output.html). The basic structure is this:
|
You need to collect [`egui::RawInput`](https://docs.rs/egui/latest/egui/struct.RawInput.html), paint [`egui::ClippedMesh`](https://docs.rs/epaint/):es and handle [`egui::Output`](https://docs.rs/egui/latest/egui/struct.Output.html). The basic structure is this:
|
||||||
|
|
||||||
``` rust
|
``` rust
|
||||||
let mut egui_ctx = egui::Context::new();
|
let mut egui_ctx = egui::Context::new();
|
||||||
|
|
@ -179,8 +179,8 @@ loop {
|
||||||
egui_ctx.begin_frame(raw_input);
|
egui_ctx.begin_frame(raw_input);
|
||||||
my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
my_app.ui(&mut egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
||||||
let (output, shapes) = egui_ctx.end_frame();
|
let (output, shapes) = egui_ctx.end_frame();
|
||||||
let paint_jobs = egui_ctx.tessellate(shapes); // create triangles to paint
|
let clipped_meshes = egui_ctx.tessellate(shapes); // create triangles to paint
|
||||||
my_integration.paint(paint_jobs);
|
my_integration.paint(clipped_meshes);
|
||||||
my_integration.set_cursor_icon(output.cursor_icon);
|
my_integration.set_cursor_icon(output.cursor_icon);
|
||||||
// Also see `egui::Output` for more
|
// Also see `egui::Output` for more
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -583,13 +583,14 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tessellate the given shapes into triangle meshes.
|
/// Tessellate the given shapes into triangle meshes.
|
||||||
pub fn tessellate(&self, shapes: Vec<ClippedShape>) -> PaintJobs {
|
pub fn tessellate(&self, shapes: Vec<ClippedShape>) -> Vec<ClippedMesh> {
|
||||||
let mut tessellation_options = self.memory().options.tessellation_options;
|
let mut tessellation_options = self.memory().options.tessellation_options;
|
||||||
tessellation_options.aa_size = 1.0 / self.pixels_per_point();
|
tessellation_options.aa_size = 1.0 / self.pixels_per_point();
|
||||||
let paint_stats = PaintStats::from_shapes(&shapes); // TODO: internal allocations
|
let paint_stats = PaintStats::from_shapes(&shapes); // TODO: internal allocations
|
||||||
let paint_jobs = tessellator::tessellate_shapes(shapes, tessellation_options, self.fonts());
|
let clipped_meshes =
|
||||||
*self.paint_stats.lock() = paint_stats.with_paint_jobs(&paint_jobs);
|
tessellator::tessellate_shapes(shapes, tessellation_options, self.fonts());
|
||||||
paint_jobs
|
*self.paint_stats.lock() = paint_stats.with_clipped_meshes(&clipped_meshes);
|
||||||
|
clipped_meshes
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------
|
// ---------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ impl Widget for &epaint::stats::PaintStats {
|
||||||
shape_path,
|
shape_path,
|
||||||
shape_mesh,
|
shape_mesh,
|
||||||
shape_vec,
|
shape_vec,
|
||||||
jobs,
|
clipped_meshes,
|
||||||
vertices,
|
vertices,
|
||||||
indices,
|
indices,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
@ -97,12 +97,13 @@ impl Widget for &epaint::stats::PaintStats {
|
||||||
label(ui, shapes, "shapes").on_hover_text("Boxes, circles, etc");
|
label(ui, shapes, "shapes").on_hover_text("Boxes, circles, etc");
|
||||||
label(ui, shape_text, "text");
|
label(ui, shape_text, "text");
|
||||||
label(ui, shape_path, "paths");
|
label(ui, shape_path, "paths");
|
||||||
label(ui, shape_mesh, "meshes");
|
label(ui, shape_mesh, "nested meshes");
|
||||||
label(ui, shape_vec, "nested");
|
label(ui, shape_vec, "nested shapes");
|
||||||
ui.advance_cursor(10.0);
|
ui.advance_cursor(10.0);
|
||||||
|
|
||||||
ui.label("Tessellated:");
|
ui.label("Tessellated:");
|
||||||
label(ui, jobs, "jobs").on_hover_text("Number of separate clip rectangles");
|
label(ui, clipped_meshes, "clipped_meshes")
|
||||||
|
.on_hover_text("Number of separate clip rectangles");
|
||||||
label(ui, vertices, "vertices");
|
label(ui, vertices, "vertices");
|
||||||
label(ui, indices, "indices").on_hover_text("Three 32-bit indices per triangles");
|
label(ui, indices, "indices").on_hover_text("Three 32-bit indices per triangles");
|
||||||
ui.advance_cursor(10.0);
|
ui.advance_cursor(10.0);
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,8 @@
|
||||||
//! egui_ctx.begin_frame(raw_input);
|
//! egui_ctx.begin_frame(raw_input);
|
||||||
//! my_app.ui(&egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
//! my_app.ui(&egui_ctx); // add panels, windows and widgets to `egui_ctx` here
|
||||||
//! let (output, shapes) = egui_ctx.end_frame();
|
//! let (output, shapes) = egui_ctx.end_frame();
|
||||||
//! let paint_jobs = egui_ctx.tessellate(shapes); // create triangles to paint
|
//! let clipped_meshes = egui_ctx.tessellate(shapes); // create triangles to paint
|
||||||
//! my_integration.paint(paint_jobs);
|
//! my_integration.paint(clipped_meshes);
|
||||||
//! my_integration.set_cursor_icon(output.cursor_icon);
|
//! my_integration.set_cursor_icon(output.cursor_icon);
|
||||||
//! // Also see `egui::Output` for more
|
//! // Also see `egui::Output` for more
|
||||||
//! }
|
//! }
|
||||||
|
|
@ -109,7 +109,7 @@ pub use emath::{
|
||||||
pub use epaint::{
|
pub use epaint::{
|
||||||
color, mutex,
|
color, mutex,
|
||||||
text::{FontDefinitions, FontFamily, TextStyle},
|
text::{FontDefinitions, FontFamily, TextStyle},
|
||||||
Color32, PaintJobs, Rgba, Shape, Stroke, Texture, TextureId,
|
ClippedMesh, Color32, Rgba, Shape, Stroke, Texture, TextureId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use {
|
pub use {
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ fn test_egui_e2e() {
|
||||||
ctx.begin_frame(raw_input.clone());
|
ctx.begin_frame(raw_input.clone());
|
||||||
demo_windows.ui(&ctx);
|
demo_windows.ui(&ctx);
|
||||||
let (_output, shapes) = ctx.end_frame();
|
let (_output, shapes) = ctx.end_frame();
|
||||||
let paint_jobs = ctx.tessellate(shapes);
|
let clipped_meshes = ctx.tessellate(shapes);
|
||||||
assert!(!paint_jobs.is_empty());
|
assert!(!clipped_meshes.is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ pub fn run(mut app: Box<dyn epi::App>) -> ! {
|
||||||
.build();
|
.build();
|
||||||
app.update(&ctx, &mut frame);
|
app.update(&ctx, &mut frame);
|
||||||
let (egui_output, shapes) = ctx.end_frame();
|
let (egui_output, shapes) = ctx.end_frame();
|
||||||
let paint_jobs = ctx.tessellate(shapes);
|
let clipped_meshes = ctx.tessellate(shapes);
|
||||||
|
|
||||||
let frame_time = (Instant::now() - frame_start).as_secs_f64() as f32;
|
let frame_time = (Instant::now() - frame_start).as_secs_f64() as f32;
|
||||||
previous_frame_time = Some(frame_time);
|
previous_frame_time = Some(frame_time);
|
||||||
|
|
@ -220,7 +220,7 @@ pub fn run(mut app: Box<dyn epi::App>) -> ! {
|
||||||
&display,
|
&display,
|
||||||
ctx.pixels_per_point(),
|
ctx.pixels_per_point(),
|
||||||
app.clear_color(),
|
app.clear_color(),
|
||||||
paint_jobs,
|
clipped_meshes,
|
||||||
&ctx.texture(),
|
&ctx.texture(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,7 @@
|
||||||
#![allow(deprecated)] // legacy implement_vertex macro
|
#![allow(deprecated)] // legacy implement_vertex macro
|
||||||
|
|
||||||
use {
|
use {
|
||||||
egui::{
|
egui::{math::clamp, paint::Mesh, Color32, Rect},
|
||||||
math::clamp,
|
|
||||||
paint::{Mesh, PaintJobs},
|
|
||||||
Color32, Rect,
|
|
||||||
},
|
|
||||||
glium::{
|
glium::{
|
||||||
implement_vertex,
|
implement_vertex,
|
||||||
index::PrimitiveType,
|
index::PrimitiveType,
|
||||||
|
|
@ -128,7 +124,7 @@ impl Painter {
|
||||||
display: &glium::Display,
|
display: &glium::Display,
|
||||||
pixels_per_point: f32,
|
pixels_per_point: f32,
|
||||||
clear_color: egui::Rgba,
|
clear_color: egui::Rgba,
|
||||||
jobs: PaintJobs,
|
cipped_meshes: Vec<egui::ClippedMesh>,
|
||||||
egui_texture: &egui::Texture,
|
egui_texture: &egui::Texture,
|
||||||
) {
|
) {
|
||||||
self.upload_egui_texture(display, egui_texture);
|
self.upload_egui_texture(display, egui_texture);
|
||||||
|
|
@ -142,7 +138,7 @@ impl Painter {
|
||||||
clear_color[2],
|
clear_color[2],
|
||||||
clear_color[3],
|
clear_color[3],
|
||||||
);
|
);
|
||||||
for (clip_rect, mesh) in jobs {
|
for egui::ClippedMesh(clip_rect, mesh) in cipped_meshes {
|
||||||
self.paint_mesh(&mut target, display, pixels_per_point, clip_rect, &mesh)
|
self.paint_mesh(&mut target, display, pixels_per_point, clip_rect, &mesh)
|
||||||
}
|
}
|
||||||
target.finish().unwrap();
|
target.finish().unwrap();
|
||||||
|
|
|
||||||
|
|
@ -42,30 +42,30 @@ impl WebBackend {
|
||||||
self.ctx.begin_frame(raw_input)
|
self.ctx.begin_frame(raw_input)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn end_frame(&mut self) -> Result<(egui::Output, egui::PaintJobs), JsValue> {
|
pub fn end_frame(&mut self) -> Result<(egui::Output, Vec<egui::ClippedMesh>), JsValue> {
|
||||||
let frame_start = self
|
let frame_start = self
|
||||||
.frame_start
|
.frame_start
|
||||||
.take()
|
.take()
|
||||||
.expect("unmatched calls to begin_frame/end_frame");
|
.expect("unmatched calls to begin_frame/end_frame");
|
||||||
|
|
||||||
let (output, shapes) = self.ctx.end_frame();
|
let (output, shapes) = self.ctx.end_frame();
|
||||||
let paint_jobs = self.ctx.tessellate(shapes);
|
let clipped_meshes = self.ctx.tessellate(shapes);
|
||||||
|
|
||||||
let now = now_sec();
|
let now = now_sec();
|
||||||
self.previous_frame_time = Some((now - frame_start) as f32);
|
self.previous_frame_time = Some((now - frame_start) as f32);
|
||||||
|
|
||||||
Ok((output, paint_jobs))
|
Ok((output, clipped_meshes))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint(
|
pub fn paint(
|
||||||
&mut self,
|
&mut self,
|
||||||
clear_color: egui::Rgba,
|
clear_color: egui::Rgba,
|
||||||
paint_jobs: egui::PaintJobs,
|
clipped_meshes: Vec<egui::ClippedMesh>,
|
||||||
) -> Result<(), JsValue> {
|
) -> Result<(), JsValue> {
|
||||||
self.painter.upload_egui_texture(&self.ctx.texture());
|
self.painter.upload_egui_texture(&self.ctx.texture());
|
||||||
self.painter.clear(clear_color);
|
self.painter.clear(clear_color);
|
||||||
self.painter
|
self.painter
|
||||||
.paint_meshes(paint_jobs, self.ctx.pixels_per_point())
|
.paint_meshes(clipped_meshes, self.ctx.pixels_per_point())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn painter_debug_info(&self) -> String {
|
pub fn painter_debug_info(&self) -> String {
|
||||||
|
|
@ -190,7 +190,7 @@ impl AppRunner {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn logic(&mut self) -> Result<(egui::Output, egui::PaintJobs), JsValue> {
|
pub fn logic(&mut self) -> Result<(egui::Output, Vec<egui::ClippedMesh>), JsValue> {
|
||||||
resize_canvas_to_screen_size(self.web_backend.canvas_id());
|
resize_canvas_to_screen_size(self.web_backend.canvas_id());
|
||||||
let canvas_size = canvas_size_in_points(self.web_backend.canvas_id());
|
let canvas_size = canvas_size_in_points(self.web_backend.canvas_id());
|
||||||
let raw_input = self.input.new_frame(canvas_size);
|
let raw_input = self.input.new_frame(canvas_size);
|
||||||
|
|
@ -216,7 +216,7 @@ impl AppRunner {
|
||||||
|
|
||||||
let egui_ctx = &self.web_backend.ctx;
|
let egui_ctx = &self.web_backend.ctx;
|
||||||
self.app.update(egui_ctx, &mut frame);
|
self.app.update(egui_ctx, &mut frame);
|
||||||
let (egui_output, paint_jobs) = self.web_backend.end_frame()?;
|
let (egui_output, clipped_meshes) = self.web_backend.end_frame()?;
|
||||||
handle_output(&egui_output);
|
handle_output(&egui_output);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -227,11 +227,12 @@ impl AppRunner {
|
||||||
} = app_output;
|
} = app_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok((egui_output, paint_jobs))
|
Ok((egui_output, clipped_meshes))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn paint(&mut self, paint_jobs: egui::PaintJobs) -> Result<(), JsValue> {
|
pub fn paint(&mut self, clipped_meshes: Vec<egui::ClippedMesh>) -> Result<(), JsValue> {
|
||||||
self.web_backend.paint(self.app.clear_color(), paint_jobs)
|
self.web_backend
|
||||||
|
.paint(self.app.clear_color(), clipped_meshes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -405,8 +405,8 @@ fn paint_and_schedule(runner_ref: AppRunnerRef) -> Result<(), JsValue> {
|
||||||
fn paint_if_needed(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
fn paint_if_needed(runner_ref: &AppRunnerRef) -> Result<(), JsValue> {
|
||||||
let mut runner_lock = runner_ref.0.lock();
|
let mut runner_lock = runner_ref.0.lock();
|
||||||
if runner_lock.needs_repaint.fetch_and_clear() {
|
if runner_lock.needs_repaint.fetch_and_clear() {
|
||||||
let (output, paint_jobs) = runner_lock.logic()?;
|
let (output, clipped_meshes) = runner_lock.logic()?;
|
||||||
runner_lock.paint(paint_jobs)?;
|
runner_lock.paint(clipped_meshes)?;
|
||||||
if output.needs_repaint {
|
if output.needs_repaint {
|
||||||
runner_lock.needs_repaint.set_true();
|
runner_lock.needs_repaint.set_true();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,11 @@ pub trait Painter {
|
||||||
|
|
||||||
fn upload_egui_texture(&mut self, texture: &egui::Texture);
|
fn upload_egui_texture(&mut self, texture: &egui::Texture);
|
||||||
|
|
||||||
fn clear(&mut self, lear_color: egui::Rgba);
|
fn clear(&mut self, clear_color: egui::Rgba);
|
||||||
|
|
||||||
fn paint_meshes(&mut self, jobs: egui::PaintJobs, pixels_per_point: f32)
|
fn paint_meshes(
|
||||||
-> Result<(), JsValue>;
|
&mut self,
|
||||||
|
clipped_meshes: Vec<egui::ClippedMesh>,
|
||||||
|
pixels_per_point: f32,
|
||||||
|
) -> Result<(), JsValue>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use {
|
||||||
|
|
||||||
use egui::{
|
use egui::{
|
||||||
math::clamp,
|
math::clamp,
|
||||||
paint::{Color32, Mesh, PaintJobs, Texture},
|
paint::{Color32, Mesh, Texture},
|
||||||
vec2,
|
vec2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -478,7 +478,11 @@ impl crate::Painter for WebGlPainter {
|
||||||
gl.clear(Gl::COLOR_BUFFER_BIT);
|
gl.clear(Gl::COLOR_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_meshes(&mut self, jobs: PaintJobs, pixels_per_point: f32) -> Result<(), JsValue> {
|
fn paint_meshes(
|
||||||
|
&mut self,
|
||||||
|
clipped_meshes: Vec<egui::ClippedMesh>,
|
||||||
|
pixels_per_point: f32,
|
||||||
|
) -> Result<(), JsValue> {
|
||||||
self.upload_user_textures();
|
self.upload_user_textures();
|
||||||
|
|
||||||
let gl = &self.gl;
|
let gl = &self.gl;
|
||||||
|
|
@ -504,7 +508,7 @@ impl crate::Painter for WebGlPainter {
|
||||||
let u_sampler_loc = gl.get_uniform_location(&self.program, "u_sampler").unwrap();
|
let u_sampler_loc = gl.get_uniform_location(&self.program, "u_sampler").unwrap();
|
||||||
gl.uniform1i(Some(&u_sampler_loc), 0);
|
gl.uniform1i(Some(&u_sampler_loc), 0);
|
||||||
|
|
||||||
for (clip_rect, mesh) in jobs {
|
for egui::ClippedMesh(clip_rect, mesh) in clipped_meshes {
|
||||||
if let Some(gl_texture) = self.get_texture(mesh.texture_id) {
|
if let Some(gl_texture) = self.get_texture(mesh.texture_id) {
|
||||||
gl.bind_texture(Gl::TEXTURE_2D, Some(gl_texture));
|
gl.bind_texture(Gl::TEXTURE_2D, Some(gl_texture));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use {
|
||||||
|
|
||||||
use egui::{
|
use egui::{
|
||||||
math::clamp,
|
math::clamp,
|
||||||
paint::{Color32, Mesh, PaintJobs, Texture},
|
paint::{Color32, Mesh, Texture},
|
||||||
vec2,
|
vec2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -467,7 +467,11 @@ impl crate::Painter for WebGl2Painter {
|
||||||
gl.clear(Gl::COLOR_BUFFER_BIT);
|
gl.clear(Gl::COLOR_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn paint_meshes(&mut self, jobs: PaintJobs, pixels_per_point: f32) -> Result<(), JsValue> {
|
fn paint_meshes(
|
||||||
|
&mut self,
|
||||||
|
clipped_meshes: Vec<egui::ClippedMesh>,
|
||||||
|
pixels_per_point: f32,
|
||||||
|
) -> Result<(), JsValue> {
|
||||||
self.upload_user_textures();
|
self.upload_user_textures();
|
||||||
|
|
||||||
let gl = &self.gl;
|
let gl = &self.gl;
|
||||||
|
|
@ -493,7 +497,7 @@ impl crate::Painter for WebGl2Painter {
|
||||||
let u_sampler_loc = gl.get_uniform_location(&self.program, "u_sampler").unwrap();
|
let u_sampler_loc = gl.get_uniform_location(&self.program, "u_sampler").unwrap();
|
||||||
gl.uniform1i(Some(&u_sampler_loc), 0);
|
gl.uniform1i(Some(&u_sampler_loc), 0);
|
||||||
|
|
||||||
for (clip_rect, mesh) in jobs {
|
for egui::ClippedMesh(clip_rect, mesh) in clipped_meshes {
|
||||||
if let Some(gl_texture) = self.get_texture(mesh.texture_id) {
|
if let Some(gl_texture) = self.get_texture(mesh.texture_id) {
|
||||||
gl.bind_texture(Gl::TEXTURE_2D, Some(gl_texture));
|
gl.bind_texture(Gl::TEXTURE_2D, Some(gl_texture));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,14 @@ pub struct ClippedShape(
|
||||||
pub Shape,
|
pub Shape,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// A clip triangle and some textured triangles, all in points (logical pixels).
|
/// A [`Mesh`] within a clip rectangle.
|
||||||
pub type PaintJob = (emath::Rect, Mesh);
|
///
|
||||||
|
/// Everything is using logical points.
|
||||||
/// Grouped by clip rectangles, in points (logical pixels).
|
#[derive(Clone, Debug)]
|
||||||
pub type PaintJobs = Vec<PaintJob>;
|
pub struct ClippedMesh(
|
||||||
|
/// Clip / scissor rectangle.
|
||||||
|
/// Only show the part of the [`Mesh`] that falls within this.
|
||||||
|
pub emath::Rect,
|
||||||
|
/// The shape
|
||||||
|
pub Mesh,
|
||||||
|
);
|
||||||
|
|
|
||||||
|
|
@ -107,17 +107,17 @@ impl AllocInfo {
|
||||||
|
|
||||||
pub fn format(&self, what: &str) -> String {
|
pub fn format(&self, what: &str) -> String {
|
||||||
if self.num_allocs() == 0 {
|
if self.num_allocs() == 0 {
|
||||||
format!("{:6} {:12}", 0, what)
|
format!("{:6} {:14}", 0, what)
|
||||||
} else if self.num_allocs() == 1 {
|
} else if self.num_allocs() == 1 {
|
||||||
format!(
|
format!(
|
||||||
"{:6} {:12} {} 1 allocation",
|
"{:6} {:14} {} 1 allocation",
|
||||||
self.num_elements,
|
self.num_elements,
|
||||||
what,
|
what,
|
||||||
self.megabytes()
|
self.megabytes()
|
||||||
)
|
)
|
||||||
} else if self.element_size != ElementSize::Heterogenous {
|
} else if self.element_size != ElementSize::Heterogenous {
|
||||||
format!(
|
format!(
|
||||||
"{:6} {:12} {} {:3} allocations",
|
"{:6} {:14} {} {:3} allocations",
|
||||||
self.num_elements(),
|
self.num_elements(),
|
||||||
what,
|
what,
|
||||||
self.megabytes(),
|
self.megabytes(),
|
||||||
|
|
@ -125,7 +125,7 @@ impl AllocInfo {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"{:6} {:12} {} {:3} allocations",
|
"{:6} {:14} {} {:3} allocations",
|
||||||
"",
|
"",
|
||||||
what,
|
what,
|
||||||
self.megabytes(),
|
self.megabytes(),
|
||||||
|
|
@ -145,7 +145,7 @@ pub struct PaintStats {
|
||||||
pub shape_vec: AllocInfo,
|
pub shape_vec: AllocInfo,
|
||||||
|
|
||||||
/// Number of separate clip rectangles
|
/// Number of separate clip rectangles
|
||||||
pub jobs: AllocInfo,
|
pub clipped_meshes: AllocInfo,
|
||||||
pub vertices: AllocInfo,
|
pub vertices: AllocInfo,
|
||||||
pub indices: AllocInfo,
|
pub indices: AllocInfo,
|
||||||
}
|
}
|
||||||
|
|
@ -188,9 +188,9 @@ impl PaintStats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_paint_jobs(mut self, paint_jobs: &[crate::PaintJob]) -> Self {
|
pub fn with_clipped_meshes(mut self, clipped_meshes: &[crate::ClippedMesh]) -> Self {
|
||||||
self.jobs += AllocInfo::from_slice(paint_jobs);
|
self.clipped_meshes += AllocInfo::from_slice(clipped_meshes);
|
||||||
for (_, indices) in paint_jobs {
|
for ClippedMesh(_, indices) in clipped_meshes {
|
||||||
self.vertices += AllocInfo::from_slice(&indices.vertices);
|
self.vertices += AllocInfo::from_slice(&indices.vertices);
|
||||||
self.indices += AllocInfo::from_slice(&indices.indices);
|
self.indices += AllocInfo::from_slice(&indices.indices);
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +202,7 @@ impl PaintStats {
|
||||||
// + self.shape_text
|
// + self.shape_text
|
||||||
// + self.shape_path
|
// + self.shape_path
|
||||||
// + self.shape_mesh
|
// + self.shape_mesh
|
||||||
// + self.jobs
|
// + self.clipped_meshes
|
||||||
// + self.vertices
|
// + self.vertices
|
||||||
// + self.indices
|
// + self.indices
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
|
|
@ -668,27 +668,28 @@ pub fn tessellate_shapes(
|
||||||
shapes: Vec<ClippedShape>,
|
shapes: Vec<ClippedShape>,
|
||||||
options: TessellationOptions,
|
options: TessellationOptions,
|
||||||
fonts: &Fonts,
|
fonts: &Fonts,
|
||||||
) -> Vec<(Rect, Mesh)> {
|
) -> Vec<ClippedMesh> {
|
||||||
let mut tessellator = Tessellator::from_options(options);
|
let mut tessellator = Tessellator::from_options(options);
|
||||||
|
|
||||||
let mut jobs = PaintJobs::default();
|
let mut clipped_meshes: Vec<ClippedMesh> = Vec::default();
|
||||||
|
|
||||||
for ClippedShape(clip_rect, shape) in shapes {
|
for ClippedShape(clip_rect, shape) in shapes {
|
||||||
let start_new_job = match jobs.last() {
|
let start_new_mesh = match clipped_meshes.last() {
|
||||||
None => true,
|
None => true,
|
||||||
Some(job) => job.0 != clip_rect || job.1.texture_id != shape.texture_id(),
|
Some(cm) => cm.0 != clip_rect || cm.1.texture_id != shape.texture_id(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if start_new_job {
|
if start_new_mesh {
|
||||||
jobs.push((clip_rect, Mesh::default()));
|
clipped_meshes.push(ClippedMesh(clip_rect, Mesh::default()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let out = &mut jobs.last_mut().unwrap().1;
|
let out = &mut clipped_meshes.last_mut().unwrap().1;
|
||||||
tessellator.clip_rect = clip_rect;
|
tessellator.clip_rect = clip_rect;
|
||||||
tessellator.tessellate_shape(fonts, shape, out);
|
tessellator.tessellate_shape(fonts, shape, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.debug_paint_clip_rects {
|
if options.debug_paint_clip_rects {
|
||||||
for (clip_rect, mesh) in &mut jobs {
|
for ClippedMesh(clip_rect, mesh) in &mut clipped_meshes {
|
||||||
tessellator.clip_rect = Rect::everything();
|
tessellator.clip_rect = Rect::everything();
|
||||||
tessellator.tessellate_shape(
|
tessellator.tessellate_shape(
|
||||||
fonts,
|
fonts,
|
||||||
|
|
@ -704,14 +705,14 @@ pub fn tessellate_shapes(
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.debug_ignore_clip_rects {
|
if options.debug_ignore_clip_rects {
|
||||||
for (clip_rect, _) in &mut jobs {
|
for ClippedMesh(clip_rect, _) in &mut clipped_meshes {
|
||||||
*clip_rect = Rect::everything();
|
*clip_rect = Rect::everything();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (_, mesh) in &jobs {
|
for ClippedMesh(_, mesh) in &clipped_meshes {
|
||||||
debug_assert!(mesh.is_valid(), "Tessellator generated invalid Mesh");
|
debug_assert!(mesh.is_valid(), "Tessellator generated invalid Mesh");
|
||||||
}
|
}
|
||||||
|
|
||||||
jobs
|
clipped_meshes
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue