bevy_render/diagnostic/
mesh_allocator_diagnostic_plugin.rs1use bevy_app::{Plugin, PreUpdate};
2use bevy_diagnostic::{Diagnostic, DiagnosticPath, Diagnostics, RegisterDiagnostic};
3use bevy_ecs::{resource::Resource, system::Res};
4use bevy_platform::sync::atomic::{AtomicU64, AtomicUsize, Ordering};
5
6use crate::{mesh::allocator::MeshAllocator, Extract, ExtractSchedule, RenderApp};
7
8static MESH_ALLOCATOR_SLABS: DiagnosticPath = DiagnosticPath::const_new("mesh_allocator_slabs");
10
11static MESH_ALLOCATOR_SLABS_SIZE: DiagnosticPath =
13 DiagnosticPath::const_new("mesh_allocator_slabs_size");
14
15static MESH_ALLOCATOR_ALLOCATIONS: DiagnosticPath =
17 DiagnosticPath::const_new("mesh_allocator_allocations");
18
19pub struct MeshAllocatorDiagnosticPlugin;
20
21impl MeshAllocatorDiagnosticPlugin {
22 pub fn slabs_diagnostic_path() -> &'static DiagnosticPath {
24 &MESH_ALLOCATOR_SLABS
25 }
26 pub fn slabs_size_diagnostic_path() -> &'static DiagnosticPath {
28 &MESH_ALLOCATOR_SLABS_SIZE
29 }
30 pub fn allocations_diagnostic_path() -> &'static DiagnosticPath {
32 &MESH_ALLOCATOR_ALLOCATIONS
33 }
34}
35
36impl Plugin for MeshAllocatorDiagnosticPlugin {
37 fn build(&self, app: &mut bevy_app::App) {
38 app.register_diagnostic(
39 Diagnostic::new(MESH_ALLOCATOR_SLABS.clone()).with_suffix(" slabs"),
40 )
41 .register_diagnostic(
42 Diagnostic::new(MESH_ALLOCATOR_SLABS_SIZE.clone()).with_suffix(" bytes"),
43 )
44 .register_diagnostic(
45 Diagnostic::new(MESH_ALLOCATOR_ALLOCATIONS.clone()).with_suffix(" meshes"),
46 )
47 .init_resource::<MeshAllocatorMeasurements>()
48 .add_systems(PreUpdate, add_mesh_allocator_measurement);
49
50 if let Some(render_app) = app.get_sub_app_mut(RenderApp) {
51 render_app.add_systems(ExtractSchedule, measure_allocator);
52 }
53 }
54}
55
56#[derive(Debug, Default, Resource)]
57struct MeshAllocatorMeasurements {
58 slabs: AtomicUsize,
59 slabs_size: AtomicU64,
60 allocations: AtomicUsize,
61}
62
63fn add_mesh_allocator_measurement(
64 mut diagnostics: Diagnostics,
65 measurements: Res<MeshAllocatorMeasurements>,
66) {
67 diagnostics.add_measurement(&MESH_ALLOCATOR_SLABS, || {
68 measurements.slabs.load(Ordering::Relaxed) as f64
69 });
70 diagnostics.add_measurement(&MESH_ALLOCATOR_SLABS_SIZE, || {
71 measurements.slabs_size.load(Ordering::Relaxed) as f64
72 });
73 diagnostics.add_measurement(&MESH_ALLOCATOR_ALLOCATIONS, || {
74 measurements.allocations.load(Ordering::Relaxed) as f64
75 });
76}
77
78fn measure_allocator(
79 measurements: Extract<Res<MeshAllocatorMeasurements>>,
80 allocator: Res<MeshAllocator>,
81) {
82 measurements
83 .slabs
84 .store(allocator.slab_count(), Ordering::Relaxed);
85 measurements
86 .slabs_size
87 .store(allocator.slabs_size(), Ordering::Relaxed);
88 measurements
89 .allocations
90 .store(allocator.allocations(), Ordering::Relaxed);
91}