CPU-only end-of-frame: histogram update + drain into rolling. Split out so tests don't need a wgpu::Device. Production callers go through `frame_end` which handles GPU readback first and then delegates here.
(&mut self)
| 273 | /// callers go through `frame_end` which handles GPU readback |
| 274 | /// first and then delegates here. |
| 275 | fn frame_end_cpu(&mut self) { |
| 276 | // Phase 8 — sum the per-pass samples into a per-frame total |
| 277 | // for the histogram before draining. CPU sums every sample; |
| 278 | // GPU sums only those with timestamps (rest have None). |
| 279 | let mut frame_cpu = 0.0; |
| 280 | let mut frame_gpu = 0.0; |
| 281 | for s in &self.frame { |
| 282 | frame_cpu += s.cpu_us; |
| 283 | if let Some(g) = s.gpu_us { frame_gpu += g; } |
| 284 | } |
| 285 | self.frame_total_cpu_us[self.histogram_idx] = frame_cpu; |
| 286 | self.frame_total_gpu_us[self.histogram_idx] = frame_gpu; |
| 287 | self.histogram_idx = (self.histogram_idx + 1) % ROLLING_FRAMES; |
| 288 | self.histogram_filled = (self.histogram_filled + 1).min(ROLLING_FRAMES); |
| 289 | |
| 290 | for s in self.frame.drain(..) { |
| 291 | let entry = self.rolling.entry(s.label).or_insert_with(RollingStats::new); |
| 292 | entry.push(s.cpu_us, s.gpu_us); |
| 293 | } |
| 294 | self.open_cpu.clear(); |
| 295 | self.next_query = 0; |
| 296 | self.pending_gpu.clear(); |
| 297 | self.frame_count = self.frame_count.wrapping_add(1); |
| 298 | } |
| 299 | |
| 300 | /// Phase 8 — frame-history snapshot for the overlay's bar chart. |
| 301 | /// Returns `(cpu_us, gpu_us)` pairs in chronological order, oldest |
no test coverage detected