#![allow(dead_code)]
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct DrawCallHeatmapConfig {
pub enabled: bool,
pub max_calls: u32,
pub grid_resolution: u32,
pub color_cold: [f32; 4],
pub color_hot: [f32; 4],
pub opacity: f32,
}
impl Default for DrawCallHeatmapConfig {
fn default() -> Self {
Self {
enabled: false,
max_calls: 50,
grid_resolution: 16,
color_cold: [0.0, 0.0, 1.0, 0.5],
color_hot: [1.0, 0.0, 0.0, 0.5],
opacity: 0.5,
}
}
}
#[allow(dead_code)]
pub fn new_draw_call_heatmap_config() -> DrawCallHeatmapConfig {
DrawCallHeatmapConfig::default()
}
#[allow(dead_code)]
pub fn draw_call_to_color(count: u32, cfg: &DrawCallHeatmapConfig) -> [f32; 4] {
let t = (count as f32 / cfg.max_calls as f32).clamp(0.0, 1.0);
let inv = 1.0 - t;
let r = cfg.color_cold[0] * inv + cfg.color_hot[0] * t;
let g = cfg.color_cold[1] * inv + cfg.color_hot[1] * t;
let b = cfg.color_cold[2] * inv + cfg.color_hot[2] * t;
[r, g, b, cfg.opacity]
}
#[allow(dead_code)]
pub fn hm_enable(cfg: &mut DrawCallHeatmapConfig) {
cfg.enabled = true;
}
#[allow(dead_code)]
pub fn hm_disable(cfg: &mut DrawCallHeatmapConfig) {
cfg.enabled = false;
}
#[allow(dead_code)]
pub fn hm_set_max_calls(cfg: &mut DrawCallHeatmapConfig, max: u32) {
cfg.max_calls = max.max(1);
}
#[allow(dead_code)]
pub fn hm_set_grid_resolution(cfg: &mut DrawCallHeatmapConfig, res: u32) {
cfg.grid_resolution = res.clamp(4, 256);
}
#[allow(dead_code)]
pub fn hm_set_opacity(cfg: &mut DrawCallHeatmapConfig, opacity: f32) {
cfg.opacity = opacity.clamp(0.0, 1.0);
}
#[allow(dead_code)]
pub fn hm_cell_count(cfg: &DrawCallHeatmapConfig) -> u32 {
cfg.grid_resolution * cfg.grid_resolution
}
#[allow(dead_code)]
pub fn hm_find_hottest(grid: &[u32]) -> u32 {
grid.iter().copied().max().unwrap_or(0)
}
#[allow(dead_code)]
pub fn draw_call_heatmap_to_json(cfg: &DrawCallHeatmapConfig) -> String {
format!(
r#"{{"enabled":{},"max_calls":{},"grid_resolution":{},"opacity":{:.4}}}"#,
cfg.enabled, cfg.max_calls, cfg.grid_resolution, cfg.opacity
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default() {
let c = DrawCallHeatmapConfig::default();
assert!(!c.enabled);
assert_eq!(c.grid_resolution, 16);
}
#[test]
fn test_color_cold() {
let c = DrawCallHeatmapConfig::default();
let col = draw_call_to_color(0, &c);
assert!((col[2] - 1.0).abs() < 1e-5);
}
#[test]
fn test_color_hot() {
let c = DrawCallHeatmapConfig::default();
let col = draw_call_to_color(c.max_calls, &c);
assert!((col[0] - 1.0).abs() < 1e-5);
}
#[test]
fn test_enable_disable() {
let mut c = DrawCallHeatmapConfig::default();
hm_enable(&mut c);
assert!(c.enabled);
hm_disable(&mut c);
assert!(!c.enabled);
}
#[test]
fn test_set_max_calls_min() {
let mut c = DrawCallHeatmapConfig::default();
hm_set_max_calls(&mut c, 0);
assert_eq!(c.max_calls, 1);
}
#[test]
fn test_set_grid_resolution_clamp() {
let mut c = DrawCallHeatmapConfig::default();
hm_set_grid_resolution(&mut c, 1000);
assert!(c.grid_resolution <= 256);
}
#[test]
fn test_set_opacity() {
let mut c = DrawCallHeatmapConfig::default();
hm_set_opacity(&mut c, 0.3);
assert!((c.opacity - 0.3).abs() < 1e-6);
}
#[test]
fn test_cell_count() {
let c = DrawCallHeatmapConfig::default();
assert_eq!(hm_cell_count(&c), 16 * 16);
}
#[test]
fn test_find_hottest() {
let grid = [1u32, 5, 3, 2];
assert_eq!(hm_find_hottest(&grid), 5);
}
#[test]
fn test_to_json() {
let j = draw_call_heatmap_to_json(&DrawCallHeatmapConfig::default());
assert!(j.contains("max_calls"));
assert!(j.contains("grid_resolution"));
}
}