Scaler(Hardware Scaler,硬件缩放器)是 显示控制器 中专门做图像放大或缩小的硬件电路;在 DRM Plane 语境下,它允许 plane 的源图像尺寸和它在屏幕上占据的目标区域尺寸不同,并在 Scanout 过程中实时把源图像缩放成目标尺寸。
这里的 Scaler 不是机器学习里的特征归一化器,而是显示管线里的像素处理单元。例如嵌入式 SoC 的 dc8000 类显示控制器可以在扫描输出时对某个 plane 做缩放,让同一张 帧缓冲 图像以不同尺寸显示到屏幕上。
核心问题
显示控制器最终要按屏幕时序输出像素,但输入图像和屏幕目标区域经常不一样大:
- 视频源是 1280x720,屏幕窗口要显示成 1920x1080。
- 相机预览是 640x480,只放在屏幕右上角 320x240。
- UI layer 是完整屏幕尺寸,video overlay 只覆盖其中一块区域。
- framebuffer 中只取一块 crop 区域,再放大到屏幕中的某个矩形。
如果没有硬件 Scaler,系统通常只能让 GPU 或 CPU 先渲染出目标尺寸的新图像,再交给显示控制器扫描输出。这会增加一次渲染或拷贝,也会占用内存带宽。硬件 Scaler 的价值是:在显示控制器读像素送屏幕的过程中顺手完成缩放。
核心对象
| 对象 | 含义 | 工程关注点 |
|---|---|---|
| source framebuffer | plane 的源图像缓冲 | 像素格式、stride、modifier、多平面布局 |
| source rectangle | 从源图像里取出的区域 | SRC_X、SRC_Y、SRC_W、SRC_H,常用 fixed-point 表示 |
| destination rectangle | 在屏幕或 CRTC 上占据的区域 | CRTC_X、CRTC_Y、CRTC_W、CRTC_H |
| scale factor | 源尺寸到目标尺寸的比例 | 放大、缩小、水平/垂直比例是否超过硬件限制 |
| filter kernel | 缩放采样滤波规则 | nearest、bilinear、polyphase、锐度和边缘伪影 |
| line buffer | 缩放时暂存若干源行的硬件缓冲 | 支持的最大宽度、格式、带宽 |
| plane | KMS 中可独立定位和叠加的显示层 | 哪些 plane 自带 scaler、是否共享 scaler |
核心机制
在 DRM atomic plane 配置里,缩放主要由两组矩形决定:
source: SRC_X, SRC_Y, SRC_W, SRC_H
destination: CRTC_X, CRTC_Y, CRTC_W, CRTC_HSRC_*描述从 帧缓冲 中取哪块源图像,坐标属于源图像坐标系。CRTC_*描述这块图像在屏幕扫描坐标系里放到哪里。SRC_W != CRTC_W或SRC_H != CRTC_H时就需要水平或垂直缩放。- DRM 中
SRC_*常用 16.16 fixed-point 表示,也就是整数部分表示像素,低 16 位表示亚像素;这不是普通整数坐标。
缩放可以用一个反向采样模型理解。对目标区域中的每个输出像素 (x_d, y_d),硬件计算它应该从源图像哪个位置取样:
u = SRC_X + (x_d + 0.5) * SRC_W / CRTC_W - 0.5
v = SRC_Y + (y_d + 0.5) * SRC_H / CRTC_H - 0.5
out(x_d, y_d) = filter(src, u, v)(x_d, y_d)是目标矩形内的输出像素坐标。(u, v)是映射回源图像后的采样位置,可能落在非整数像素位置。SRC_W / CRTC_W是水平缩放比例;大于 1 表示缩小,小于 1 表示放大。SRC_H / CRTC_H是垂直缩放比例。filter(src, u, v)表示硬件滤波器按(u, v)附近的源像素算出输出像素;nearest 只取最接近像素,bilinear 会混合相邻像素。
这一步发生在 Scanout 路径上。显示控制器按屏幕时序生成目标像素位置,Scaler 计算对应源位置并取样,然后把结果继续送到后续的混合、色彩转换或输出接口。
典型流程如下:
- 用户态合成器设置 plane 的 framebuffer、source rectangle 和 destination rectangle。
- KMS atomic check 检查该 plane 是否支持这个格式、比例、对齐和带宽。
- DRM 驱动把比例、步进值、滤波器和 line buffer 参数写入显示控制器寄存器。
- 显示控制器开始 scanout,按目标矩形生成输出像素。
- Scaler 根据比例从源 framebuffer 取样并插值。
- 缩放后的像素进入 plane blending、颜色处理和接口输出。
工程用途
- 视频 overlay:视频解码出来的尺寸不等于窗口尺寸时,直接由 plane scaler 缩放。
- 相机预览:把传感器输出或 ISP 输出放大、缩小到屏幕预览窗口。
- 嵌入式 UI:减少 GPU 合成压力,让显示控制器完成简单缩放和叠加。
- 低功耗显示:避免额外渲染 pass 或全屏 blit,降低带宽和功耗。
- 屏幕适配:在固定 framebuffer 分辨率和不同显示分辨率之间做缩放。
调试时要看 DRM plane 属性、目标矩形、源矩形、格式、stride、modifier、缩放倍率、带宽估算和 atomic check 的失败原因。
边界与常见坑
- Scaler 不是 GPU shader:它通常是 显示控制器 的固定功能电路,能力比 GPU 灵活性低,但延迟和功耗更适合 scanout 路径。
- Scaler 不改变 framebuffer 本身:源 帧缓冲 仍保持原尺寸;变化的是扫描输出时的取样方式。
- 不是所有 plane 都能缩放:有些硬件只有 overlay plane 有 scaler,有些 scaler 在多个 plane 或 pipe 间共享。
- 缩放比例有限制:过大的放大/缩小、奇怪的宽高对齐或特定 YUV 格式可能导致 atomic check 失败。
- 格式和 modifier 会限制缩放:压缩、tiled、多平面格式可能只有部分组合能被 scaler 读取。
- 带宽不足会 underflow:缩放、多个 plane、高分辨率和高刷新率叠加时,显示控制器可能来不及取数,表现为闪屏、花屏或黑屏。
- 缩放不等于裁剪:改变
SRC_*是选择源区域,改变CRTC_*是选择屏幕目标区域;两者尺寸不同才触发缩放。