3. 触摸与输入系统概述
这一章我们聊个很实际的问题——帧率和触摸响应到底什么关系?
很多刚接触TouchGFX的朋友会有一个误区:觉得帧率越高越好,恨不得跑到60fps、120fps。但实际做产品时你会发现,帧率太高反而可能让触摸变得迟钝。为什么会这样?说白了,MCU的资源是有限的,你把算力都花在渲染上,触摸采样自然就被挤占了。
3.1 帧率不是越高越好
先看一个我在项目里遇到的真实案例。去年做一款智能家居面板,主控是STM32F429,屏幕分辨率480×272。刚开始我把帧率锁定在60fps,结果触摸滑动列表时总感觉有「粘滞感」——手指已经划过去了,界面要滞后几十毫秒才跟上。
排查后发现,问题出在帧率太高导致触摸采样被频繁打断。TouchGFX的渲染和触摸采样共享同一个主循环,每帧渲染时间如果超过16ms,触摸扫描的周期就会被拉长。
核心结论:帧率与触摸响应之间存在资源竞争关系。高帧率 ≠ 高响应,关键是要找到平衡点。
3.2 渲染与触摸采样的时间分配
我们来看一下典型的TouchGFX主循环时间线:
从这张图可以看得很清楚:一帧时间内,渲染和触摸采样是串行执行的。渲染占用的时间越长,留给触摸采样的时间就越短。
3.3 如何找到最佳帧率
我个人习惯的做法是:先确定触摸采样需要的最低时间窗口,再反推帧率上限。
| 触摸采样率 | 每帧所需采样时间 | 推荐最大帧率 | 适用场景 |
|---|---|---|---|
| 100Hz | 10ms | 50fps | 滑动列表、拖拽 |
| 60Hz | 16ms | 30fps | 按钮点击、静态界面 |
| 200Hz | 5ms | 60fps | 手写、绘图应用 |
我的经验:对于大多数嵌入式UI场景,30fps的渲染帧率配合100Hz的触摸采样率,是性价比最高的组合。界面流畅度可以接受,触摸响应也足够灵敏。
3.4 实战:在TouchGFX中调整帧率
具体怎么调?TouchGFX提供了几个关键配置项:
// 在TouchGFXConfiguration.cpp中
static TouchGFXConfiguration config;
// 方法1:设置固定帧率
config.setFrameRate(30); // 锁定30fps
// 方法2:使用自适应帧率
config.setFrameRateCompensation(true);
config.setTargetFrameRate(30); // 目标30fps,允许波动
// 方法3:手动控制渲染间隔
config.setMinFrameInterval(33); // 最小帧间隔33ms ≈ 30fps
我曾经在一个项目里用过自适应帧率,结果发现触摸响应反而更不稳定了。原因是帧率波动导致触摸采样的时间窗口忽长忽短,触摸控制器来不及稳定。后来我改成固定30fps,问题就解决了。
避坑指南:不要同时开启帧率补偿和固定帧率限制,两者会互相干扰。选一种方式即可。
3.5 渲染优化的具体手段
既然帧率不能随便降,那就得从渲染本身下手。我总结了几条实用的优化路径:
- 减少重绘区域:只更新变化的部分,不要全屏刷新。TouchGFX的invalidate机制就是干这个的。
- 使用局部缓冲:对于静态背景,用一次渲染+局部更新,避免每帧重绘。
- 降低色彩深度:从24位色降到16位色,渲染时间能减少30%以上。
- 关闭不必要的特效:阴影、渐变、透明混合这些特效,能省就省。
// 示例:只更新变化区域
void updateSlider(int newValue) {
// 只使滑块区域无效,而不是整个屏幕
Rect sliderRect(10, 100, 200, 40);
invalidateRect(sliderRect);
// 更新滑块值
slider.setValue(newValue);
}
3.6 触摸采样与渲染的协同策略
最后分享一个我常用的策略——「分时复用」:
- 把一帧时间分成两个阶段:前70%用于渲染,后30%用于触摸采样。
- 在渲染阶段,触摸数据先缓存起来,不立即处理。
- 进入采样阶段后,批量处理缓存的触摸事件。
这样做的好处是:渲染不会被触摸中断,触摸采样也有稳定的时间窗口。说白了,就是让两者各司其职,互不干扰。
最终建议:先跑一个性能基准测试,测量你的渲染耗时和触摸采样耗时。然后根据实际数据调整帧率,而不是凭感觉设一个值。每个项目的硬件不同,最优解也不一样。
嗯,帧率和触摸响应的关系,说白了就是资源分配的艺术。你给渲染多了,触摸就饿着;你给触摸多了,界面又卡。找到那个平衡点,你的产品才能既流畅又跟手。