Skip to content

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:

  1. The screen's onBeforeDraw(timestamp) callback fires - this is where you update drawable properties.
  2. The SDK serializes any changed properties as compact command deltas.
  3. Deltas are sent to the glasses over BLE.
  4. The glasses apply the changes to their on-device scene graph.
  5. 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