4、MDP流水线架构:Layer Mixer、Pipe(VIG/RGB/DMA)、Destination Scaler、CSC(色彩空间转换)
好,咱们今天聊点硬核的。MDP(Mobile Display Processor)流水线,说白了就是高通显示子系统的“心脏”。你屏幕上每一帧画面,从GPU或视频解码器出来之后,都得经过这条流水线“加工”一遍,才能最终点亮屏幕。
我个人习惯把MDP流水线想象成一条汽车装配线。每个工位干不同的活,有的负责搬运原料(Pipe),有的负责调色(CSC),有的负责把多个零件拼在一起(Layer Mixer),最后还有个质检员负责缩放尺寸(Destination Scaler)。任何一个环节出问题,你看到的画面就会花屏、撕裂或者颜色不对。
我在项目中遇到过好几次,客户反馈说“屏幕颜色偏绿”,查了半天发现是CSC矩阵配置错了。嗯,这种坑踩过一次就忘不了。咱们今天就把这条流水线拆开,一个一个讲清楚。
4.1 Pipe:数据搬运工的三兄弟
MDP里的Pipe,就是负责从内存里把图像数据“搬”到处理单元的家伙。高通把Pipe分成了三种类型:VIG、RGB、DMA。你想想看,为什么要有三种?
说白了,是为了应对不同的数据源和性能需求。
| Pipe类型 | 全称 | 主要用途 | 典型场景 |
|---|---|---|---|
| VIG | Video Input Gate | 视频流输入,支持缩放和格式转换 | 摄像头预览、视频播放 |
| RGB | RGB Pipe | 图形/UI图层,支持Alpha混合 | 桌面图标、游戏UI |
| DMA | Direct Memory Access | 纯数据搬运,不做任何处理 | 帧缓冲拷贝、离线渲染 |
VIG Pipe 是最“全能”的。它自带硬件缩放器,可以把1080p的视频直接缩放到4K输出。我记得有一次调试视频通话,画面总是卡顿,后来发现是VIG Pipe的缩放参数没对齐,导致带宽浪费。
RGB Pipe 则专注于UI图层。它支持每像素alpha通道,可以实现半透明效果。你手机桌面上的天气小部件,背景半透明,就是RGB Pipe的功劳。
DMA Pipe 最简单,也最“暴力”。它不干任何额外的事,就是一股脑把数据从A搬到B。适合做屏幕截图或者帧缓冲备份。我曾经用它来做“画中画”功能,直接把视频帧拷贝到另一个图层,效率很高。
4.2 Layer Mixer:图层“搅拌机”
多个Pipe的数据都准备好了,怎么合成一个完整的画面?这就轮到Layer Mixer登场了。
Layer Mixer,你可以把它理解成一个“硬件搅拌机”。它把多个图层(Layer)按照Z-order顺序叠在一起,处理透明度、混合模式,最终输出一帧完整的图像。
高通8155的MDP通常有多个Layer Mixer,每个Mixer可以处理最多4个或8个图层。为什么需要多个?因为现在的车载系统,仪表盘、中控、HUD,每个屏幕都需要独立的Mixer。
我在项目中遇到过一个问题:中控屏幕上的导航箭头总是被背景图片挡住。查了半天,发现是Layer Mixer的Z-order配置反了。嗯,这里要注意,Z-order值越大,图层越靠上。
// 伪代码示例:配置Layer Mixer的Z-order
layer_mixer_config_t mixer_cfg;
mixer_cfg.layer_count = 3;
// 图层0:背景(最底层)
mixer_cfg.layers[0].pipe_id = RGB_PIPE_0;
mixer_cfg.layers[0].z_order = 0;
// 图层1:导航箭头(中间层)
mixer_cfg.layers[1].pipe_id = VIG_PIPE_1;
mixer_cfg.layers[1].z_order = 1;
// 图层2:触摸反馈(最顶层)
mixer_cfg.layers[2].pipe_id = DMA_PIPE_2;
mixer_cfg.layers[2].z_order = 2;
// 应用配置
mdp_apply_layer_mixer_config(&mixer_cfg);
4.3 Destination Scaler:最后的“整形师”
Layer Mixer合成完画面后,输出分辨率可能和屏幕物理分辨率不一致。比如你合成的是1920x1080的画面,但屏幕是4K的。这时候就需要Destination Scaler(目标缩放器)来“整形”。
Destination Scaler位于MDP流水线的末端,紧挨着显示接口(DSI/DP)。它负责把合成后的画面缩放到屏幕的实际分辨率。
为什么不在Pipe阶段就缩放?你想想看,如果每个Pipe都单独缩放,不仅浪费算力,还可能导致图层之间的对齐误差。不如等所有图层合成好了,统一缩放一次,精度更高,效率也更高。
我记得在调试一个双屏异显项目时,主屏是4K,副屏是1080p。两个屏幕共用一个MDP,但每个屏幕有自己的Destination Scaler。配置的时候一定要区分清楚,别把主屏的缩放参数写到副屏去了。
| 参数 | 说明 | 典型值 |
|---|---|---|
| src_width/src_height | 输入分辨率(合成后的分辨率) | 1920 x 1080 |
| dst_width/dst_height | 输出分辨率(屏幕物理分辨率) | 3840 x 2160 |
| scaling_filter | 缩放算法(双线性、双三次等) | BILINEAR / BICUBIC |
4.4 CSC:色彩空间的“翻译官”
最后,咱们聊聊CSC(Color Space Conversion,色彩空间转换)。
不同的数据源,色彩空间可能不一样。摄像头采集的是YCbCr,GPU渲染的是sRGB,视频解码出来的是BT.2020。如果不做转换,直接混在一起,颜色就全乱了。
CSC模块就是干这个的——它把不同色彩空间的像素数据,统一转换到目标色彩空间(通常是屏幕支持的色彩空间)。
CSC的核心是一个3x3的矩阵运算。每个像素的R、G、B值乘以这个矩阵,再加上偏移量,就完成了转换。
// CSC矩阵示例:YCbCr转RGB
// 假设输入是BT.601标准的YCbCr
csc_matrix_t ycbcr_to_rgb = {
.coeff = {
{ 1.164, 0.000, 1.596 },
{ 1.164, -0.392, -0.813 },
{ 1.164, 2.017, 0.000 }
},
.offset = { -16, -128, -128 }
};
// 应用CSC配置
mdp_configure_csc(VIG_PIPE_0, &ycbcr_to_rgb);
我在项目中遇到过最头疼的问题,就是HDR视频播放时颜色发灰。查了三天,发现是CSC矩阵用的是SDR的标准,没有切换到BT.2020的转换矩阵。嗯,这里要注意,HDR和SDR的CSC矩阵是完全不同的。
4.5 流水线整体流程回顾
好了,咱们把整个MDP流水线串起来捋一遍:
- Pipe阶段: VIG/RGB/DMA Pipe从内存读取数据,VIG做缩放,RGB做alpha混合,DMA纯搬运。
- CSC阶段: 每个Pipe的输出经过CSC模块,统一转换到目标色彩空间。
- Layer Mixer阶段: 多个图层按照Z-order合成一帧完整画面。
- Destination Scaler阶段: 合成后的画面缩放到屏幕物理分辨率。
- 输出: 最终数据送到DSI或DP接口,点亮屏幕。
你想想看,这一套流程走下来,每一帧画面都要经过几十次矩阵运算和像素处理。高通8155能流畅驱动三块4K屏幕,靠的就是这条精心设计的硬件流水线。
我个人习惯在调试时,先确认Pipe配置是否正确,再看CSC矩阵,最后检查Layer Mixer和Destination Scaler。按这个顺序排查,90%的问题都能快速定位。
好,今天就聊到这里。下一章咱们讲讲MDP的时钟和带宽管理,那才是真正考验BSP工程师功底的地方。