khora_infra/telemetry/
vram_monitor.rs

1// Copyright 2025 eraflo
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! VRAM Resource Monitor
16//!
17//! Provides monitoring capabilities for video memory (VRAM) usage through the
18//! ResourceMonitor trait interface. This allows the core monitoring system
19//! to track VRAM usage without depending on specific renderer implementations.
20
21use khora_core::telemetry::monitoring::{
22    MonitoredResourceType, ResourceMonitor, ResourceUsageReport, VramProvider,
23};
24use std::borrow::Cow;
25use std::sync::Weak;
26
27/// VRAM Monitor that interfaces with graphics devices to provide
28/// memory usage statistics through the unified ResourceMonitor interface.
29#[derive(Debug)]
30pub struct VramMonitor {
31    /// Weak reference to the VRAM provider to avoid circular dependencies
32    vram_provider: Weak<dyn VramProvider>,
33    /// Unique identifier for this monitor instance
34    monitor_id: String,
35}
36
37impl VramMonitor {
38    /// Create a new VRAM monitor
39    pub fn new(vram_provider: Weak<dyn VramProvider>, monitor_id: String) -> Self {
40        Self {
41            vram_provider,
42            monitor_id,
43        }
44    }
45
46    /// Helper to convert megabytes to bytes
47    fn mb_to_bytes(mb: f32) -> u64 {
48        (mb * 1024.0 * 1024.0) as u64
49    }
50}
51
52impl ResourceMonitor for VramMonitor {
53    fn monitor_id(&self) -> Cow<'static, str> {
54        Cow::Owned(self.monitor_id.clone())
55    }
56
57    fn resource_type(&self) -> MonitoredResourceType {
58        MonitoredResourceType::Vram
59    }
60
61    fn get_usage_report(&self) -> ResourceUsageReport {
62        if let Some(provider) = self.vram_provider.upgrade() {
63            let current_mb = provider.get_vram_usage_mb();
64            let peak_mb = provider.get_vram_peak_mb();
65            let capacity_mb = provider.get_vram_capacity_mb();
66
67            ResourceUsageReport {
68                current_bytes: Self::mb_to_bytes(current_mb),
69                peak_bytes: Some(Self::mb_to_bytes(peak_mb)),
70                total_capacity_bytes: capacity_mb.map(Self::mb_to_bytes),
71            }
72        } else {
73            // VRAM provider is no longer available
74            ResourceUsageReport::default()
75        }
76    }
77
78    fn as_any(&self) -> &dyn std::any::Any {
79        self
80    }
81
82    fn update(&self) {
83        // VRAM monitor updates are handled automatically by the graphics system
84        // through the VramProvider interface, so no additional work needed here
85    }
86}