Skip to main content

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}