OpenHarmony 裁剪屏
关于 OpenHarmony 的裁剪屏方案(Crop / Cut Display Panel),可以尝试是去做。
如果要让系统上层(包括 DisplayManagerService、SurfaceFlinger/Hdi Display、以及多窗口等子系统)
感知“裁剪后分辨率”,需要理解 裁剪信息传递路径。
下面分三层 梳理 整个裁剪屏分辨率的传递逻辑,可以分析应该改哪一层。
1. 裁剪屏是什么
所谓“裁剪屏”,常见于以下几种硬件情况:
1. 物理屏幕分辨率为 1920×1080,但实际可视区域只有 1840×1080(左右被边框挡住);
2. 或者是 MIPI 屏实际显示有效区小于 Panel timing 设定的 display width;
3. 或者要把系统逻辑分辨率“虚拟裁剪”到较小尺寸(例如 720×1280);
这类裁剪如果不处理,系统上层仍会以原始分辨率输出,导致显示错位或黑边
2. OpenHarmony 显示栈路径(裁剪点位置)
整个分辨率/显示信息是从底到上这样传递的:
[Display Driver HAL (HDI层)]
↓
[Display SA Service: display_service]
↓
[DisplayManager (foundation/graphic/display_manager)]
↓
[WindowManager / Rosen / UI]
要让上层感知裁剪后的分辨率,你要在底层 HDI 或 SA 层注入修改点。
3. 核心修改点与推荐裁剪位置
| 层级 | 修改作用 | 推荐修改点 | 说明 |
| 1. 驱动层 (drivers/peripheral/display) | 确定物理显示输出的 active area | 面板驱动(如 panel_xxx.c)中的 display_mode 参数(width/height/hbp/hfp/vbp/vfp) | 若硬件裁剪即 panel 实际区域缩小,这里直接填有效宽高 |
| 2. HDI 层 (drivers/peripheral/display/hdi_service) | 系统上报显示能力信息 | GetDisplayCapability() / GetDisplayMode() / GetDisplayInfo() | 可以在这里强制修改返回的 width/height 为裁剪后值,上层就会感知到裁剪分辨率 |
| 3. SA 层 (foundation/graphic/display_manager/service) | 服务层缓存的 DisplayInfo | 若只想在上层逻辑层裁剪,可修改这里的返回值 | |
| 4. 框架层 (Rosen / WindowManager) | UI 逻辑层裁剪视口 | 若裁剪只是逻辑限制(非物理),可以通过窗口策略设置视口区域 |
4. 常用方案对比
| 方案 | 适合场景 | 处理方式 |
| 硬件级裁剪(推荐) | 硬件屏幕实际可视区小 | 修改 panel 驱动 timing 参数;HDI 上报实际 width/height |
| HDI 层虚拟裁剪 | 逻辑上想缩小系统分辨率 | 在 display_hdi_impl.cpp 的 GetDisplayMode() 中调整 |
| 上层逻辑裁剪 | UI 层逻辑限制 | WindowManager 中设定逻辑坐标系裁剪(例如 Launcher 只绘制部分区域) |
5. 代码参考(HDI 层)
以 drivers/peripheral/display/hdi_service/display_hdi_impl.cpp 为例:
int32_t DisplayHdiImpl::GetDisplayMode(uint32_t devId, DisplayModeInfo &modeInfo)
{
int32_t ret = driver_->GetDisplayMode(devId, modeInfo);
if (ret != DISPLAY_SUCCESS) {
return ret;
}
// 在这里修改返回的分辨率,假设物理屏是 1920x1080,但只想显示 1840x1080
modeInfo.width = 1840;
modeInfo.height = 1080;
return DISPLAY_SUCCESS;
}
或者在:
int32_t DisplayHdiImpl::GetDisplayCapability(uint32_t devId, DisplayCapability &info)
中修改 info.phyWidth, info.phyHeight。
这样上层 DisplayManagerService 查询到的分辨率就是裁剪后的。
6. 注意事项
如果裁剪的是逻辑分辨率但面板输出没改,仍需保证硬件层输出同步,否则会出现显示偏移;
若设备支持多屏(HDMI + Panel),记得按 devId 区分;
某些芯片 BSP(如 RK3568、Hi3516)驱动层会强制读取 panel timing,不修改驱动会被重写;
如果后续要适配 UI 布局或 launcher,可能还需要在 Rosen 或 DisplayManager 的窗口布局策略中再处理一次逻辑裁剪区域。
更多推荐

所有评论(0)