docs:Add plan of spilting into multi-library

This commit is contained in:
2026-05-21 20:31:17 +08:00
parent 295c5eaa24
commit 6b94ceea14
13 changed files with 5651 additions and 0 deletions
+114
View File
@@ -0,0 +1,114 @@
# Olive/Oak 模块化与多进程渲染:显式加载 + 纯 C 接口方案
> **状态**:详细实施计划
> **范围**:仅制定方案,不涉及代码变更。
> **核心目标**:
> 1. 所有业务模块编译为动态库,主进程**显式加载**(`dlopen`/`LoadLibrary`),通过**纯 C 接口**交互。
> 2. 渲染引擎拆分为独立可执行文件 `olive-renderer`,采用**"用完即弃"**的进程模型:每帧(或每几帧)启动一个新进程,渲染完成后立即退出,最大限度避免锁和状态同步问题。
---
## 目录索引
| 文件 | 内容 |
|---|---|
| `README.md` | 本文档:总体架构、设计哲学、目录索引 |
| `09-c-api-design.md` | **先读此文件**:C API 设计规范、显式加载器、内存管理、错误处理、类型映射总纲。所有其他库的 C API 都遵循此规范。 |
| `01-olivecore.md` | `libolivecore.so`:基础数据类型库(Rational, Color, TimeRange, PixelFormat, SampleBuffer 等) |
| `02-olivecodec.md` | `libolivecodec.so`:编解码库(Decoder, Encoder, Frame, Stream) |
| `03-oliveplugin.md` | `liboliveplugin.so`:OFX 插件宿主支持 |
| `04-oliveaudio.md` | `liboliveaudio.so`:音频播放与处理 |
| `05-olivenode.md` | `libolivenode.so`:节点图系统(Node, NodeGraph, Project, Param, Keyframe, Timeline, Undo) |
| `06-oliverender.md` | `liboliverender.so`:渲染引擎抽象(RenderContext, RenderJob, RenderResult) |
| `07-oliveui.md` | `liboliveui.so`:UI 层(Widget, Panel, Window, Dialog) |
| `08-olive-renderer.md` | `olive-renderer` 可执行文件:多进程渲染的"用完即弃"模型详细设计 |
| `10-implementation-roadmap.md` | 10 周小步快跑实施路线图,含每周任务、验收标准、回退策略 |
| `11-ipc-protocol.md` | 渲染子进程的 IPC 协议(命令行参数、stdin JSON、stdout NDJSON、共享内存) |
---
## 总体架构图
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ olive-editor(主进程,GUI) │
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ModuleLoader(显式加载管理器) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │dlopen │ │dlopen │ │dlopen │ │dlopen │ │dlopen │ │ │
│ │ │olivecore │ │olivecodec│ │olivenode │ │oliverender││oliveui │ │ │
│ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │
│ │ │ │ │ │ │ │ │
│ │ └────────────┴────────────┴────────────┘ │ │ │
│ │ 纯 C 接口交互 │ │ │
│ │ ▼ │ │
│ │ ┌──────────────┐ │ │
│ │ │ QProcess │ │ │
│ │ │ 启动/等待/回收 │ │ │
│ │ └──────┬───────┘ │ │
│ └───────────────────────────────────────────────────────────┼───────────┘ │
│ │ │
├──────────────────────────────────────────────────────────────┼───────────────┤
│ │ │
│ ┌───────────────────────────────────────────────────────────┘ │
│ │ olive-renderer(子进程,无 GUI,"用完即弃") │
│ │ │
│ │ 启动参数:--node-graph=/tmp/g.xml --time=1001/30000 --output-shm=/o_123 │
│ │ │
│ │ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ │ 1. 初始化 Qt Core │ │
│ │ │ 2. 初始化 OpenGL 离屏上下文 │ │
│ │ │ 3. 加载节点图 XML │ │
│ │ │ 4. 执行渲染(RenderProcessor + OpenGLRenderer) │ │
│ │ │ 5. 将帧数据写入共享内存 │ │
│ │ │ 6. 输出 JSON 结果到 stdout │ │
│ │ │ 7. 清理并退出(return 0) │ │
│ │ └─────────────────────────────────────────────────────────────────────┘ │
│ └────────────────────────────────────────────────────────────────────────────┘
│
│ 所有动态库共享的基础依赖:QtCore, FFmpeg, OpenColorIO 等(由操作系统加载器解析)
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 核心设计哲学
### 1. 显式加载 + 纯 C 接口
- **主进程不链接任何业务动态库**。`olive-editor` 的 `main.cpp` 和 `core.cpp` 中没有任何对业务模块的 `#include`(除 C API 头文件外)。
- 所有跨模块边界的交互通过**纯 C 函数**完成,使用**不透明指针(Opaque Pointer)**封装 C++ 对象。
- 动态库内部可以继续使用 C++、Qt、STL、虚函数、模板等任意特性,但对外仅暴露 C 接口。
**为什么用 C 接口而非 C++ 类?**
- C++ 的 ABI(虚表布局、name mangling、异常传播)在不同编译器/版本间不兼容。
- C 接口的符号名干净(无 mangling),`dlsym` 可直接查找。
- 未来如果需要,C 接口可被 Python、Rust、C# 等语言直接绑定。
### 2. "用完即弃"的渲染进程
- **每一帧(或每 N 帧)渲染任务 = 一个独立的操作系统进程**。
- 进程启动时接收完整的渲染参数和节点图,渲染完成后立即 `exit(0)`。
- **不存在常驻渲染进程**,因此不需要:心跳检测、崩溃恢复、状态同步、读写锁、graph_ref 缓存、复杂的取消机制。
- 主进程如果需要取消渲染,直接 `QProcess::kill()` 即可。
**可能的问题与回退**:
- 若进程启动开销(`QProcess::start()` + OpenGL 上下文初始化)导致实时预览帧率不足,可回退为**"批处理模式"**:每 3–5 帧共享一个进程,或预先启动一个进程池(但进程池内的进程仍不共享状态,每个进程只处理一个批次后自杀)。详见 `08-olive-renderer.md`。
### 3. 小步快跑
- 每个模块的改造都是**独立、可回退、可并行**的。
- 不改现有 C++ 类定义,只在其上层**新增 C 封装层**(`api/<module>_api.cpp`)。
- 保留原有 OBJECT 库编译方式,通过 CMake 选项 `-DOLIVE_DYNAMIC_MODULES=ON` 切换。
- 每完成一个模块,就通过该模块的单元测试验证,再进入下一个模块。
---
## 快速开始(阅读顺序)
1. **先读 `09-c-api-design.md`**:理解 C API 的约定、显式加载器、内存管理规则。
2. **再读 `08-olive-renderer.md`**:理解最核心的架构变革——多进程渲染。
3. **然后按任意顺序阅读 `01-` 到 `07-`**:各业务模块的具体 C API 设计和实施步骤。
4. **最后读 `10-implementation-roadmap.md`**:10 周实施计划,了解如何排期和验收。
5. **参考 `11-ipc-protocol.md`**:渲染子进程的通信协议细节。