系统概述
OpenHarmony的图形渲染子系统是一个分层设计的图形栈,包含2D图形、3D图形、Surface管理和工具组件四大核心模块。系统采用模块化设计,支持跨进程共享内存、GPU加速渲染和统一的多媒体缓冲区管理。
目录
核心特性
- 跨进程共享内存:通过Surface实现生产者-消费者模型
- GPU加速:支持OpenGL/Vulkan后端
- 统一缓冲区管理:BufferQueue机制管理图形缓冲区生命周期
- ECS架构:3D引擎采用实体-组件-系统架构
- 分层设计:接口层、框架层、引擎层分离
架构设计
整体架构图
┌─────────────────────────────────────────────────────────────┐
│ Application Layer │
├─────────────────────────────────────────────────────────────┤
│ Interface Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ 2D API │ │ 3D API │ │ Surface API │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Framework Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Rosen 2D │ │ AGP 3D │ │ Surface Manager │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ Engine Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Skia │ │ Lume │ │ BufferQueue │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
模块组成
模块名称 | 路径 | 核心功能 |
---|---|---|
graphic_2d | /foundation/graphic/graphic_2d | 2D图形渲染、动画、字体 |
graphic_3d | /foundation/graphic/graphic_3d | 3D图形渲染、ECS架构 |
graphic_surface | /foundation/graphic/graphic_surface | Surface管理、跨进程通信 |
graphic_utils_lite | /foundation/graphic/graphic_utils_lite | 通用数据结构、OS适配 |
surface_lite | /foundation/graphic/surface_lite | 轻量级Surface实现 |
核心模块详解
1. 2D图形模块 (graphic_2d)
1.1 架构分层
接口层
- 路径:
/foundation/graphic/graphic_2d/interfaces/kits
- 提供C/C++ API接口
- 关键文件:
drawing_canvas.h
- 画布操作接口drawing_path.h
- 路径绘制接口drawing_paint.h
- 画笔属性接口
框架层
- 路径:
/foundation/graphic/graphic_2d/rosen
- Rosen渲染引擎核心实现
- 子模块:
animation_server
- 动画服务器bootanimation
- 开机动画render_service
- 渲染服务
引擎层
- 基于Skia图形引擎
- GPU加速支持(OpenGL/Vulkan)
- 关键类:
SkiaSurface
、DrawingCanvas
1.2 核心类分析
DrawingCanvas类
// 文件: /foundation/graphic/graphic_2d/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_surface.h
class SkiaSurface : public SurfaceImpl {
public:
// 创建Surface
static std::shared_ptr<Surface> MakeRenderTarget(GPUContext* gpuContext, bool budgeted, const ImageInfo& imageInfo);
static std::shared_ptr<Surface> MakeRaster(const ImageInfo& imageInfo);
// 渲染操作
std::shared_ptr<Canvas> GetCanvas() const override;
void FlushAndSubmit(bool syncCpu) override;
// 截图功能
std::shared_ptr<Image> GetImageSnapshot() const override;
};
GPUContext管理
// 文件: /foundation/graphic/graphic_2d/rosen/modules/2d_graphics/drawing_ndk/include/drawing_gpu_context.h
OH_Drawing_GpuContext* OH_Drawing_GpuContextCreateFromGL(OH_Drawing_GpuContextOptions);
void OH_Drawing_GpuContextDestroy(OH_Drawing_GpuContext*);
2. 3D图形模块 (graphic_3d)
2.1 ECS架构设计
实体-组件-系统架构
- Entity - 场景中的对象
- Component - 数据容器
- System - 逻辑处理
2.2 核心组件
TransformComponent
// 文件: /foundation/graphic/graphic_3d/lume/Lume_3D/api/3d/ecs/components/transform_component.h
BEGIN_COMPONENT(ITransformComponentManager, TransformComponent)
DEFINE_PROPERTY(BASE_NS::Math::Vec3, position, "Position", 0, ARRAY_VALUE(0.f, 0.f, 0.f))
DEFINE_PROPERTY(BASE_NS::Math::Quat, rotation, "Rotation", 0, ARRAY_VALUE(0.f, 0.f, 0.f, 1.f))
DEFINE_PROPERTY(BASE_NS::Math::Vec3, scale, "Scale", 0, ARRAY_VALUE(1.f, 1.f, 1.f))
END_COMPONENT(ITransformComponentManager, TransformComponent, "07786a48-a52b-4425-8229-8c0d955dc4cd")
AnimationComponent
// 文件: /foundation/graphic/graphic_3d/lume/Lume_3D/api/3d/ecs/components/animation_component.h
enum class PlaybackState : uint8_t { STOP = 0, PLAY = 1, PAUSE = 2 };
BEGIN_COMPONENT(IAnimationComponentManager, AnimationComponent)
DEFINE_PROPERTY(PlaybackState, state, "Playback State", 0, VALUE(PlaybackState::STOP))
DEFINE_PROPERTY(uint32_t, repeatCount, "Playback Repeat Count", 0, VALUE(1))
DEFINE_PROPERTY(float, speed, "Playback Speed", 0, VALUE(1.f))
END_COMPONENT(IAnimationComponentManager, AnimationComponent, "65f8a318-8931-4bc8-8476-02863937b1fa")
2.3 渲染管线
Node系统
// 文件: /foundation/graphic/graphic_3d/lume/scenewidgetplugin/plugin/include/scene_plugin/interface/intf_node.h
class INode : public META_NS::INamed {
public:
// 变换属性
META_PROPERTY(BASE_NS::Math::Vec3, Position)
META_PROPERTY(BASE_NS::Math::Vec3, Scale)
META_PROPERTY(BASE_NS::Math::Quat, Rotation)
// 可见性控制
META_PROPERTY(bool, Visible)
META_PROPERTY(uint64_t, LayerMask)
// 网格渲染
META_PROPERTY(BASE_NS::shared_ptr<IMesh>, Mesh)
};
3. Surface管理模块
3.1 BufferQueue机制
核心概念
- 生产者 - 创建图形内容的进程
- 消费者 - 使用图形内容的进程
- BufferQueue - 管理缓冲区队列
- 共享内存 - 跨进程数据传输
缓冲区生命周期
Free Queue → Producer → Dirty Queue → Consumer → Free Queue
3.2 Surface API
关键接口
// 文件: /foundation/graphic/surface_lite/interfaces/kits/surface.h
class Surface {
public:
static Surface* CreateSurface();
// 缓冲区管理
virtual SurfaceBuffer* RequestBuffer(uint8_t wait = 0) = 0;
virtual int32_t FlushBuffer(SurfaceBuffer* buffer) = 0;
virtual SurfaceBuffer* AcquireBuffer() = 0;
virtual bool ReleaseBuffer(SurfaceBuffer* buffer) = 0;
// 参数配置
virtual void SetQueueSize(uint8_t queueSize) = 0;
virtual void SetWidthAndHeight(int32_t width, int32_t height) = 0;
virtual void SetFormat(uint32_t format) = 0;
// 事件监听
virtual void RegisterConsumerListener(IBufferConsumerListener& listener) = 0;
};
3.3 缓冲区参数配置
测试用例分析
// 文件: /foundation/graphic/surface_lite/test/unittest/graphic_surface_test.cpp
// 默认配置
EXPECT_EQ(1, surface->GetQueueSize()); // 默认队列大小
EXPECT_EQ(0, surface->GetUsage()); // 默认使用场景
EXPECT_EQ(101, surface->GetFormat()); // 默认格式 RGB565
EXPECT_EQ(4, surface->GetStrideAlignment()); // 默认对齐4字节
// 配置设置
surface->SetQueueSize(10); // 设置队列大小 [1,10]
surface->SetWidthAndHeight(101, 202);
surface->SetFormat(102); // ARGB1555格式
surface->SetStrideAlignment(8); // 8字节对齐
渲染原理深度解析
1. 2D渲染管线原理
1.1 完整渲染流程详解
软件架构层次
应用层 (ArkTS/Java/C++)
↓ [JNI/NDK接口]
Drawing NDK API层
↓ [C++封装]
Rosen渲染引擎层
↓ [Skia适配]
图形后端层 (OpenGL/Vulkan)
↓ [驱动层]
GPU硬件层
↓ [显示控制器]
屏幕显示层
实际案例分析:绘制一个圆角矩形按钮
让我们通过一个实际案例来理解完整的渲染流程:
// 实际应用代码示例 (ArkTS侧)
@Entry
@Component
struct MyButton {
build() {
Column() {
Button('点击我')
.width(200)
.height(50)
.borderRadius(25)
.backgroundColor('#007AFF')
}
}
}
底层转换过程:
-
UI组件解析阶段
- ArkTS编译器将组件转换为渲染指令
- 生成对应的Canvas绘制命令序列
-
NDK接口调用链
// 实际生成的C++调用序列
OH_Drawing_Canvas* canvas = OH_Drawing_CanvasCreate();
OH_Drawing_RoundRect* roundRect = OH_Drawing_RoundRectCreate(rect, 25.0f, 25.0f);
OH_Drawing_CanvasDrawRoundRect(canvas, roundRect);
- Skia后端处理
// Skia内部实现 (skia_surface.cpp)
void SkiaSurface::DrawRoundRect(const SkRect& rect, SkScalar rx, SkScalar ry) {
// 1. 顶点生成 - 生成圆角矩形的顶点数据
std::vector<SkPoint> vertices = GenerateRoundRectVertices(rect, rx, ry);
// 2. 索引生成 - 创建三角化的索引
std::vector<uint16_t> indices = TriangulateRoundRect(vertices);
// 3. GPU命令录制
GrRecordingContext* context = surface_->recordingContext();
context->drawVertices(vertices, indices, SkPaint());
}
- GPU命令缓冲区
// GPU命令序列示例
GL_CMD_BEGIN(GL_TRIANGLES);
GL_CMD_VERTEX_ATTRIB(0, 3, GL_FLOAT, vertices);
GL_CMD_DRAW_ELEMENTS(GL_TRIANGLES, indices.size(), GL_UNSIGNED_SHORT, 0);
GL_CMD_END();
1.2 坐标变换矩阵详解
变换矩阵栈机制
// 实际矩阵计算过程
class TransformStack {
std::vector<Mat4> stack_;
public:
void PushTransform() {
// 保存当前变换状态
stack_.push_back(current_transform_);
}
void Translate(float x, float y) {
Mat4 translation = Mat4::Translate(x, y, 0);
current_transform_ = current_transform_ * translation;
}
void Scale(float sx, float sy) {
Mat4 scale = Mat4::Scale(sx, sy, 1);
current_transform_ = current_transform_ * scale;
}
};
实际案例:旋转动画
// 60FPS旋转动画实现
class RotationAnimation {
float rotation_ = 0.0f;
void UpdateFrame() {
// 每帧旋转6度 (360度/60帧)
rotation_ += 6.0f;
if (rotation_ >= 360.0f) rotation_ -= 360.0f;
// 构建旋转矩阵
Mat4 rotation = Mat4::RotateZ(rotation_ * M_PI / 180.0f);
canvas->SetTransform(rotation);
}
};
2. 3D渲染管线原理
2.1 ECS架构深入分析
实体生命周期管理
// 实际ECS系统实现 (lume_3d_engine.cpp)
class ECSWorld {
EntityManager entityManager_;
ComponentManager componentManager_;
SystemManager systemManager_;
public:
Entity Create3DObject(const std::string& modelPath) {
// 1. 创建实体
Entity entity = entityManager_.CreateEntity();
// 2. 添加必要组件
TransformComponent& transform = componentManager_.AddComponent<TransformComponent>(entity);
transform.position = {0, 0, 0};
transform.scale = {1, 1, 1};
// 3. 加载模型组件
MeshComponent& mesh = componentManager_.AddComponent<MeshComponent>(entity);
mesh.meshData = LoadModel(modelPath);
// 4. 注册到渲染系统
systemManager_.GetSystem<RenderSystem>()->RegisterEntity(entity);
return entity;
}
};
实际案例:3D场景渲染
// 完整的3D场景设置示例
class Scene3D {
void SetupScene() {
// 1. 创建相机
Entity camera = world_.CreateEntity();
auto& cameraTransform = world_.AddComponent<TransformComponent>(camera);
cameraTransform.position = {0, 5, 10};
cameraTransform.rotation = LookAt({0, 0, 0});
// 2. 添加光源
Entity light = world_.CreateEntity();
auto& lightComponent = world_.AddComponent<LightComponent>(light);
lightComponent.type = LightType::DIRECTIONAL;
lightComponent.color = {1, 1, 1};
lightComponent.intensity = 1.0f;
// 3. 加载3D模型
Entity model = world_.CreateEntity();
auto& mesh = world_.AddComponent<MeshComponent>(model);
mesh.LoadFromFile("/system/etc/models/character.fbx");
// 4. 设置材质
auto& material = world_.AddComponent<MaterialComponent>(model);
material.diffuseTexture = LoadTexture("character_diffuse.png");
material.normalTexture = LoadTexture("character_normal.png");
}
};
2.2 渲染管线阶段详解
顶点处理阶段
// 顶点着色器处理流程
void VertexShader(const VertexInput& input, VertexOutput& output) {
// 1. 模型变换
vec4 worldPos = modelMatrix * vec4(input.position, 1.0);
// 2. 视图变换
vec4 viewPos = viewMatrix * worldPos;
// 3. 投影变换
vec4 clipPos = projectionMatrix * viewPos;
output.position = clipPos;
output.uv = input.uv;
output.normal = mat3(normalMatrix) * input.normal;
}
片元处理阶段
// 片元着色器光照计算
vec4 FragmentShader(const FragmentInput& input) {
// 1. 基础颜色
vec4 baseColor = texture(diffuseTexture, input.uv);
// 2. 法线贴图
vec3 normal = normalize(texture(normalTexture, input.uv).rgb * 2.0 - 1.0);
// 3. 光照计算
vec3 lightDir = normalize(lightPosition - input.worldPos);
float NdotL = max(dot(normal, lightDir), 0.0);
// 4. 最终颜色
return baseColor * (ambient + NdotL * lightColor);
}
3. Surface缓冲区管理原理
3.1 共享内存机制详解
内存映射过程
// BufferQueue内存管理实现
class BufferQueue {
struct BufferSlot {
sp<GraphicBuffer> buffer;
BufferState state = BufferState::FREE;
sp<Fence> fence;
uint64_t frameNumber = 0;
};
BufferSlot slots_[MAX_BUFFER_SLOTS];
public:
status_t requestBuffer(int slot, sp<GraphicBuffer>* buf) {
// 1. 验证slot有效性
if (slot < 0 || slot >= MAX_BUFFER_SLOTS) {
return BAD_VALUE;
}
// 2. 检查缓冲区状态
if (slots_[slot].state != BufferState::FREE) {
return BAD_VALUE;
}
// 3. 创建或重用缓冲区
if (slots_[slot].buffer == nullptr) {
slots_[slot].buffer = new GraphicBuffer(
width_, height_, format_, usage_);
}
*buf = slots_[slot].buffer;
slots_[slot].state = BufferState::DEQUEUED;
return OK;
}
};
实际案例:视频播放器实现
// 基于Surface的视频播放器
class VideoPlayer {
sp<Surface> surface_;
sp<MediaCodec> codec_;
public:
void SetupVideoOutput() {
// 1. 创建Surface用于视频输出
surface_ = Surface::createFromIGraphicBufferProducer(
new BufferQueue());
// 2. 配置缓冲区参数
surface_->setBufferCount(8); // 8帧缓冲,减少卡顿
surface_->setDefaultBufferSize(1920, 1080);
surface_->setDefaultBufferFormat(HAL_PIXEL_FORMAT_YV12);
// 3. 设置生产者监听器
surface_->registerProducerListener(this);
// 4. 配置MediaCodec输出
codec_->configure(format, surface_, nullptr, 0);
}
void onFrameAvailable() override {
// 帧可用回调处理
ANativeWindowBuffer* buffer;
surface_->dequeueBuffer(&buffer, &fence);
// 渲染到屏幕
surface_->queueBuffer(buffer, fence);
}
};
3.2 同步机制详解
Fence同步机制
// GPU-CPU同步实现
class SyncFence {
int fd_; // 文件描述符用于跨进程同步
public:
void waitForever() {
// 等待GPU完成渲染
sync_wait(fd_, -1);
}
bool waitTimeout(int timeoutMs) {
return sync_wait(fd_, timeoutMs) == 0;
}
};
// 实际使用场景
void VideoCompositor::compositeFrame() {
// 1. 获取解码器输出缓冲区
sp<GraphicBuffer> srcBuffer = decoder_->getOutputBuffer();
// 2. 获取合成目标缓冲区
sp<GraphicBuffer> dstBuffer;
surface_->requestBuffer(&dstBuffer);
// 3. 等待解码完成
srcBuffer->getFence()->waitForever();
// 4. 执行GPU合成操作
gpuComposer_->composite(srcBuffer, dstBuffer);
// 5. 设置完成fence
dstBuffer->setFence(gpuComposer_->getCompletionFence());
}
1.2 坐标变换
矩阵变换流程
- 局部坐标 → 世界坐标(模型变换)
- 世界坐标 → 视图坐标(视图变换)
- 视图坐标 → 投影坐标(投影变换)
- 投影坐标 → 设备坐标(视口变换)
2. 3D渲染管线
2.1 ECS渲染流程
2.2 着色器管理
ShaderManager核心功能
// 文件: /foundation/graphic/graphic_3d/lume/LumeRender/src/device/shader_manager.cpp
class ShaderManager {
void CreateGpuResources(Allocs& allocs);
void HandlePendingModules(Allocs& allocs);
// 着色器生命周期管理
vector<ShaderRef> shaders_;
vector<ComputeShaderRef> computeShaders_;
vector<ShaderModule> shaderModules_;
};
3. 缓冲区同步机制
3.1 生产者-消费者模型
3.2 同步原语
- Mutex - 缓冲区访问互斥
- Condition Variable - 缓冲区可用通知
- File Descriptor - 跨进程共享内存句柄
关键函数调用流程
1. 2D渲染调用链
1.1 Canvas绘制流程
1.2 Surface渲染流程
2. 3D渲染调用链
2.1 场景渲染流程
2.2 ECS系统调用
3. BufferQueue操作流程
3.1 缓冲区申请流程
3.2 缓冲区释放流程
常见需求与Bug分析
1. 常见开发需求
1.1 2D图形需求
需求场景 | 实现方案 | 关键API |
---|---|---|
自定义绘制 | Canvas + Path | OH_Drawing_CanvasDrawPath |
文本渲染 | Font + Typeface | OH_Drawing_FontCreate |
图像处理 | ShaderEffect | OH_Drawing_CreateImageShader |
离屏渲染 | Surface + Bitmap | Surface::MakeRaster |
1.2 3D图形需求
需求场景 | 实现方案 | 关键组件 |
---|---|---|
模型加载 | MeshComponent | INode::SetMesh |
动画控制 | AnimationComponent | IAnimationComponentManager |
相机控制 | Camera系统 | IRenderDataStoreDefaultCamera |
光照效果 | LightComponent | IRenderDataStoreDefaultScene |
1.3 Surface管理需求
需求场景 | 实现方案 | 关键API |
---|---|---|
跨进程渲染 | Surface + BufferQueue | Surface::CreateSurface |
缓冲区配置 | 参数设置 | SetQueueSize/SetFormat |
性能优化 | 缓冲区池化 | RequestBuffer/ReleaseBuffer |
同步机制 | Listener回调 | RegisterConsumerListener |
2. 实际案例分析
2.1 2D渲染实际案例
案例1:复杂UI界面性能优化
问题背景:某电商APP商品列表页面滚动卡顿,FPS从60降到30
问题分析:
// 原始问题代码 - 每帧重复创建对象
void DrawProductCard(Canvas* canvas) {
for (auto& product : products) {
// 每帧重新创建Path对象 - 性能杀手
auto path = Path::CreateRoundRect(product.rect, 8.0f);
auto paint = Paint::Create();
paint->setColor(product.color);
canvas->drawPath(path, paint);
// 每帧重新加载图片 - 内存泄漏
auto image = Image::LoadFromFile(product.imagePath);
canvas->drawImage(image, product.imageRect);
}
}
优化方案:
// 优化后的实现 - 对象池化 + 缓存机制
class ProductRenderer {
struct CachedProduct {
sp<Path> path;
sp<Paint> paint;
sp<Image> image;
bool needsUpdate = false;
};
std::unordered_map<int, CachedProduct> cache_;
public:
void DrawProductCard(Canvas* canvas, const Product& product) {
auto& cached = cache_[product.id];
// 1. 路径缓存
if (!cached.path || cached.needsUpdate) {
cached.path = Path::CreateRoundRect(product.rect, 8.0f);
cached.paint = Paint::Create();
cached.paint->setColor(product.color);
}
// 2. 图片缓存
if (!cached.image) {
cached.image = ImageCache::GetInstance()->Get(product.imagePath);
}
// 3. 批量渲染
canvas->drawPath(cached.path, cached.paint);
canvas->drawImage(cached.image, product.imageRect);
}
void PreloadImages(const std::vector<Product>& products) {
// 预加载下3屏的图片
ImageCache::GetInstance()->Preload(products);
}
};
性能提升:
- 内存使用:从每帧200MB降到稳定50MB
- FPS提升:从30fps恢复到稳定60fps
- 加载时间:图片加载时间从200ms降到20ms
案例2:实时图表绘制优化
需求场景:股票APP实时K线图,需要每秒更新60次
技术挑战:
- 高频数据更新(每秒60次)
- 大量数据点(1000根K线)
- 复杂视觉效果(阴影、渐变、动画)
解决方案:
class StockChartRenderer {
struct VertexBuffer {
std::vector<float> positions;
std::vector<float> colors;
GLuint vbo = 0;
GLuint vao = 0;
};
VertexBuffer candlestickBuffer_;
VertexBuffer volumeBuffer_;
public:
void InitializeBuffers(int maxDataPoints) {
// 1. 预分配GPU缓冲区
candlestickBuffer_.positions.resize(maxDataPoints * 4 * 3); // 4顶点/蜡烛 * 3坐标
candlestickBuffer_.colors.resize(maxDataPoints * 4 * 4); // 4顶点/蜡烛 * 4颜色
glGenBuffers(1, &candlestickBuffer_.vbo);
glGenVertexArrays(1, &candlestickBuffer_.vao);
// 2. 设置顶点属性
glBindVertexArray(candlestickBuffer_.vao);
glBindBuffer(GL_ARRAY_BUFFER, candlestickBuffer_.vbo);
glBufferData(GL_ARRAY_BUFFER,
candlestickBuffer_.positions.size() * sizeof(float),
nullptr, GL_DYNAMIC_DRAW);
}
void UpdateChart(const std::vector<StockData>& data) {
// 1. 增量更新 - 只更新变化的部分
int startIndex = std::max(0, (int)data.size() - 100);
// 2. CPU到GPU数据传输优化
glBufferSubData(GL_ARRAY_BUFFER,
startIndex * 4 * 3 * sizeof(float),
(data.size() - startIndex) * 4 * 3 * sizeof(float),
candlestickBuffer_.positions.data() + startIndex * 4 * 3);
// 3. 批量渲染调用
glDrawArrays(GL_TRIANGLES, startIndex * 6, (data.size() - startIndex) * 6);
}
};
2.2 3D渲染实际案例
案例1:游戏引擎集成
需求场景:将OpenHarmony 3D引擎集成到Unity风格的游戏框架中
架构设计:
// 游戏对象系统封装
class GameObject {
Entity entity_;
std::vector<std::unique_ptr<Component>> components_;
public:
template<typename T, typename... Args>
T* AddComponent(Args&&... args) {
auto component = std::make_unique<T>(std::forward<Args>(args)...);
T* ptr = component.get();
components_.push_back(std::move(component));
// 注册到ECS系统
if constexpr (std::is_base_of_v<MeshRenderer, T>) {
world_.AddComponent<MeshComponent>(entity_, ptr->GetMeshData());
}
return ptr;
}
void Update(float deltaTime) {
for (auto& component : components_) {
component->Update(deltaTime);
}
}
};
// 实际使用示例
class PlayerController : public MonoBehaviour {
Transform* transform_;
Rigidbody* rigidbody_;
public:
void Start() override {
transform_ = GetComponent<Transform>();
rigidbody_ = GetComponent<Rigidbody>();
// 加载角色模型
auto meshRenderer = gameObject->AddComponent<MeshRenderer>();
meshRenderer->LoadModel("/models/player.fbx");
// 设置动画
auto animator = gameObject->AddComponent<Animator>();
animator->LoadAnimation("/animations/run.anim");
}
void Update(float deltaTime) override {
// 处理输入
if (Input::GetKey(KeyCode::W)) {
rigidbody_->AddForce(transform_->forward * moveSpeed);
}
// 更新动画
auto animator = GetComponent<Animator>();
animator->SetFloat("speed", rigidbody_->velocity.magnitude());
}
};
性能优化策略:
- 对象池:GameObject池化,避免频繁创建销毁
- 批处理:静态合批减少DrawCall
- LOD系统:根据距离动态调整模型精度
案例2:AR增强现实
需求场景:AR导航应用,需要实时叠加3D箭头到摄像头画面
技术实现:
class ARNavigationSystem {
struct ARAnchor {
Vec3 worldPosition;
Quaternion worldRotation;
Vec2 screenPosition;
float distance;
bool isVisible;
};
std::vector<ARAnchor> anchors_;
Camera* arCamera_;
public:
void UpdateARFrame(const CameraFrame& frame) {
// 1. 获取设备位姿
Pose devicePose = frame.GetDevicePose();
// 2. 计算锚点位置
for (auto& anchor : anchors_) {
// 世界坐标到相机坐标
Vec3 cameraSpace = devicePose.InverseTransformPoint(anchor.worldPosition);
// 相机坐标到屏幕坐标
anchor.screenPosition = arCamera_->WorldToScreen(cameraSpace);
anchor.distance = cameraSpace.magnitude();
anchor.isVisible = IsInFrustum(cameraSpace);
}
// 3. 渲染3D箭头
Render3DArrows();
}
private:
void Render3DArrows() {
// 使用Billboard技术确保箭头始终面向相机
for (const auto& anchor : anchors_) {
if (!anchor.isVisible) continue;
// 计算Billboard旋转
Vec3 toCamera = (arCamera_->position - anchor.worldPosition).normalized();
Quaternion billboardRot = Quaternion::LookRotation(toCamera, Vec3::up);
// 设置变换
arrowEntity_->GetComponent<Transform>()->
SetPosition(anchor.worldPosition);
arrowEntity_->GetComponent<Transform>()->
SetRotation(billboardRot);
}
}
};
2.3 Surface管理实际案例
案例1:多窗口视频通话
需求场景:视频会议APP,需要同时显示9个参与者的视频流
架构挑战:
- 多路视频流并发处理
- 动态布局调整
- 网络延迟补偿
解决方案:
class VideoConferenceManager {
struct VideoStream {
sp<Surface> surface;
sp<MediaCodec> decoder;
Rect layoutRect;
int participantId;
bool isActive;
};
std::vector<VideoStream> streams_;
sp<SurfaceComposerClient> composer_;
public:
void InitializeConference(int participantCount) {
streams_.resize(participantCount);
for (int i = 0; i < participantCount; ++i) {
// 1. 为每个参与者创建独立的Surface
streams_[i].surface = Surface::createFromIGraphicBufferProducer(
new BufferQueue());
// 2. 配置解码器输出
streams_[i].decoder = MediaCodec::CreateDecoder();
streams_[i].decoder->configure(format, streams_[i].surface, nullptr, 0);
// 3. 设置缓冲区策略
streams_[i].surface->setBufferCount(3); // 减少延迟
streams_[i].surface->setDefaultBufferSize(640, 480);
}
// 4. 创建合成层
SetupLayoutGrid(3, 3); // 3x3网格布局
}
void UpdateLayout(const std::vector<Rect>& newLayouts) {
// 动态调整布局
for (size_t i = 0; i < streams_.size() && i < newLayouts.size(); ++i) {
streams_[i].layoutRect = newLayouts[i];
// 重新配置Surface参数
streams_[i].surface->setDefaultBufferSize(
newLayouts[i].width, newLayouts[i].height);
}
}
private:
void SetupLayoutGrid(int rows, int cols) {
int screenWidth = 1920;
int screenHeight = 1080;
int cellWidth = screenWidth / cols;
int cellHeight = screenHeight / rows;
for (int i = 0; i < streams_.size(); ++i) {
int row = i / cols;
int col = i % cols;
streams_[i].layoutRect = {
col * cellWidth,
row * cellHeight,
cellWidth,
cellHeight
};
}
}
};
案例2:游戏直播推流
需求场景:游戏直播APP,需要将游戏画面+摄像头+弹幕合成后推流
技术实现:
class LiveStreamComposer {
struct CompositionLayer {
sp<Surface> inputSurface;
Rect sourceRect;
Rect targetRect;
float alpha;
BlendMode blendMode;
};
sp<Surface> gameSurface_;
sp<Surface> cameraSurface_;
sp<Surface> danmakuSurface_;
sp<Surface> outputSurface_;
sp<MediaCodec> encoder_;
public:
void SetupComposition() {
// 1. 创建合成管线
outputSurface_ = Surface::createFromIGraphicBufferProducer(
new BufferQueue());
// 2. 配置编码器
encoder_ = MediaCodec::CreateEncoder();
encoder_->configure(outputFormat, outputSurface_, nullptr, 1);
// 3. 设置各层参数
SetupLayer(gameSurface_, {0, 0, 1920, 1080}, {0, 0, 1920, 1080}, 1.0f);
SetupLayer(cameraSurface_, {0, 0, 640, 480}, {1320, 600, 600, 337}, 0.9f);
SetupLayer(danmakuSurface_, {0, 0, 1920, 200}, {0, 880, 1920, 200}, 0.8f);
}
void CompositeFrame() {
// 1. 获取输出缓冲区
ANativeWindowBuffer* outputBuffer;
outputSurface_->dequeueBuffer(&outputBuffer, &fence);
// 2. GPU合成操作
gpuComposer_->CompositeLayers({
{gameSurface_, {0, 0, 1920, 1080}, {0, 0, 1920, 1080}, 1.0f},
{cameraSurface_, {0, 0, 640, 480}, {1320, 600, 600, 337}, 0.9f},
{danmakuSurface_, {0, 0, 1920, 200}, {0, 880, 1920, 200}, 0.8f}
}, outputBuffer);
// 3. 推送到编码器
outputSurface_->queueBuffer(outputBuffer, fence);
}
};
3. 性能监控与调优
3.1 性能分析工具
GPU性能监控
class GPUProfiler {
struct FrameMetrics {
uint64_t frameNumber;
uint64_t gpuStartTime;
uint64_t gpuEndTime;
uint32_t trianglesRendered;
uint32_t drawCalls;
};
std::queue<FrameMetrics> frameHistory_;
public:
void BeginFrame() {
FrameMetrics metrics;
metrics.frameNumber = GetCurrentFrame();
metrics.gpuStartTime = GetGPUTimeStamp();
// 重置计数器
metrics.trianglesRendered = 0;
metrics.drawCalls = 0;
frameHistory_.push(metrics);
}
void EndFrame() {
auto& metrics = frameHistory_.back();
metrics.gpuEndTime = GetGPUTimeStamp();
// 计算性能指标
uint64_t gpuTime = metrics.gpuEndTime - metrics.gpuStartTime;
float fps = 1000000000.0f / gpuTime;
LogPerformance("GPU Frame Time: %llu ns, FPS: %.2f", gpuTime, fps);
}
};
内存使用监控
class MemoryTracker {
struct MemoryStats {
size_t gpuMemoryUsed;
size_t textureMemory;
size_t bufferMemory;
size_t surfaceMemory;
};
public:
void TrackSurfaceMemory(const sp<Surface>& surface) {
ANativeWindow* window = surface.get();
int width, height, format;
ANativeWindow_getWidth(window, &width);
ANativeWindow_getHeight(window, &height);
ANativeWindow_getFormat(window, &format);
size_t bytesPerPixel = GetBytesPerPixel(format);
size_t bufferSize = width * height * bytesPerPixel;
int bufferCount;
ANativeWindow_getBufferCount(window, &bufferCount);
LogMemory("Surface: %dx%d, %zu bytes x %d buffers = %zu MB",
width, height, bufferSize, bufferCount,
(bufferSize * bufferCount) / (1024 * 1024));
}
};
问题2:GPU资源泄漏
- 症状:内存持续增长,应用卡顿
- 原因:未释放GPU上下文
- 解决方案:
// 正确释放
OH_Drawing_GpuContextDestroy(context);
2.2 3D渲染问题
问题1:模型不显示
- 症状:加载模型后黑屏
- 原因:未设置相机或光照
- 解决方案:
// 设置相机
auto camera = scene->GetDefaultCamera();
camera->SetPosition({0, 0, 5});
camera->LookAt({0, 0, 0});
问题2:动画不播放
- 症状:AnimationComponent状态为STOP
- 原因:未启动动画系统
- 解决方案:
// 启动动画
animationComp->state = AnimationComponent::PlaybackState::PLAY;
2.3 Surface管理问题
问题1:缓冲区申请失败
- 症状:RequestBuffer返回nullptr
- 原因:队列大小不足或格式不支持
- 解决方案:
// 调整队列大小
surface->SetQueueSize(3); // 增加到3个缓冲区
问题2:跨进程通信失败
- 症状:消费者收不到缓冲区
- 原因:Listener未注册或线程问题
- 解决方案:
// 注册监听器
class MyListener : public IBufferConsumerListener {
void OnBufferAvailable() override {
// 处理缓冲区可用事件
}
};
surface->RegisterConsumerListener(listener);
3. 性能优化建议
3.1 2D优化
- 批处理:合并多个绘制调用
- 离屏渲染:预渲染复杂图形
- 纹理缓存:重用GPU纹理资源
3.2 3D优化
- LOD系统:根据距离调整模型精度
- 剔除算法:视锥体剔除不可见对象
- 实例化渲染:批量渲染相同模型
3.3 Surface优化
- 缓冲区池化:减少内存分配
- 异步渲染:多线程渲染管线
- 格式选择:使用硬件支持的格式
源码位置索引
1. 2D图形源码
1.1 核心类文件
功能模块 | 文件路径 | 关键类 |
---|---|---|
Surface实现 | graphic_2d/rosen/modules/2d_graphics/src/drawing/engine_adapter/skia_adapter/skia_surface.h | SkiaSurface |
GPU上下文 | graphic_2d/rosen/modules/2d_graphics/drawing_ndk/include/drawing_gpu_context.h | OH_Drawing_GpuContext |
渲染服务 | graphic_2d/rosen/modules/render_service/src/rs_render_service_security_utils.cpp | RSRenderServiceSecurityUtils |
1.2 API接口文件
API类型 | 文件路径 | 功能描述 |
---|---|---|
Canvas API | graphic_2d/rosen/modules/2d_graphics/drawing_ndk/include/drawing_canvas.h | 画布操作接口 |
Path API | graphic_2d/rosen/modules/2d_graphics/drawing_ndk/include/drawing_path.h | 路径绘制接口 |
Font API | graphic_2d/rosen/modules/2d_graphics/drawing_ndk/src/drawing_font.cpp | 字体渲染实现 |
2. 3D图形源码
2.1 ECS组件文件
组件类型 | 文件路径 | 功能描述 |
---|---|---|
Transform组件 | graphic_3d/lume/Lume_3D/api/3d/ecs/components/transform_component.h | 变换矩阵组件 |
Animation组件 | graphic_3d/lume/Lume_3D/api/3d/ecs/components/animation_component.h | 动画控制组件 |
Node接口 | graphic_3d/lume/scenewidgetplugin/plugin/include/scene_plugin/interface/intf_node.h | 场景节点接口 |
2.2 渲染系统文件
系统模块 | 文件路径 | 功能描述 |
---|---|---|
Shader管理 | graphic_3d/lume/LumeRender/src/device/shader_manager.cpp | 着色器生命周期管理 |
渲染节点 | graphic_3d/lume/Lume_3D/src/render/node/render_node_default_env.h | 默认环境渲染节点 |
Widget适配 | graphic_3d/3d_widget_adapter/include/widget_adapter.h | 3D Widget适配器 |
3. Surface管理源码
3.1 核心接口文件
接口类型 | 文件路径 | 功能描述 |
---|---|---|
Surface API | surface_lite/interfaces/kits/surface.h | Surface管理接口 |
Buffer管理 | surface_lite/interfaces/kits/surface_buffer.h | 缓冲区管理接口 |
消费者监听 | surface_lite/interfaces/kits/ibuffer_consumer_listener.h | 消费者事件监听 |
3.2 测试用例文件
测试类型 | 文件路径 | 测试内容 |
---|---|---|
单元测试 | surface_lite/test/unittest/graphic_surface_test.cpp | Surface功能测试 |
Fuzz测试 | graphic_surface/surface/test/fuzztest/bufferqueue_fuzzer/ | 缓冲区队列模糊测试 |
Surface测试 | graphic_surface/surface/test/fuzztest/surfacebuffer_fuzzer/ | Surface缓冲区测试 |
4. 工具组件源码
4.1 通用数据结构
数据结构 | 文件路径 | 功能描述 |
---|---|---|
数学库 | graphic_utils_lite/frameworks/utils/include/ | 数学运算工具 |
OS适配 | graphic_utils_lite/frameworks/hals/ | 硬件抽象层 |
线程管理 | graphic_utils_lite/frameworks/utils/include/thread.h | 线程封装 |
4.2 编译构建
构建文件 | 文件路径 | 功能描述 |
---|---|---|
Bundle配置 | graphic_2d/bundle.json | 2D模块构建配置 |
Bundle配置 | graphic_3d/bundle.json | 3D模块构建配置 |
CMake配置 | CMakeLists.txt | 跨平台构建配置 |
构建与调试指南
1. 构建命令
1.1 模块构建
# 构建2D图形模块
hb build -T graphic_2d
# 构建3D图形模块
hb build -T graphic_3d
# 构建Surface模块
hb build -T graphic_surface
# 构建工具模块
hb build -T graphic_utils_lite
2. 调试技巧
2.1 日志调试
// 启用渲染调试日志
#define RENDER_DEBUG_LOG 1
// GPU调试信息
void EnableGpuDebug() {
OH_Drawing_GpuContextOptions options;
options.allowPathMaskCaching = true;
auto context = OH_Drawing_GpuContextCreateFromGL(options);
}
2.2 性能分析
// 渲染耗时统计
class RenderTimer {
public:
void StartFrame() { start_ = std::chrono::high_resolution_clock::now(); }
void EndFrame() {
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end - start_);
printf("Frame time: %ld us\n", duration.count());
}
private:
std::chrono::high_resolution_clock::time_point start_;
};
总结
OpenHarmony的图形渲染系统提供了完整的2D/3D图形解决方案,通过模块化设计实现了高性能、跨进程的图形渲染能力。系统采用分层架构,从应用API到GPU驱动都有清晰的抽象层次,为开发者提供了丰富的图形功能和灵活的扩展能力。