全志科技
直播中

李俊

7年用户 1346经验值
私信 关注
[问答]

请教一下disp驱动如何进行帧同步刷新

  • 现在D1上将melis跑起来了,底层disp驱动也能点亮屏。
    遇到下面两个问题想请教一下:
    • disp驱动如何进行帧同步刷新?
    • disp驱动要显示一帧图像就是调用disp_ioctl(DISP_LAYER_SET_CONFIG, (void *)arg); ,请问上层如何知道显示一帧结束从而继续显示下一帧并释放资源?
    不过依然还有个疑问,送一帧下去后可能上层有开始要送第二帧,如果没法知道底层是否刷完的话,会造成花屏吧? 因为不知道底层刷没刷完。
  • 好的明白了,谢谢!
  • 再请教一个问题,就是假如上层开辟了一个全局静态的framebuffer,所有的帧数据都是通过这个同一个地址设置到layer里去的,那这样在disp驱动内部会实现拷贝到内部的pingpong buffer吗?还是只是记录一个指针?  如果记录的是上层传的指针就有可能虽然地下是双buffer指针,但其实是指向一个buffer,从而花屏。
  • 那这样的话,我又有一个疑问了,问题又回到最初的那个问题“应用不知道底层现在正在刷哪个buffer” 从而可能花屏。
    例如:应用分配buffer A/B,第一次显示buffer A,第二次显示buffer B,第三次由于应用不知道前两次显示的是否完成,所以按照应用层交替使用A/B buffer的逻辑,此时又会使用A,而此时底层驱动可能正在刷A,这就导致应用也会同时修改A buffer的数据,造成不同步花屏。

回帖(4)

陆苏倌

2021-12-28 16:37:10
1.依赖TCON中断,TCON终端频率就是通常我们玩游戏的时候理解的刷新率。
2.这是由软件决定的,软件控制的叫帧率,也就是产生图像的频率,图像来源可以是GPU绘制合成的,也可以是来自于VPU解码送过来的,总之,这个帧率是方案决定的。
上层不知道一帧何时开始,何时结束的,上层只需要送帧.由TCON负责同步。你送的帧不一定马上显示出来,要等TCON中断过来,才会真正显示到屏幕上的。
所以你要结合刷新率考虑帧率,帧率上去了,刷新率越大越好,帧率不能超过刷新率,图不变,同样的图刷新多少次,效果是一样的,用户感知不到,自己要有一个帧率的预估,帧率一般由片源决定的,比如30FPS,60FPS等等,帧率要小于刷新率,大于刷新率的帧率是没有意义的。
3.搞清楚这两个”率",帧率和刷新率要配合,而这个配合,是你要觉察的。
举报

李秋年

2021-12-28 16:37:32
不会的,驱动内部对显示图层分配了两个buffer,你可以认为是一个pingpong buffer机制,当前写的不是正在显示的那片buffer,两个buffer依赖TCON中断进行同步。
虽然不存在花屏的问题,但是可能存在覆盖的问题,如果你送帧的帧率和TCON刷新率不匹配(太快),可能会覆盖上次还没显示出来的帧。
比如你的帧率要控制在30fps,你就需要通过某种机制保证在这个范围内送帧,误差不要太大, 这方面RTOS做的要比linux 好很多。
举报

张明

2021-12-28 16:37:52
buffer是零拷贝,驱动内部记录是乒乓指针,buffer由应用去分配。
所以,站在这个层面看显示驱动,你不能只分配一个静态framebuffer,而是至少分配两个,然后传指针进去。
举报

孙巍

2021-12-28 16:38:16
有可能的。
buffer的指针在用户手里,用户如果不加考虑随便写,可能会导致写入正在显示的画面,导致撕裂。
以播放视频的场景为例,一般video framebuffer会有很多个,比如说10个吧,所以显示那边会有一个显示帧队列,比如有三个帧,一帧是刚刚获取的,一帧是正在显示的,还有一帧是刚刚显示完的,通过软件控制时序,是可以保证常态化如此的,你可以理解它有点类似于网络中的滑动窗口,队列中永远都有一个待显示帧,当前帧和已显示帧。并且已显示帧需要回帧后,解锁才能再次写入数据,这样就可以避免撕裂的情况。
如果是UI framebuffer,也可以参考类似的做法,多创建几个帧,并且创建回帧机制。
严谨的做法可能要用到fence机制了,如果你们有 tina sdk,在disp2驱动下有个composoer_init函数,里面的逻辑就是实现fence的,安卓上用的就是这套机制。
所以,你说的情况是存在的,但是如果你隔足够安全的时间去送帧,自然每次都是成功的,这也是melis上的做法。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分