Rendering Pipeline
This page focuses on the draw loop, rendering rate, and data flow. For an overview of the on-board rendering model and screen/drawable lifecycle, see Lifecycle.
Data Flow
sequenceDiagram
participant App as Your App
participant SDK as SDK Engine
participant BLE as BLE Transport
participant Glasses as Glasses Render Engine
App->>SDK: Create drawables
App->>SDK: screen.add(drawable)
SDK->>BLE: Object definitions and resources
BLE->>Glasses: Create objects on-device
loop Every tick
App->>SDK: Update properties
SDK->>SDK: Diff state
SDK->>BLE: Deltas only
BLE->>Glasses: Apply changes
end
loop 67 Hz, on-device
Glasses->>Glasses: Render frame
end
Draw Loop
The M2ScreenService drives a draw loop at the configured M2RenderingRate:
- The screen's
onBeforeDraw(timestamp)callback fires - this is where you update drawable properties. - The SDK serializes any changed properties as compact command deltas.
- Deltas are sent to the glasses over BLE.
- The glasses apply the changes to their on-device scene graph.
- The glasses render the next frame independently.
Rendering Rate
The draw loop tick rate is configured per screen via M2Screen.setRenderingRate():
| Rate | Tick Interval | Use Case |
|---|---|---|
M2RenderingRate.PowerSaving |
480 ms | Static or rarely-updated content |
M2RenderingRate.Normal |
45 ms | Default for most applications |
M2RenderingRate.Fast |
30 ms | Frequently-updated content |
M2RenderingRate.Video |
60 ms | Video clips and live video - matches the 15 fps video limit |
M2RenderingRate.Ota |
150 ms | Used by the SDK during firmware updates - not for apps |
Note
The rendering rate controls how often the SDK sends updates to the glasses, not how often the glasses render. It also sets the BLE connection interval, so a slower rate saves battery on both the phone and the glasses.
Example
class MyScreen : M2FullScreen() {
private val title = M2Text("title")
override fun onCreate() {
super.onCreate()
title.setFont(M2FontResource.fontMedium)
.setText("Hello Maverick AI!")
.setAlign(M2Align.CenterBoth)
.setXY(width / 2f, height / 2f)
add(title)
}
override fun onTouch(touch: M2Touch) {
if (touch == M2Touch.Tap) {
title.setText("Tapped!")
}
}
}
// Add screen to the stack
Evs.screenService.addScreen(MyScreen())
See Also
- Images - Display images on the glasses
- UI Lifecycle - Screen and drawable lifecycle events
- Animations - Animate drawable properties