#![allow(clippy::too_many_arguments)]
#![allow(dead_code)]
use super::widgets::{RenderContext, ShaderProgram, UniformValue, WidgetRender};
use crate::error::{MetricsError, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
pub trait RenderingEngine: std::fmt::Debug + Send + Sync {
fn initialize(&mut self, config: RenderingConfig) -> Result<()>;
fn render_widget(&self, widget_render: &WidgetRender, context: &RenderContext) -> Result<()>;
fn clear(&self, color: [f32; 4]) -> Result<()>;
fn present(&self) -> Result<()>;
fn capabilities(&self) -> RenderingCapabilities;
fn create_shader(&self, program: &ShaderProgram) -> Result<String>;
fn update_uniforms(
&self,
shader_id: &str,
uniforms: &HashMap<String, UniformValue>,
) -> Result<()>;
fn set_viewport(&self, x: u32, y: u32, width: u32, height: u32) -> Result<()>;
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RenderingConfig {
pub backend: RenderingBackend,
pub antialiasing: bool,
pub quality: RenderQuality,
pub performance: PerformanceSettings,
pub buffers: BufferConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RenderingBackend {
WebGL2,
WebGL1,
Canvas2D,
SVG,
WebGPU,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RenderQuality {
Low,
Medium,
High,
Ultra,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceSettings {
pub frustum_culling: bool,
pub occlusion_culling: bool,
pub lod_enabled: bool,
pub instanced_rendering: bool,
pub batch_rendering: bool,
pub target_fps: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BufferConfig {
pub color_format: ColorFormat,
pub depth_buffer: bool,
pub stencil_buffer: bool,
pub msaa_samples: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum ColorFormat {
RGBA8,
RGBA16F,
RGBA32F,
RGB8,
}
#[derive(Debug, Clone)]
pub struct RenderingCapabilities {
pub max_texture_size: u32,
pub max_render_buffer_size: u32,
pub extensions: Vec<String>,
pub shader_version: String,
pub webgl_version: f32,
}
#[derive(Debug)]
pub struct UpdateManager {
config: UpdateConfig,
update_queue: Vec<UpdateRequest>,
performance_monitor: PerformanceMonitor,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateConfig {
pub update_interval: std::time::Duration,
pub batch_size: usize,
pub delta_updates: bool,
pub prioritization: bool,
}
#[derive(Debug, Clone)]
pub struct UpdateRequest {
pub widget_id: String,
pub update_type: UpdateType,
pub data: serde_json::Value,
pub priority: UpdatePriority,
pub timestamp: std::time::Instant,
}
#[derive(Debug, Clone)]
pub enum UpdateType {
Data,
Style,
Position,
Size,
FullRefresh,
}
#[derive(Debug, Clone)]
pub enum UpdatePriority {
Low,
Normal,
High,
Critical,
}
#[derive(Debug)]
pub struct PerformanceMonitor {
frame_times: std::collections::VecDeque<std::time::Duration>,
stats: RenderStatistics,
config: PerformanceConfig,
}
#[derive(Debug, Clone)]
pub struct RenderStatistics {
pub avg_frame_time: std::time::Duration,
pub fps: f64,
pub draw_calls: u32,
pub triangles: u32,
pub memory_usage: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PerformanceConfig {
pub enabled: bool,
pub sample_size: usize,
pub alerts_enabled: bool,
pub fps_threshold: f64,
}
impl UpdateManager {
pub fn new(config: UpdateConfig) -> Self {
Self {
config,
update_queue: Vec::new(),
performance_monitor: PerformanceMonitor::new(),
}
}
pub fn queue_update(&mut self, request: UpdateRequest) {
self.update_queue.push(request);
self.update_queue.sort_by(|a, b| {
match (a.priority.priority_value(), b.priority.priority_value()) {
(a_prio, b_prio) if a_prio != b_prio => b_prio.cmp(&a_prio),
_ => a.timestamp.cmp(&b.timestamp),
}
});
}
pub fn process_updates(&mut self) -> Result<Vec<UpdateRequest>> {
let batch_size = self.config.batch_size.min(self.update_queue.len());
let updates = self.update_queue.drain(0..batch_size).collect();
Ok(updates)
}
}
impl PerformanceMonitor {
pub fn new() -> Self {
Self {
frame_times: std::collections::VecDeque::new(),
stats: RenderStatistics::default(),
config: PerformanceConfig::default(),
}
}
pub fn record_frame_time(&mut self, frame_time: std::time::Duration) {
if self.frame_times.len() >= self.config.sample_size {
self.frame_times.pop_front();
}
self.frame_times.push_back(frame_time);
self.update_statistics();
}
fn update_statistics(&mut self) {
if self.frame_times.is_empty() {
return;
}
let total_time: std::time::Duration = self.frame_times.iter().sum();
self.stats.avg_frame_time = total_time / self.frame_times.len() as u32;
self.stats.fps = 1.0 / self.stats.avg_frame_time.as_secs_f64();
}
pub fn get_statistics(&self) -> &RenderStatistics {
&self.stats
}
}
impl UpdatePriority {
fn priority_value(&self) -> u32 {
match self {
UpdatePriority::Low => 1,
UpdatePriority::Normal => 2,
UpdatePriority::High => 3,
UpdatePriority::Critical => 4,
}
}
}
impl Default for RenderingConfig {
fn default() -> Self {
Self {
backend: RenderingBackend::WebGL2,
antialiasing: true,
quality: RenderQuality::High,
performance: PerformanceSettings::default(),
buffers: BufferConfig::default(),
}
}
}
impl Default for PerformanceSettings {
fn default() -> Self {
Self {
frustum_culling: true,
occlusion_culling: false,
lod_enabled: true,
instanced_rendering: true,
batch_rendering: true,
target_fps: 60,
}
}
}
impl Default for BufferConfig {
fn default() -> Self {
Self {
color_format: ColorFormat::RGBA8,
depth_buffer: true,
stencil_buffer: false,
msaa_samples: 4,
}
}
}
impl Default for UpdateConfig {
fn default() -> Self {
Self {
update_interval: std::time::Duration::from_millis(16), batch_size: 50,
delta_updates: true,
prioritization: true,
}
}
}
impl Default for PerformanceConfig {
fn default() -> Self {
Self {
enabled: true,
sample_size: 60,
alerts_enabled: true,
fps_threshold: 30.0,
}
}
}
impl Default for RenderStatistics {
fn default() -> Self {
Self {
avg_frame_time: std::time::Duration::from_millis(16),
fps: 60.0,
draw_calls: 0,
triangles: 0,
memory_usage: 0,
}
}
}