Egloo 架构设计
Egloo 是一个基于 Kotlin Multiplatform 的 OpenGL ES 框架,提供了跨平台的图形渲染能力。
1. 架构概览
Egloo 采用分层架构设计,主要包含以下几个层次:
graph TD
A[应用层] --> B[场景层]
B --> C[图形层]
C --> D[渲染层]
D --> E[核心层]
E --> F[平台特定实现]
subgraph "核心层"
E1[EGL管理] --- E2[表面管理]
end
subgraph "渲染层"
D1[着色器程序] --- D2[缓冲区管理] --- D3[纹理处理]
end
subgraph "图形层"
C1[2D图形] --- C2[3D图形] --- C3[几何工具]
end
subgraph "场景层"
B1[场景管理] --- B2[渲染顺序] --- B3[对象变换]
end
subgraph "平台特定实现"
F1[Android JVM] --- F2[Android Native]
end
上图展示了Egloo的整体架构和各层之间的关系。
1.1 核心层 (Core Layer)
核心层提供了与 OpenGL ES 和 EGL 交互的基础设施:
-
EGL 管理:
EglCore:平台特定的 EGL 上下文管理实现EglNativeCore:跨平台的 EGL 核心功能实现Egloo:框架入口和工具类
-
表面管理:
EglSurface:基础渲染表面EglWindowSurface:窗口渲染表面
1.2 渲染层 (Rendering Layer)
渲染层提供了图形渲染的核心组件:
-
着色器程序:
GlFlatProgram:基础着色器程序实现
-
缓冲区管理:
GlBuffer:通用缓冲区GlShaderStorageBuffer:着色器存储缓冲区
-
纹理处理:
- 纹理加载、管理和渲染
1.3 图形层 (Graphics Layer)
图形层提供了各种图形对象的实现:
-
2D 图形:
Gl2dDrawable:2D 图形基类GlCircle:圆形GlRect:矩形GlRoundRect:圆角矩形GlSquare:正方形GlTriangle:三角形GlPolygon:多边形
-
3D 图形:
Gl3dDrawable:3D 图形基类
-
几何工具:
PointF:点RectF:矩形区域IndexedPointF:索引点IndexedSegmentF:索引线段
1.4 场景层 (Scene Layer)
场景层负责管理复杂的渲染场景:
- 场景管理:
- 场景图管理
- 渲染顺序控制
- 对象变换
2. 多平台支持
Egloo 使用 Kotlin Multiplatform (KMP) 实现跨平台支持,通过 expect/actual 机制实现代码共享和平台特定实现的分离。
graph TD
A[Kotlin Multiplatform] --> B[共享代码 commonMain]
A --> C[Android JVM androidJvmMain]
A --> D[Android Native androidNativeMain]
B --> E[接口定义]
B --> F[抽象类]
B --> G[通用算法]
C --> H[Android特定实现]
D --> I[Native特定实现]
E -.-> H
E -.-> I
F -.-> H
F -.-> I
2.1 Kotlin Multiplatform 架构设计
Egloo 的 KMP 架构基于以下原则设计:
2.1.1 代码组织结构
-
源集划分:
commonMain: 包含所有平台共享的代码androidJvmMain: Android JVM 平台特定实现androidNativeMain: Android Native (C/C++) 平台特定实现
-
依赖管理:
- 每个源集有独立的依赖声明
- 共享源集依赖被所有平台继承
- 平台特定源集可以添加特定依赖
2.1.2 平台抽象机制
-
expect/actual 声明:
- 在
commonMain中使用expect声明接口和类 - 在平台特定源集中使用
actual实现这些声明 - 例如:
GlShaderLoader在 common 中声明,在各平台中实现
- 在
-
接口抽象:
- 定义通用接口,由各平台实现
- 允许平台特定优化,同时保持 API 一致性
2.1.3 互操作性
-
JVM 互操作:
- 与 Android SDK 和 Java 库的无缝集成
- 使用 JNI 桥接 Java 和 Native 代码
-
Native 互操作:
- 使用
kotlinx.cinterop与 C 库交互 - 直接访问 OpenGL ES 和 EGL 的 Native API
- 使用
2.2 共享代码 (commonMain)
-
平台无关的核心实现:
- 数学库(矩阵、向量计算)
- 图形基础组件(点、线、形状)
- 渲染管线抽象
-
通用的数据结构和算法:
- 缓冲区管理
- 场景图算法
- 资源管理
-
接口定义和抽象类:
- OpenGL 操作抽象
- 渲染组件接口
- 平台服务接口
2.3 Android JVM (androidJvmMain)
-
Android 特定的 EGL/GL 实现:
- 使用 Android 的
GLES20和EGL14API - 与 Android 的
SurfaceView和TextureView集成
- 使用 Android 的
-
与 Android 系统的集成:
- 生命周期管理
- 资源加载
- 上下文访问
-
JVM 平台优化:
- 利用 JVM 垃圾回收
- 线程管理
- 异常处理
2.4 Android Native (androidNativeMain)
-
Native 层的 EGL/GL 实现:
- 直接调用 OpenGL ES 和 EGL 的 C API
- 使用
kotlinx.cinterop进行 C 函数调用
-
32/64 位支持:
- 适配不同 CPU 架构
- 内存对齐和指针操作
-
性能优化:
- 减少 JNI 调用开销
- 直接内存访问
- 避免不必要的对象创建
3. 核心组件详解
Egloo 的核心组件设计遵循 OpenGL ES 的渲染流程,同时提供了更高级的抽象以简化开发。
classDiagram
class GlContext {
+create(): GlContext
+makeCurrent(): Boolean
+release(): Boolean
}
class GlProgram {
-shaders: List<GlShader>
-attributes: Map<String, Int>
-uniforms: Map<String, Int>
+use(): Boolean
+getAttributeLocation(name: String): Int
+getUniformLocation(name: String): Int
}
class GlShader {
-type: Int
-source: String
+compile(): Boolean
}
class GlShaderLoader {
+loadShaderSource(path: String): String
}
class GlTexture {
-target: Int
-unit: Int
+bind(): Boolean
+setParameter(pname: Int, param: Int): Boolean
}
class GlDrawable {
+draw(program: GlProgram): Boolean
}
class GlScene {
-drawables: List<GlDrawable>
+addDrawable(drawable: GlDrawable): Boolean
+draw(): Boolean
}
GlProgram --> GlShader: contains
GlProgram --> GlShaderLoader: uses
GlScene --> GlDrawable: contains
GlDrawable --> GlProgram: uses
GlDrawable --> GlTexture: may use
GlContext --> GlProgram: manages
GlContext --> GlTexture: manages
GlShaderLoader是对源码进行优化,支持res中glsl文件加载。
3.1 EGL 管理
EGL 是 OpenGL ES 与底层窗口系统之间的接口,负责创建和管理渲染上下文。
flowchart LR
A[应用程序] --> B[EGL API]
B --> C[窗口系统]
B --> D[OpenGL ES API]
D --> E[GPU]
subgraph "Egloo EGL 管理"
F[GlContext] --> G[EglCore]
G --> H[EglSurface]
H --> I[Native Window]
end
3.1.1 GlContext
GlContext 是 Egloo 中 EGL 上下文的抽象,负责:
- 创建和管理 OpenGL ES 上下文
- 处理上下文的生命周期
- 提供线程安全的上下文切换
3.1.2 EglCore
EglCore 封装了 EGL 的核心功能:
- 配置 EGL 显示和上下文
- 选择合适的 EGL 配置
- 管理 EGL 资源的生命周期
3.1.3 EglSurface
EglSurface 表示渲染目标:
- 可以是窗口表面(用于屏幕显示)
- 可以是像素缓冲区(用于离屏渲染)
- 处理帧缓冲区交换和同步
3.2 着色器程序
着色器程序是 OpenGL ES 渲染管线的核心,Egloo 提供了简化的着色器管理。
flowchart TD
A[GlProgram] --> B[顶点着色器]
A --> C[片段着色器]
B --> D[编译]
C --> E[编译]
D --> F[链接程序]
E --> F
F --> G[使用程序]
H[GlShaderLoader] --> B
H --> C
3.2.1 GlProgram
GlProgram 封装了 OpenGL ES 程序对象:
- 管理着色器的编译和链接
- 提供属性和统一变量的位置查询
- 简化程序的使用和资源管理
3.2.2 GlShader
GlShader 表示单个着色器:
- 支持顶点和片段着色器
- 处理着色器编译
- 提供错误检查和日志
3.2.3 GlShaderLoader
GlShaderLoader 负责从不同来源加载着色器代码:
- 从资源文件加载
- 从字符串加载
- 支持跨平台的资源访问
3.3 渲染对象
Egloo 提供了一系列渲染对象,用于构建复杂的场景。
flowchart LR
A[GlScene] --> B[GlDrawable]
B --> C[GlFlatDrawable]
B --> D[GlTexturedDrawable]
C --> E[GlRect]
C --> F[GlTriangle]
C --> G[GlCircle]
D --> H[GlTexturedRect]
3.3.1 GlDrawable
GlDrawable 是所有可绘制对象的基类:
- 定义绘制接口
- 管理顶点数据
- 处理变换和属性
3.3.2 GlScene
GlScene 管理多个可绘制对象:
- 维护绘制顺序
- 处理场景更新
- 优化渲染性能
3.3.3 特定形状
Egloo 提供了常用形状的实现:
GlRect: 矩形GlTriangle: 三角形GlCircle: 圆形GlTexturedRect: 纹理矩形
3.4 纹理管理
纹理是 OpenGL ES 中重要的资源类型,Egloo 简化了纹理的创建和使用。
flowchart TD
A[GlTexture] --> B[创建纹理]
B --> C[配置参数]
C --> D[上传数据]
D --> E[使用纹理]
F[图像源] --> D
G[GlTextureLoader] --> F
3.4.1 GlTexture
GlTexture 封装了 OpenGL ES 纹理对象:
- 创建和绑定纹理
- 设置纹理参数
- 管理纹理单元
3.4.2 GlTextureLoader
GlTextureLoader 负责从不同来源加载纹理数据:
- 从位图加载
- 从资源文件加载
- 支持不同的图像格式
4. 跨平台实现策略
Egloo 通过精心设计的抽象层次和平台特定实现,实现了跨平台的 OpenGL ES 渲染能力。
flowchart TD
A[通用接口层] --> B[平台抽象层]
B --> C[Android JVM 实现]
B --> D[Android Native 实现]
subgraph "通用接口层"
A1[GlProgram] --- A2[GlDrawable] --- A3[GlScene]
end
subgraph "平台抽象层"
B1[expect 声明] --- B2[平台接口]
end
subgraph "Android JVM 实现"
C1[actual 实现] --- C2[Android API 调用]
end
subgraph "Android Native 实现"
D1[actual 实现] --- D2[Native API 调用]
end
4.1 共享代码策略
Egloo 采用以下策略来最大化代码共享:
-
接口驱动设计:
- 定义清晰的接口边界
- 使用抽象类封装通用逻辑
- 将平台特定代码隔离到实现类
-
依赖注入:
- 使用工厂模式创建平台特定实例
- 运行时注入适当的实现
- 避免硬编码依赖
-
预处理器指令:
- 使用
expect/actual声明 - 条件编译处理平台差异
- 源集分离管理平台代码
- 使用
4.2 平台特定优化
每个平台实现都针对其特性进行了优化:
4.2.1 Android JVM 优化
- 利用 Android 图形 API 的高级功能
- 与 Android 生命周期集成
- 使用 Android 特定的内存管理策略
4.2.2 Android Native 优化
- 直接内存操作减少开销
- 避免 JNI 调用的频繁跨边界
- 使用 Native 内存分配策略
5. 性能优化与最佳实践
Egloo 架构设计中包含了多项性能优化策略和最佳实践。
5.1 渲染性能优化
graph TD
A[批处理渲染] --> B[减少状态切换]
C[顶点缓冲对象] --> D[减少数据传输]
E[着色器优化] --> F[减少计算复杂度]
G[纹理管理] --> H[减少纹理切换]
-
批处理渲染:
- 合并相似绘制调用
- 减少 OpenGL ES 状态切换
- 优化绘制顺序
-
缓冲区管理:
- 使用顶点缓冲对象 (VBO)
- 适当时使用索引缓冲对象 (IBO)
- 减少缓冲区更新频率
-
着色器优化:
- 简化着色器计算
- 避免条件分支
- 使用内置函数
-
纹理管理:
- 纹理图集减少绑定切换
- 合理设置纹理过滤和包装模式
- 使用适当的纹理格式和大小
5.2 内存管理
-
资源生命周期:
- 及时释放不再使用的资源
- 使用引用计数管理共享资源
- 避免资源泄漏
-
内存分配策略:
- 减少渲染过程中的对象创建
- 使用对象池重用临时对象
- 避免频繁的垃圾回收
-
缓冲区策略:
- 预分配足够的缓冲区空间
- 使用直接缓冲区减少复制
- 合理设置缓冲区大小
5.3 多线程渲染
-
渲染线程:
- 将渲染操作与主线程分离
- 确保 OpenGL ES 上下文正确共享
- 处理线程间同步
-
资源加载:
- 异步加载纹理和着色器
- 使用后台线程准备渲染数据
- 实现资源加载进度反馈
-
线程安全:
- 保护共享资源访问
- 避免跨线程 OpenGL ES 调用
- 使用同步原语确保数据一致性
6. 总结
Egloo 的架构设计围绕以下核心原则展开:
-
跨平台兼容性:
- 使用 Kotlin Multiplatform 实现代码共享
- 通过抽象隔离平台差异
- 提供一致的 API 体验
-
模块化设计:
- 清晰的组件职责划分
- 松耦合的模块依赖
- 可扩展的插件架构
-
性能优先:
- 针对移动平台优化
- 减少不必要的开销
- 高效的资源管理
-
开发者友好:
- 简化的 API 设计
- 全面的错误处理
- 详细的文档和示例
通过这些设计原则,Egloo 提供了一个强大而灵活的 OpenGL ES 框架,适用于跨平台图形应用开发。
3. 设计原则
3.1 模块化
- 每个功能模块都是独立的,具有明确的职责
- 模块之间通过接口进行交互
- 便于扩展和维护
3.2 抽象层次
- 使用 expect/actual 处理平台差异
- 通过接口抽象隔离平台特定实现
- 提供统一的 API 接口
3.3 性能优化
- 最小化 GL 状态切换
- 优化缓冲区管理
- 支持批量渲染
3.4 易用性
- 提供简单直观的 API
- 封装复杂的 GL 操作
- 提供常用的图形组件
4. 扩展性
框架支持多种扩展方式:
- 自定义着色器程序
- 自定义图形对象
- 自定义渲染管线
- 场景图扩展
5. 工具支持
提供了多个实用工具:
- 矩阵操作 (
Matrix) - 缓冲区工具 (
Buffers) - 类型转换
- 调试支持