4.4 KiB
4.4 KiB
HarmonyOS Rendering Research
1. 结论
第一阶段推荐 OpenGL ES + EGL + libmpv OpenGL Render API:ArkUI XComponent 仅交付 OHNativeWindow *,Native 层创建 EGL window surface/context,并在 GL 线程调用 mpv_render_context_render() 渲染到默认 FBO,随后 eglSwapBuffers()。视频帧不经过 ArkTS/N-API。
XComponent Surface
-> OHNativeWindow
-> EGLSurface + GLES context(Native 渲染线程)
-> libmpv OpenGL Render API
-> GPU render -> eglSwapBuffers -> Display
依据:本机 API 24 SDK 明确把 EGLNativeWindowType 定义为 struct NativeWindow *;MPV 公共 Render API 当前只公开 MPV_RENDER_API_TYPE_OPENGL 与软件渲染,未公开 Vulkan Render API。
2. 方案 A:OpenGL ES / EGL
调用边界
OH_NativeXComponent_RegisterCallback()接收 Surface 创建/变化/销毁。OnSurfaceCreated的void *window按 SDK 契约转换为OHNativeWindow *。- Native GL 线程执行
eglGetDisplay、eglInitialize、eglChooseConfig、eglCreateWindowSurface、eglCreateContext。 - 用
MPV_RENDER_PARAM_API_TYPE=MPV_RENDER_API_TYPE_OPENGL和mpv_opengl_init_params创建 render context。 - update callback 只唤醒渲染线程;该线程 make-current,调用
mpv_render_context_render(),目标为默认 FBO 0 和当前 Surface 尺寸,再 swap。 - Surface changed 更新 viewport/FBO 尺寸;Surface destroyed 先停止提交帧,再释放 render context 的 surface 相关状态和 EGLSurface。
评估
| 维度 | 结论 |
|---|---|
| 实现复杂度 | 中;MPV 已有完整 OpenGL Render API,Harmony 只负责 EGL/XComponent 生命周期 |
| MPV 支持度 | 高;公共 API 稳定,include/mpv/render.h、render_gl.h 为直接依据 |
| HarmonyOS 支持度 | 高;API 24 提供 EGL、GLES2/3、OHNativeWindow |
| Surface 生命周期 | 必须单线程串行化 create/change/destroy,销毁后禁止 swap |
| Copy 次数 | 软件解码时 FFmpeg frame 上传 GPU,至少一次 CPU→GPU;无逐帧 N-API copy |
| 4K | 渲染路径可行,性能取决于上传、shader、带宽;需 Benchmark |
| 10-bit | 软件帧可由 MPV shader 处理;Surface 色深/输出格式待设备 EGLConfig 验证 |
| HDR | MPV 色彩处理可复用,但 Harmony Surface 色域、transfer、HDR metadata 通路尚未证明 |
| 风险 | EGL context 线程归属、Surface 快速重建、默认 FBO 方向、vsync/帧节奏 |
MPV 修改范围
- Phase 1 构建
libmpv时启用plain-gl,无需先新增完整vo_harmony。 - Playback Lab 的 Harmony glue 独立放在后续
playback_lab/native/,不把 ArkTS 业务代码放进 MPV core。 - 只有确认必须让 MPV 自管 window/context 时,才新增
video/out/opengl/context_harmony.c并在 Meson 中以features['harmony']注册。
3. 方案 B:Vulkan
可行基础
API 24 提供 VK_OHOS_surface、VkSurfaceCreateInfoOHOS、vkCreateSurfaceOHOS() 与 libvulkan.so,可从 OHNativeWindow * 创建 VkSurfaceKHR。MPV 内部 vo_gpu_next / libplacebo 支持 Vulkan,但 libmpv 公共 Render API 没有 Vulkan 类型。
| 维度 | 结论 |
|---|---|
| 实现复杂度 | 高;需要新增/扩展 MPV Vulkan context 或设计受支持的嵌入路径 |
| MPV 支持度 | 内部高、公共嵌入 API 低 |
| HarmonyOS 支持度 | API 10+ 有 surface 扩展,设备扩展需枚举 |
| Surface 生命周期 | 需重建 swapchain,处理 out-of-date/suboptimal、旋转与尺寸变化 |
| Copy 次数 | 软件解码仍需上传;未来 native buffer/Vulkan interop 有降 copy 潜力 |
| 4K | 理论适合,未实测不能优于 GLES |
| 10-bit/HDR | Vulkan format/colorspace 路径潜力更强,但 Harmony 设备与系统合成支持待证 |
| 风险 | libplacebo/Vulkan 版本、OHOS surface 接入、swapchain、同步/fence、驱动差异 |
4. 禁止路径
MPV -> CPU frame -> Native Buffer -> ArkTS -> ArkUI Image 不进入正式架构。它会增加逐帧跨 N-API、CPU copy、GC/调度与背压风险,也无法作为 4K 主路径。
5. Phase 门禁
- Phase 1:只证明
libmpvarm64 编译,OpenGL Render API 符号存在。 - Phase 2:Playback Lab 证明 XComponent→EGL→首帧;记录 Surface 重建和旋转。
- Phase 3:软件解码基线后再接 OHCodec;分别测 CPU upload 与 surface decode。
- Vulkan 只有在 GLES 基线与瓶颈证据齐备后启动,不以“理论更快”替代 Benchmark。