cvkg_core/render_base.rs
1/// Captures the depth of every stack-pushing operation on the `Renderer`.
2///
3/// Created via `Renderer::snapshot_render_state()` and consumed by
4/// `Renderer::restore_render_state()`. The renderer uses this to recover
5/// from mid-render panics -- any items pushed beyond the snapshot point
6/// are popped so sibling views drawn afterward don't inherit leaked
7/// clip / opacity / transform / shadow / vnode / mjolnir-slice state.
8///
9/// Frame-scoped: the renderer resets all stacks in `begin_frame()` so a
10/// snapshot taken in one frame is meaningless in another.
11#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
12pub struct RenderStateSnapshot {
13 pub clip_depth: u32,
14 pub opacity_depth: u32,
15 pub slice_depth: u32,
16 pub shadow_depth: u32,
17 pub transform_depth: u32,
18 pub vnode_depth: u32,
19}
20
21/// TelemetryData tracks real-time performance metrics for the GPU renderer.
22#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
23pub struct TelemetryData {
24 pub frame_time_ms: f32,
25 /// Total frame budget in milliseconds for the active policy.
26 pub frame_budget_ms: f32,
27 /// Remaining frame budget after the frame completed; negative means over budget.
28 pub frame_budget_remaining_ms: f32,
29 /// Remaining layout budget after layout completed; negative means the layout slice was exceeded.
30 pub layout_budget_remaining_ms: f32,
31 /// Whether the frame exceeded the total budget.
32 pub frame_over_budget: bool,
33 /// Whether the layout phase exceeded its budget slice.
34 pub layout_over_budget: bool,
35 /// 99th percentile frame time over the last window, used to detect tail latency.
36 pub p99_frame_time_ms: f32,
37 /// Statistical jitter (variance in frame timing).
38 pub frame_jitter_ms: f32,
39 /// Indicates if a hardware stall (DRAM refresh, thermal spike) was detected.
40 pub hardware_stall_detected: bool,
41
42 // Pass timing
43 pub input_time_ms: f32,
44 pub state_flush_time_ms: f32,
45 pub layout_time_ms: f32,
46 pub draw_time_ms: f32,
47 pub gpu_submit_time_ms: f32,
48
49 pub draw_calls: u32,
50 pub vertices: u32,
51
52 /// Global Berserker Pipeline Intensity (0.0 - 1.0+)
53 pub berserker_rage: f32,
54
55 // Memory breakdown
56 pub vram_usage_mb: f32,
57 pub vram_textures_mb: f32,
58 pub vram_buffers_mb: f32,
59 pub vram_pipelines_mb: f32,
60 /// Indicates if the Mega-Atlas or VRAM pools are at capacity.
61 pub vram_exhausted: bool,
62}
63
64/// Configuration for render-loop frame timing and degradation strategies.
65#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
66pub struct FrameBudget {
67 /// Target frame time in milliseconds (default: 16.0 for 60FPS)
68 pub target_ms: f32,
69 /// If true, the renderer is allowed to dynamically skip non-critical effects
70 /// (like heavy blurs or complex shadows) when the budget is exceeded.
71 pub allow_degradation: bool,
72}
73
74impl Default for FrameBudget {
75 fn default() -> Self {
76 Self {
77 target_ms: 16.0,
78 allow_degradation: true,
79 }
80 }
81}