Threading Model
Filament uses a sophisticated multi-threaded architecture to maximize performance on modern CPUs. This guide explains the threading model and how to work with it effectively.Overview
Filament’s threading model consists of:- Main Thread - User code, scene setup, API calls
- Render Thread - Backend driver, command execution
- Worker Threads - Parallel rendering tasks via JobSystem
Thread Safety
FromEngine.h:
An Engine instance is not thread-safe. The implementation makes no attempt to synchronize calls to an Engine instance methods. If multi-threading is needed, synchronization must be external.Important: All Engine API calls must come from the same thread, or be externally synchronized.
Engine Threading
When created, the Engine starts threads automatically:Thread Priorities
Filament sets appropriate thread priorities based on the platform:- Render Thread - High priority for consistent frame delivery
- Worker Threads - Balanced priority for parallel work
JobSystem
Filament usesutils::JobSystem for parallel workloads.
Architecture
Fromutils/include/utils/JobSystem.h:
Job Structure
Jobs are 64-byte cache-aligned structures:Creating Jobs
Multiple ways to create jobs:1. Simple Job
2. Method Pointer
3. Utility Functions
For easier usage:Job Hierarchies
Jobs can have parent-child relationships:Parallel For
Process arrays in parallel:Work Stealing
JobSystem uses a work-stealing dequeue:Render Thread Commands
Command Stream
The main thread records commands into a command stream, which the render thread executes:Command Buffer Configuration
FromEngine::Config:
Command Execution
FromCommandStream.h:
Thread Adoption
You can make external threads part of the JobSystem:Pausing the Render Thread
Experimental API:- Buffer callbacks won’t fire while paused
- Commands keep queuing until buffer limit
- Exceeding buffer limit causes abort
Message Queues
Handle callbacks on the main thread:Synchronization
flush() and flushAndWait()
Fences
For GPU synchronization:JobSystem Configuration
Configure thread count:- CPU-constrained environments - Reduce thread contention
- Power management - Limit CPU usage
- Testing - Reproduce threading issues
Single-Threaded Platforms
For platforms without threading (e.g., some embedded systems):Best Practices
Do’s
✓ Call Engine APIs from one thread (or use external locking)✓ Use JobSystem for parallel work in rendering
✓ Call pumpMessageQueues() regularly for low latency
✓ Configure jobSystemThreadCount if needed
✓ Use flushAndWait() when destroying critical resources
✓ Create job hierarchies for complex parallel tasks
Don’ts
✗ Don’t call Engine APIs from multiple threads without locking✗ Don’t create/destroy resources from callbacks without care
✗ Don’t rely on callbacks while paused
✗ Don’t exceed command buffer size
✗ Don’t use blocking operations in jobs
✗ Don’t forget to emancipate() adopted threads
Example: Parallel Scene Processing
Performance Monitoring
See Also
- Performance Optimization - Threading optimizations
- Custom Backends - Render thread architecture
- Engine API - Engine configuration