perf: remove large drawing stalls
Keep resident geometry and GPU resources stable across edits, MSPACE zoom, and Model/Paper switches. Add unified PERF output for tracing remaining costs.
This commit is contained in:
parent
2bc4c1c8f3
commit
12bf126646
26 changed files with 794 additions and 325 deletions
|
|
@ -9,8 +9,8 @@ use crate::scene::{VIEWCUBE_PAD, VIEWCUBE_REGION_PX};
|
|||
use crate::ui::wrap_bar::DensitySwap;
|
||||
use crate::ui::wrap_bar::WrapFlow;
|
||||
use iced::widget::{
|
||||
button, canvas, column, container, mouse_area, pane_grid, responsive, row, shader, stack, text,
|
||||
Row, Space,
|
||||
button, canvas, column, container, mouse_area, pane_grid, responsive, row, scrollable, shader,
|
||||
stack, text, Row, Space,
|
||||
};
|
||||
use iced::window;
|
||||
use iced::{keyboard, Background, Border, Color, Element, Fill, Subscription, Task, Theme};
|
||||
|
|
@ -1121,32 +1121,44 @@ impl OpenCADStudio {
|
|||
}
|
||||
}
|
||||
|
||||
// Frame-budget HUD (Phase 5.3): toggle with the PERF command. Shows
|
||||
// the cost of the most recent wire re-tessellation — the work avoided
|
||||
// by a warm wire cache — so render-path changes can be compared
|
||||
// PR-to-PR. Reads ~0 ms while panning/zooming on a hit cache.
|
||||
if self.perf_hud && !tab.is_start {
|
||||
// Shared performance panel: terminal PERF lines plus the current
|
||||
// tessellation summary. Copy / Clear mirror the command-history panel.
|
||||
if self.perf_hud {
|
||||
let s = &tab.scene;
|
||||
let label = format!(
|
||||
let perf_w = if render_bar_w.is_finite() && render_bar_w > 1.0 {
|
||||
render_bar_w
|
||||
} else {
|
||||
320.0
|
||||
};
|
||||
let summary = format!(
|
||||
"tess {:.1} ms · {} wires · epoch {}",
|
||||
s.last_tess_ms.get(),
|
||||
s.last_tess_wires.get(),
|
||||
s.geometry_epoch,
|
||||
);
|
||||
let panel = container(text(label).size(12).color(Color {
|
||||
r: 0.6,
|
||||
g: 1.0,
|
||||
b: 0.6,
|
||||
a: 1.0,
|
||||
}))
|
||||
.padding(6)
|
||||
.style(|_: &Theme| container::Style {
|
||||
background: Some(Background::Color(Color {
|
||||
r: 0.08,
|
||||
g: 0.08,
|
||||
b: 0.08,
|
||||
a: 0.85,
|
||||
let trace = crate::perf::snapshot_text();
|
||||
let trace = if trace.is_empty() {
|
||||
"No samples yet".to_string()
|
||||
} else {
|
||||
trace
|
||||
};
|
||||
let perf_button_style = |_: &Theme, status: button::Status| button::Style {
|
||||
background: Some(Background::Color(if matches!(status, button::Status::Hovered) {
|
||||
Color {
|
||||
r: 0.24,
|
||||
g: 0.24,
|
||||
b: 0.24,
|
||||
a: 1.0,
|
||||
}
|
||||
} else {
|
||||
Color {
|
||||
r: 0.14,
|
||||
g: 0.14,
|
||||
b: 0.14,
|
||||
a: 1.0,
|
||||
}
|
||||
})),
|
||||
text_color: Color::WHITE,
|
||||
border: Border {
|
||||
color: Color {
|
||||
r: 0.35,
|
||||
|
|
@ -1158,6 +1170,62 @@ impl OpenCADStudio {
|
|||
radius: 3.0.into(),
|
||||
},
|
||||
..Default::default()
|
||||
};
|
||||
let copy_btn = button(
|
||||
row![
|
||||
crate::ui::icons::tinted(
|
||||
crate::ui::icons::COPY,
|
||||
11.0,
|
||||
Color::from_rgb(0.7, 0.85, 1.0),
|
||||
),
|
||||
text("Copy").size(11),
|
||||
]
|
||||
.spacing(4)
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
.on_press(Message::PerfCopy)
|
||||
.style(perf_button_style)
|
||||
.padding([2, 6]);
|
||||
let clear_btn = button(
|
||||
row![
|
||||
crate::ui::icons::tinted(
|
||||
crate::ui::icons::TRASH,
|
||||
11.0,
|
||||
Color::from_rgb(1.0, 0.55, 0.55),
|
||||
),
|
||||
text("Clear").size(11),
|
||||
]
|
||||
.spacing(4)
|
||||
.align_y(iced::Center),
|
||||
)
|
||||
.on_press(Message::PerfClear)
|
||||
.style(perf_button_style)
|
||||
.padding([2, 6]);
|
||||
let header = row![
|
||||
text("PERF").size(12).color(Color::from_rgb(0.6, 1.0, 0.6)),
|
||||
Space::new().width(iced::Length::Fill),
|
||||
copy_btn,
|
||||
clear_btn,
|
||||
]
|
||||
.spacing(6)
|
||||
.align_y(iced::Center);
|
||||
let log = scrollable(text(trace).size(11).color(Color::from_rgb(0.8, 0.9, 0.8)))
|
||||
.height(iced::Length::Fixed(220.0))
|
||||
.width(iced::Length::Fill);
|
||||
let panel = container(
|
||||
column![
|
||||
header,
|
||||
text(summary).size(11).color(Color::from_rgb(0.6, 1.0, 0.6)),
|
||||
log,
|
||||
]
|
||||
.spacing(5),
|
||||
)
|
||||
.width(iced::Length::Fixed(perf_w))
|
||||
.padding(6)
|
||||
.style(|_: &Theme| container::Style {
|
||||
background: None,
|
||||
border: Border::default(),
|
||||
..Default::default()
|
||||
});
|
||||
viewport_stack = viewport_stack.push(position_canvas_overlay(
|
||||
iced::Point::new(12.0, 40.0),
|
||||
|
|
|
|||
Loading…
Reference in a new issue