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}