2. 显示控制器(Display Controller)基础:CRTC原理、时序发生器、图层混合
好,我们正式开始聊显示控制器。这东西说白了,就是整个显示子系统的“大脑”。你想想看,CPU和GPU拼命渲染出来的画面,总得有条不紊地送到屏幕上吧?谁来做这个调度?就是显示控制器。
我个人习惯把显示控制器比作一个交响乐团的指挥。它不负责演奏每个乐器(那是GPU和内存的事),但它决定什么时候让哪个乐器出声,以什么节奏出声。没有它,画面就是一锅粥。
2.1 CRTC:阴极射线管控制器的“遗产”与“新生”
CRTC,全称Cathode Ray Tube Controller。名字听着很古老,对吧?确实,它诞生于大屁股显示器的年代。但你别被名字骗了,现代LCD、OLED屏幕里,它的核心思想依然在沿用。
CRTC的核心职责就两条:
- 告诉屏幕:“现在该扫描哪一行、哪一列了。”
- 告诉内存:“现在该把哪个像素的数据给我送过来。”
它维护着一组计数器,比如行计数器、场计数器。每过一个像素时钟,列计数器加1;扫完一行,行计数器加1;扫完一帧,场计数器复位。就这么简单粗暴。
关键点:CRTC不关心像素的具体颜色,它只关心“什么时候该取数据”和“什么时候该发同步信号”。颜色是后面的图层混合模块去处理的。
我在项目中遇到过一个问题:某个平板在低分辨率下显示正常,切换到高分辨率就花屏。查了半天,发现是CRTC的时序寄存器配置错了。高分辨率下,行消隐区间变短,CRTC没来得及从内存取完数据,下一行就开始了。嗯,这就是典型的CRTC时序问题。
2.2 时序发生器:像素的“节拍器”
时序发生器,英文叫Timing Generator。它和CRTC是孪生兄弟。CRTC负责“计数”,时序发生器负责“产生节拍”。
一个完整的显示时序,包含以下几个关键参数:
| 参数 | 说明 | 我常犯的错 |
|---|---|---|
| HBP (Horizontal Back Porch) | 行同步结束到有效数据开始 | 曾经把HBP设得太小,导致屏幕左侧出现黑边 |
| HFP (Horizontal Front Porch) | 有效数据结束到行同步开始 | 这个设大了,右侧出现黑边 |
| HSYNC (Horizontal Sync) | 行同步脉冲宽度 | 太窄了,屏幕可能无法锁定同步 |
| VBP/VFP/VSYNC | 垂直方向的对应参数 | 垂直方向出问题,画面会上下抖动 |
你可能会问:“这些参数怎么来的?” 答案是:看屏幕的数据手册。每块屏幕都有自己固定的时序要求。比如一块1920x1080的屏幕,它的HBP可能是88个像素时钟,HFP可能是44个。这些值不是随便写的,是屏幕厂商测试好的。
我的调试技巧:如果你手头没有数据手册,可以先用Linux内核里现成的drm_display_mode结构体。里面预置了大部分常见分辨率的标准时序。比如drm_mode_1920x1080_60,直接拿来用,一般不会出大问题。
我曾经调试一个4K屏,死活点不亮。用示波器量HSYNC信号,发现频率是对的,但占空比不对。后来发现是时序发生器里的分频系数算错了。说白了,就是节拍器的节奏没对上。
2.3 图层混合:把“图层”叠成“画面”
现代SoC的显示控制器,通常支持多个图层(Layer/Plane)。比如一个视频层、一个UI层、一个光标层。图层混合,就是把这些层按顺序叠加起来,生成最终的画面。
混合的基本规则:
- Z-order:每个图层有一个深度值。值越小,越靠近底层。比如UI层在Z=0,视频层在Z=1,光标层在Z=2。
- Alpha混合:每个像素可以有一个透明度值。0表示完全透明,255表示完全不透明。
- 颜色格式转换:不同图层可能用不同的颜色格式(比如ARGB8888、YUV420)。混合前需要统一格式。
我建议你重点关注Alpha混合。很多驱动开发新手会忽略这一点:Alpha混合是在显示控制器硬件里完成的,不是CPU算的。 如果你把Alpha混合交给CPU去做,帧率会直接掉到个位数。
避坑指南:我曾经在某个项目里,为了省事,把UI层的背景色设成了半透明。结果发现整个画面都变暗了。为什么?因为底层是空的(全黑),半透明的UI层和黑色背景混合,自然就变暗了。正确的做法是:最底层一定要有一个完全不透明的图层,哪怕它只是一个纯色背景。
图层混合还有一个容易忽略的点:带宽。每个图层都需要从内存读取数据。如果图层太多,内存带宽会被占满。我见过一个案例,开了4个图层,结果DDR带宽打满,画面卡成PPT。解决方案?要么减少图层数,要么降低每个图层的分辨率。
2.4 核心逻辑:一张图看懂
下面我用一张SVG图,把CRTC、时序发生器、图层混合的关系画出来。你一看就明白了。
这张图里,你可以看到:CRTC和时序发生器协同工作,告诉图层混合模块“现在该处理哪一行的数据”。图层混合模块从内存中取出对应图层的像素,按照Z-order和Alpha值混合,最终通过显示接口送到屏幕。
嗯,到这里,显示控制器的三个核心模块就讲完了。CRTC是“调度员”,时序发生器是“节拍器”,图层混合是“调色师”。三者缺一不可。