Metal Pixel Grid Renderer
Relevant source files
The following files were used as context for generating this wiki page:
The Metal Pixel Grid Renderer is the high-performance graphics pipeline used in the Apple native shell of Dotorixel. It is responsible for rendering the pixel art canvas, a background checkerboard for transparency, and an optional pixel grid overlay. Unlike the web version which uses Canvas2D, the native Apple implementation leverages Metal to provide a higher performance ceiling and efficient GPU-based rendering.
This system is structured as a minimal Metal pipeline that renders a single fullscreen quad. The fragment shader handles multiple visual layers—checkerboard, pixel data sampling with nearest-neighbor interpolation, and grid lines—in a single draw call. This approach optimizes battery life and performance by utilizing on-demand rendering rather than a constant 60fps loop.
Sources: tasks/records/011-metal-pixel-grid-renderer.md, issues/013-apple-native-catchup.md
Architecture and Components
The rendering architecture is split between SwiftUI wrappers for platform integration and the core Metal logic.
PixelGridRenderer
The PixelGridRenderer serves as the MTKViewDelegate. It manages the Metal pipeline setup, including texture uploads for RGBA pixel data, uniform buffer management for viewport transforms, and the execution of draw calls. It is designed to render "on-demand" by setting isPaused = true and enableSetNeedsDisplay = true on the Metal view, which is suitable for pixel art where the display only needs updating during user interaction.
Sources: apple/Dotorixel/Rendering/PixelGridRenderer.swift, tasks/records/011-metal-pixel-grid-renderer.md
PixelCanvasView
This is a SwiftUI wrapper that enables the Metal view to be used within the SwiftUI-based user interface. It implements NSViewRepresentable for macOS and UIViewRepresentable for iOS/iPadOS, ensuring cross-platform compatibility within the Apple ecosystem. It uses a shared Coordinator to bridge the SwiftUI state with the Metal renderer.
Sources: apple/Dotorixel/Rendering/PixelCanvasView.swift, tasks/records/011-metal-pixel-grid-renderer.md
InputMTKView
A specialized subclass of MTKView that handles raw input events. It captures mouse and touch interactions, providing the necessary coordinate data to the rendering system and the underlying Rust core for drawing operations.
Sources: apple/Dotorixel/Rendering/InputMTKView.swift
Data Flow and Rendering Pipeline
The rendering process follows a specific flow from state changes to GPU execution.
The diagram shows the flow from an editor state update to the final output on the MTKView.
Sources: apple/Dotorixel/Rendering/PixelGridRenderer.swift, tasks/records/011-metal-pixel-grid-renderer.md
Pipeline Configuration
The system uses a single-pass rendering approach where all components are computed per-fragment in the shader.
| Feature | Implementation Detail |
|---|---|
| Interpolation | Nearest-neighbor (preserves pixel edges) |
| Transparency | Computed checkerboard pattern in fragment shader |
| Grid Overlay | Procedural grid lines based on fragment coordinates |
| Update Strategy | On-demand (isPaused = true) |
| Viewport | Supports panOffset and zoom (calculated at draw time) |
Sources: tasks/records/011-metal-pixel-grid-renderer.md, apple/Dotorixel/Rendering/PixelGridRenderer.swift
Shaders and Visual Composition
The visual output is defined in Shaders.metal. The vertex shader provides a fullscreen quad, while the fragment shader performs the logic for layered rendering.
Rendering Sequence
- Checkerboard: A background pattern is generated to indicate transparent areas of the canvas.
- Pixel Data: The RGBA texture (representing the pixel canvas) is sampled using nearest-neighbor filtering.
- Grid Overlay: If enabled, the shader calculates the boundaries between pixels and overlays a grid line. In the Pebble UI theme, the grid color is specifically set to
#E0DCD7.
Sources: tasks/records/011-metal-pixel-grid-renderer.md, tasks/records/014-basic-swiftui-ui.md
The sequence shows how an editor state change triggers a commit to the GPU to refresh the display.
Sources: apple/Dotorixel/Rendering/PixelGridRenderer.swift, tasks/records/011-metal-pixel-grid-renderer.md
Implementation Details
Texture Management
The PixelGridRenderer creates a Metal texture that matches the dimensions of the pixel canvas. Pixel data is uploaded from the Rust core's pixel buffer into this texture as RGBA data.
Viewport and Scaling
The renderer reads the drawableSize from the MTKView at draw time. This avoids issues where the view might have a zero-size during the initial SwiftUI layout. The viewport math incorporates displayScale to ensure the canvas is correctly centered and sized across different Retina display densities.
Sources: tasks/records/011-metal-pixel-grid-renderer.md, tasks/records/014-basic-swiftui-ui.md
Conclusion
The Metal Pixel Grid Renderer provides Dotorixel's Apple native shell with a robust and efficient drawing surface. By consolidating checkerboard, pixels, and grid rendering into a single-pass fragment shader, the system achieves high performance while maintaining the sharp, aliasing-free look essential for pixel art editors. Its integration with SwiftUI through representable views and its on-demand rendering strategy balance high-ceiling performance with efficient resource usage.