Event-driven Rendering / 事件驱动渲染与任务模型

PixelUI 把时间输入、状态更新和 framebuffer 提交分开,但除一个很窄的 ISR 入口外,所有 UI 操作都属于同一 UI task。

调度入口

API 作用
heartbeat(elapsedMs) 在普通上下文加入真实经过的毫秒数
tickFromISR(elapsedMs) 在定时 ISR 原子累加时间,并可合并唤醒 UI task
process() 消费时间,更新到期的 deadline source、Animation、Popup 和 Coroutine
renderer() 先调用 process(),再在 dirty、fade 或 continuous draw 时提交帧
handler(frameIntervalMs) 运行一次完整调度,并返回下次唤醒延时

heartbeat()tickFromISR() 只选一条时间来源,混用会重复计时。process() 的返回值只表示消费了 elapsed time;renderer() 返回值才表示实际提交了一帧。

Dirty 合并

1
2
sensorValue = newValue;
ui.markDirty();

markDirty() 把 clean 状态变为 dirty。连续多次调用只需要一次唤醒。setRenderRequestCallback() 应只发通知,不能在状态变更调用栈中同步重入 renderer()

RTOS 任务边界

1
2
3
timer ISR: tickFromISR() ----+
producer tasks: enqueue event|----> UI task: dispatch -> handler()
input ISR: enqueue event -----+

Widget setter、handleInput()markDirty()、Popup、Animation 和 ViewManager 导航都必须在 UI task 中调用。定时 ISR 可使用 setTaskNotifyFromISR() 配置的平台回调唤醒它。配置应在开启中断前完成,中断可运行时不要替换回调或 context。

周期与 tickless [试验性] [EXPERIMENTAL]

PIXELUI_ENABLE_TICKLESS=0 时,handler() 总是返回主机给定的周期。开启 tickless 后,它会合并已注册 deadline source(例如 BlinkState)、Animation、Popup、Coroutine 和 fade 的 deadline,并返回其中最早者;0 表示应立即再运行一次,PixelUI::WAIT_FOREVER 表示可停止 UI 定时器,直到外部事件唤醒。

UiDeadlineScheduler 用于接入这种“到某个时刻才发生一次离散状态变化”的对象。source 在构造/析构时自动注册/注销,调度器只在到期时调用它,并由实际状态变化决定是否标记 dirty。它不应替代连续动画。

返回的 delay 不会取代外部事件通知。低功耗移植需要同时处理“时间 deadline”和“输入/数据到达”两类唤醒。

状态查询

  • nextWakeupMs(periodicTickMs):只查询下次唤醒延时,不更新也不绘制。
  • needsHeartbeat():表示仍有时间驱动工作,不等于当前已有一帧待画。
  • hasPendingFrame():表示当前有 dirty、fade 或 continuous frame,不代表未来没有 deadline。

setContinuousDraw(true) 只用于状态必须逐帧推进、无法用 dirty 或 deadline 表达的画面。普通动画和 BlinkState 都不需要它。

最新文章
网站信息
文章数目 :
1
本站访客数 :
本站总浏览量 :
最后更新时间 :