Overview
Jarvis uses a fully GPU-accelerated rendering pipeline built on wgpu, the portable Rust graphics API. Every pixel—the animated hex grid background, glowing pane borders, boot animation, CRT scanlines—is rendered through custom WGSL shaders.
wgpu-based
Metal on macOS, Vulkan/DX12 on Windows/Linux
Custom Shaders
WGSL shaders for backgrounds and effects
Instanced Quads
UI chrome rendered as GPU-instanced rectangles
VSync
60 FPS with PresentMode::Fifo
Pipeline Architecture
The jarvis-renderer crate is organized into these modules:
| Module | Purpose |
|---|
gpu | wgpu device, queue, surface, uniform buffers |
background | Hex grid, gradient, and solid color backgrounds |
effects | Per-pane glow, dim, and scanline post-processing |
boot_screen | Full-screen boot animation with surveillance HUD |
quad | Instanced rectangle drawing for UI chrome |
ui | Tab bar, status bar, pane border data structures |
render_state | Orchestrates all pipelines into per-frame rendering |
perf | Rolling-window FPS timer |
GPU Context Initialization
Initialization Sequence
Window → Instance → Surface → Adapter → Device + Queue → Surface Configuration
Create wgpu Instance
Uses default backends: Metal on macOS, Vulkan/DX12 on Windows, Vulkan on Linux.let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::all(),
..Default::default()
});
Create Surface
Wraps the winit window handle.let surface = instance.create_surface(window)?;
Request Adapter
Prefers HighPerformance (discrete GPU). Falls back to integrated or software rendering.let adapter = instance.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::HighPerformance,
compatible_surface: Some(&surface),
force_fallback_adapter: false,
}).await?;
Request Device
Requests device with default limits.let (device, queue) = adapter.request_device(
&wgpu::DeviceDescriptor {
label: Some("jarvis-renderer device"),
..Default::default()
},
None,
).await?;
Configure Surface
Sets up double-buffered vsync rendering.let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: surface.get_capabilities(&adapter).formats[0],
width: size.width,
height: size.height,
present_mode: wgpu::PresentMode::Fifo, // vsync
desired_maximum_frame_latency: 2,
alpha_mode: wgpu::CompositeAlphaMode::Auto,
view_formats: vec![],
};
surface.configure(&device, &config);
Rendering Pipeline
Per-Frame Render Order
Each frame follows a two-pass pipeline:
Pass 1: Background
Clear surface and run background shader (hex grid or gradient) as a full-screen triangle.let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("Background Pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Clear(clear_color),
store: wgpu::StoreOp::Store,
},
})],
depth_stencil_attachment: None,
..Default::default()
});
render_pass.set_pipeline(&background_pipeline);
render_pass.draw(0..3, 0..1); // full-screen triangle
Pass 2: UI Chrome
Overlay tab bar, status bar, and pane borders via instanced quad drawing.let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("UI Chrome Pass"),
color_attachments: &[Some(wgpu::RenderPassColorAttachment {
view: &view,
resolve_target: None,
ops: wgpu::Operations {
load: wgpu::LoadOp::Load, // preserve background
store: wgpu::StoreOp::Store,
},
})],
..Default::default()
});
render_pass.set_pipeline(&quad_pipeline);
render_pass.set_vertex_buffer(0, instance_buffer.slice(..));
render_pass.draw(0..6, 0..instance_count); // instanced quads
Background Modes
Five background modes are supported:
hex_grid
solid
gradient
image
video
Animated hexagonal grid with parallax scrolling.[background]
mode = "hex_grid"
hex_size = 32.0
hex_spacing = 8.0
hex_color = "#8b5cf6"
hex_opacity = 0.15
scroll_speed = 0.5
Shader: jarvis-rs/crates/jarvis-renderer/src/shaders/hex_grid.wgsl Flat color background.[background]
mode = "solid"
color = "#1a1a1a"
Two-color linear gradient.[background]
mode = "gradient"
top_color = "#2d1b4e"
bottom_color = "#0f0f0f"
angle = 135.0
Static image (PNG/JPEG).[background]
mode = "image"
path = "~/Pictures/wallpaper.png"
blur = 0.0
opacity = 1.0
Looping video (MP4/WebM).[background]
mode = "video"
path = "~/Videos/background.mp4"
volume = 0.0
Visual Effects
Effects are applied per-pane and stacked in this order:
Outer glow around focused pane.[effects.glow]
enabled = true
color = "#8b5cf6"
radius = 8.0
intensity = 0.8
Renders a blurred quad behind the pane border.
Darkens unfocused panes.[effects.dim]
enabled = true
opacity = 0.6
Overlays a semi-transparent black quad.
CRT-style horizontal scanlines.[effects.scanlines]
enabled = true
spacing = 2.0
intensity = 0.3
Shader draws alternating transparent/dark horizontal lines.
Darkens screen edges.[effects.vignette]
enabled = true
intensity = 0.5
radius = 0.8
Applied in the background shader pass.
Light bleed effect on bright areas.[effects.bloom]
enabled = false
threshold = 0.8
intensity = 0.5
Bloom requires additional render passes and impacts performance.
Boot Animation
The boot sequence runs a three-pass pipeline:
Boot Shader Pass
Full-screen surveillance HUD with scan line, corner brackets, and vignette.Shader: jarvis-rs/crates/jarvis-renderer/src/shaders/boot.wgsl
Boot Quad Pass
Progress bar track and fill rectangles.
Boot Text Pass
Title (“J A R V I S”), cycling status messages, percentage counter.Rendered with glyphon text engine.
Boot Sequence Timeline
0ms - Show title + corner brackets
500ms - "Initializing systems..."
1000ms - Progress bar appears
1500ms - "Loading configuration..."
2000ms - "Starting renderer..." (50% progress)
2500ms - "Connecting services..." (75% progress)
3000ms - "System ready" (100% progress)
3500ms - Fade to main UI
Quad Renderer
UI chrome (borders, bars) is drawn using instanced quads:
pub struct QuadInstance {
pub position: [f32; 2], // top-left corner
pub size: [f32; 2], // width, height
pub color: [f32; 4], // RGBA
pub border_radius: f32, // corner rounding
}
One draw call renders all quads:
render_pass.set_vertex_buffer(0, instance_buffer.slice(..));
render_pass.draw(0..6, 0..instance_count); // 6 vertices, N instances
Instancing allows drawing thousands of rectangles in a single GPU call.
[performance]
preset = "balanced" # "low", "balanced", "high", "ultra"
vsync = true
target_fps = 60
| Preset | Effects | Shadows | Blur | Target FPS |
|---|
| Low | Disabled | Disabled | Disabled | 30 |
| Balanced | Glow only | Disabled | 2px | 60 |
| High | All except bloom | Enabled | 4px | 60 |
| Ultra | All | Enabled | 8px | 120 |
Frame Timing
The FrameTimer tracks rolling-window FPS:
pub struct FrameTimer {
frame_times: VecDeque<Instant>,
window_size: usize,
}
impl FrameTimer {
pub fn tick(&mut self) {
self.frame_times.push_back(Instant::now());
if self.frame_times.len() > self.window_size {
self.frame_times.pop_front();
}
}
pub fn fps(&self) -> f64 {
if self.frame_times.len() < 2 { return 0.0; }
let elapsed = self.frame_times.back().unwrap()
.duration_since(*self.frame_times.front().unwrap());
(self.frame_times.len() - 1) as f64 / elapsed.as_secs_f64()
}
}
Color Management
All colors are stored as linear RGB internally and converted to sRGB for rendering:
fn linear_to_srgb(linear: f32) -> f32 {
if linear <= 0.0031308 {
linear * 12.92
} else {
1.055 * linear.powf(1.0 / 2.4) - 0.055
}
}
The surface format is typically Bgra8UnormSrgb, which applies automatic sRGB conversion.
Shader Reference
hex_grid.wgsl
Animated hexagonal background with parallax
gradient.wgsl
Two-color linear gradient
boot.wgsl
Surveillance HUD boot animation
quad.wgsl
Instanced rectangle rendering
Source References
jarvis-rs/crates/jarvis-renderer/src/render_state/state.rs - Frame orchestration
jarvis-rs/crates/jarvis-renderer/src/gpu.rs - GPU context
jarvis-rs/crates/jarvis-renderer/src/background/ - Background modes
jarvis-rs/crates/jarvis-renderer/src/effects/ - Visual effects
jarvis-rs/crates/jarvis-renderer/src/shaders/ - WGSL shaders
docs/manual/10-renderer.md - Complete reference