9.1 主屏与副屏谁才是老大先问个问题系统里插了两块屏哪块是主屏在MTK平台上主屏Primary Display通常指系统启动时默认初始化的那块屏幕。它负责显示开机动画、锁屏界面、Launcher等核心内容。副屏Secondary Display则是后来添加的比如通过HDMI外接的显示器或者车机上的仪表盘屏。我记得有一次做车机项目客户要求中控屏和仪表盘屏同时显示导航。中控屏是主屏仪表盘是副屏。但问题来了——仪表盘屏的分辨率只有800x480而中控屏是1920x720。如果直接把导航画面镜像过去字都看不清。嗯这里要注意主屏和副屏的硬件参数可能完全不同。分辨率、刷新率、色彩格式甚至接口类型MIPI、LVDS、HDMI都可能不一样。驱动里必须分别配置。核心要点主屏系统启动时第一个注册的显示设备ID通常为0副屏后续添加的显示设备ID从1开始递增主屏不可热插拔副屏可以比如HDMI主屏的电源管理优先级最高在代码里主屏和副屏的区分其实是通过显示IDDisplay ID来做的。咱们后面会细讲。9.2 扩展模式与镜像模式两种玩法说白了这两种模式决定了多屏之间怎么协作。镜像模式Mirror Mode所有屏幕显示一模一样的内容。就像你对着镜子镜子里的人跟你做同样的动作。这种模式最简单驱动里只需要把同一份帧缓冲Framebuffer的数据复制到多个显示接口上。但有个坑——如果两块屏的分辨率不同镜像模式就会出问题。比如主屏是1920x1080副屏是1024x768。你镜像过去副屏要么显示不全要么被拉伸变形。我曾经踩过的坑在某个广告机项目里客户要求主屏和副屏都显示同样的广告内容。我直接开了镜像模式结果副屏是竖屏主屏是横屏画面被压扁了。后来我不得不改成扩展模式再单独调整副屏的显示区域。扩展模式Extended Mode每块屏幕独立显示不同的内容。你可以把桌面拖到副屏上或者让副屏显示特定的应用。这种模式更灵活但驱动复杂度也更高。在MTK平台上扩展模式需要为每块屏幕分配独立的图层Layer和合成通道Composition Pipeline。说白了系统要把每块屏当作独立的显示设备来管理。特性镜像模式扩展模式内容一致性完全相同各自独立分辨率要求必须一致或缩放可以不同性能开销低共享帧缓冲高独立合成典型应用演示、监控办公、车机你想想看车机场景里中控屏显示导航仪表盘显示车速副驾屏放电影——这必须是扩展模式。镜像模式根本做不到。9.3 显示ID与逻辑显示组驱动里的身份证好了概念讲完了咱们看看代码里怎么区分这些屏幕。在MTK的显示框架里每个物理显示接口都有一个唯一的显示IDDisplay ID。这个ID从0开始分配主屏通常是0副屏依次递增。但光有物理ID还不够。有时候我们需要把多个物理屏组合成一个逻辑单元。比如车机上的三块屏虽然物理上是独立的但逻辑上可以归为一组统一管理。这就是逻辑显示组Logical Display Group的概念。我的个人经验在做双屏异显项目时我习惯把主屏和副屏分别注册到不同的逻辑组。这样上层应用可以通过逻辑组ID来指定内容显示在哪块屏上。比如导航应用只显示在逻辑组0主屏而娱乐应用显示在逻辑组1副屏。来看一段简化的驱动代码展示如何注册显示ID和逻辑组// 伪代码MTK显示驱动注册流程 struct mtk_display_device { int display_id; // 物理显示ID int logical_group_id; // 逻辑显示组ID const char *name; // 设备名称 struct drm_connector *connector; }; // 注册主屏 struct mtk_display_device primary_dev { .display_id 0, .logical_group_id 0, .name Primary Display, }; register_display_device(primary_dev); // 注册副屏比如HDMI struct mtk_display_device secondary_dev { .display_id 1, .logical_group_id 1, .name HDMI Display, }; register_display_device(secondary_dev); // 如果想把两块屏归到同一个逻辑组 // 比如车机场景中控屏和仪表盘屏都归为主控组 secondary_dev.logical_group_id 0; // 与主屏同组这里要注意逻辑显示组ID和物理显示ID是两码事。物理ID是硬件层面的逻辑组ID是软件层面的。你可以把多个物理屏放到同一个逻辑组也可以让一个物理屏属于多个逻辑组虽然很少这么干。我记得在MTK8678平台上逻辑显示组还有一个重要作用——电源管理。同一个逻辑组里的屏幕可以统一控制休眠和唤醒。比如车机熄火时所有属于主控组的屏幕一起休眠省电又省心。9.4 避坑指南多屏显示常见问题最后分享几个我实际项目中遇到的坑你们以后碰到了能少走弯路。显示ID冲突如果两个显示设备注册了相同的ID系统会崩溃。我曾经在调试时忘了改副屏的ID结果一插HDMI就死机。排查了半天才发现是ID重复了。逻辑组配置错误上层应用通过逻辑组ID来发送显示内容。如果逻辑组ID配置错了内容可能显示到错误的屏幕上。比如导航画面跑到了仪表盘上那可就闹笑话了。分辨率不匹配镜像模式下如果两块屏分辨率不同一定要做缩放处理。MTK平台提供了硬件缩放器Scaler但需要驱动里正确配置。否则画面要么被裁切要么被拉伸。热插拔处理副屏支持热插拔但驱动里要处理好状态切换。比如HDMI拔掉后系统要自动把显示内容切回主屏。我曾经遇到过拔掉HDMI后系统还试图往副屏送数据结果导致内存泄漏。总结一下主屏副屏是硬件概念扩展镜像模式是软件策略显示ID和逻辑显示组是驱动里的管理手段。搞清楚了这四者的关系多屏显示驱动就成功了一半。下一章咱们会深入代码看看MTK8678上具体怎么配置这些参数。到时候我会带着你们一步步调试把理论变成实际能跑的程序。