news 2026/6/21 12:53:36

鸿蒙开发--GraphicsAccelerateKit-AdaptiveBufferResolution-GLES

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙开发--GraphicsAccelerateKit-AdaptiveBufferResolution-GLES

HarmonyOS 图形加速:用 ABR 实现自适应稳态渲染

什么是 ABR

玩游戏的时候,你有没有遇到过这种情况:场景简单的时候帧率很高很流畅,但一到复杂场景(比如大量敌人、特效爆炸)就开始卡顿?这是因为 GPU 的负载在不同场景下是不一样的。

ABR(Adaptive Buffer Resolution,自适应缓冲分辨率)就是为了解决这个问题。它的核心思想是:在 GPU 负载高的时候,自动降低渲染分辨率来保持帧率;在 GPU 负载低的时候,恢复高分辨率保证画质

打个比方,就像开车上坡一样。上坡的时候(GPU 负载高),你会降档减速(降低分辨率)来保持动力;下坡的时候(GPU 负载低),你又可以升档加速(提高分辨率)跑得更快。

环境搭建

硬件要求

  • 设备类型:华为手机、平板设备
  • HarmonyOS 系统:HarmonyOS 5.0.5 Release 及以上

软件要求

  • DevEco Studio 版本:DevEco Studio 6.0.0 Release 及以上
  • HarmonyOS SDK 版本:HarmonyOS 6.0.0 Release SDK 及以上

搭建步骤

  1. 安装 DevEco Studio:去华为开发者官网下载安装
  2. 配置开发环境:确保网络环境正常
  3. 设备调试:使用真机进行调试

项目结构

这个项目比较特殊,因为它涉及到 C++ 和 ArkTS 的混合开发:

└── entry/src/main // 代码区 ├── cpp │ ├── types/libentry │ │ └── index.d.ts // native层接口注册文件 │ ├── napi_init.cpp // native api层接口的具体实现函数 │ ├── CMakeLists.txt // native层编译配置 │ ├── include // 头文件 │ ├── source // C++代码区 │ │ ├── core.cpp // 核心入口,管理生命周期 │ │ ├── renderer.cpp // 渲染管理类的实现 │ │ ├── scene_base.cpp // ABR基类的实现 │ │ ├── scene_abr.cpp // ABR类的实现 │ │ ├── opaque_layer_base.cpp // 场景绘制基类的实现 │ │ ├── opaque_layer.cpp // 场景绘制派生类的实现 │ │ ├── gui.cpp // UI绘制 │ │ └── ... ├── ets │ ├── ability │ │ └── EntryAbility.ts // 程序入口类 │ ├── pages │ │ └── Index.ets // 主界面 └── resources │ ├── base/media // 图片资源 │ │ └── logo.png │ ├── rawfile // 模型和UI资源 │ │ └── ...

为什么用 C++?因为图形渲染对性能要求很高,C++ 能提供更接近硬件的控制能力。ArkTS 负责 UI 界面,C++ 负责底层的图形渲染逻辑。

应用架构

整个应用分为三部分:

  • C++ 侧:实现场景渲染,管理 ABR 生命周期
  • ArkTS 侧:实现前端界面,调用 C++ 侧的图形渲染方法
  • CMake 编译工具链:将 C++ 侧代码编译成 so 文件提供给 ArkTS 侧使用

第一步:创建项目

使用 Native C++ 模板创建项目。在 DevEco Studio 中选择 “File > New > Create Project”,然后选择 Native C++ 模板。

第二步:添加配置项

module.json5的 module 层级中添加以下配置:

"metadata":[{"name":"GraphicsAccelerateKit_ABR","value":"true"}]

这个配置告诉系统,我们的应用要使用 Graphics Accelerate Kit 的 ABR 功能。

第三步:引入头文件

在 C++ 代码中引入 ABR 的头文件:

#include<graphics_game_sdk/abr_gles.h>

这个头文件包含了所有 ABR 相关的 API。

第四步:配置 CMakeLists.txt

在 CMakeLists.txt 中需要增加对libabr.so的依赖:

find_library(EGL-lib EGL REQUIRED) find_library(GLES-lib GLESv3 REQUIRED) find_library(ace-lib ace_ndk.z REQUIRED) find_library(hilog-lib hilog_ndk.z REQUIRED) find_library(napi-lib ace_napi.z REQUIRED) find_library(rawfile-lib rawfile.z REQUIRED) find_library(uv-lib uv REQUIRED) find_library(abr-lib libabr.so REQUIRED) set(ADAPTIVEBUFFERRESOLUTION_LINK_LIBRARIES ${EGL-lib} ${GLES-lib} ${ace-lib} ${hilog-lib} ${rawfile-lib} ${napi-lib} ${uv-lib} ${abr-lib} pixelmap_ndk.z image_source_ndk.z libc++.a ) target_link_libraries(entry PRIVATE ${ADAPTIVEBUFFERRESOLUTION_LINK_LIBRARIES} )

这里做了什么:

  • find_library:查找需要的库
  • abr-lib libabr.so:这是 ABR 的核心库
  • target_link_libraries:把所有库链接到我们的项目中

第五步:ABR 生命周期管理

ABR 的生命周期分为三个阶段:

  1. ABR 初始化:创建 ABR 上下文实例,配置目标帧率和分辨率因子范围,激活 ABR 功能
  2. 自适应渲染:绑定帧缓冲索引,动态调整 buffer 的渲染分辨率
  3. 销毁 ABR 实例:销毁 ABR 上下文实例,释放内存资源

ABR 初始化

在 Surface 创建后,会触发Core::OnSurfaceCreated()回调函数。在这个函数中完成 ABR 的初始化:

// 创建ABR上下文帧实例,指定图形API类型ABR_Context*context_=HMS_ABR_CreateContext(RENDER_API_GLES);if(context_==nullptr){GOLOGE("HMS_ABR_CreateContext execution failed.");returnfalse;}// 初始化ABR实例,配置ABR的目标帧率属性。例如游戏目标帧率为120fps,则配置ABR的目标帧率属性为120fpsABR_ErrorCode errorCode=HMS_ABR_SetTargetFps(context_,120);if(errorCode!=ABR_SUCCESS){GOLOGE("HMS_ABR_SetTargetFps execution failed, error code: %d.",errorCode);returnfalse;}// 初始化ABR实例,配置Buffer分辨率因子范围属性,结合具体游戏分辨率、画质设置合适的范围// 例如设置ABR对Buffer分辨率进行0.5~1.0倍的自适应调整errorCode=HMS_ABR_SetScaleRange(context_,0.5f,1.0f);if(errorCode!=ABR_SUCCESS){GOLOGE("HMS_ABR_SetScaleRange execution failed, error code: %d.",errorCode);returnfalse;}// 激活ABR上下文实例errorCode=HMS_ABR_Activate(context_);if(errorCode!=ABR_SUCCESS){GOLOGE("HMS_ABR_Activate execution failed, error code: %d.",errorCode);returnfalse;}

让我解释一下每个 API:

HMS_ABR_CreateContext(RENDER_API_GLES)

  • 创建一个 ABR 上下文实例
  • 参数RENDER_API_GLES表示使用 OpenGL ES 图形 API
  • 返回一个上下文指针,后续所有操作都需要用到

HMS_ABR_SetTargetFps(context_, 120)

  • 设置目标帧率为 120fps
  • ABR 会根据这个目标帧率来调整分辨率
  • 如果当前帧率低于目标,就降低分辨率;如果高于目标,就提高分辨率

HMS_ABR_SetScaleRange(context_, 0.5f, 1.0f)

  • 设置分辨率缩放范围为 0.5 到 1.0
  • 0.5 表示最低可以降到原始分辨率的 50%
  • 1.0 表示最高可以恢复到原始分辨率的 100%
  • 这个范围要根据你的应用来设置,太低会影响画质

HMS_ABR_Activate(context_)

  • 激活 ABR 实例
  • 激活后,ABR 才会在每帧渲染时动态调整分辨率

自适应渲染

在每帧的渲染循环中,ABR 会自动调整分辨率:

// 更新相机信息floatconstsceneDelta=sceneTimer_.DiffTime();sceneTimer_.RestartTimer();camera_.Update(sceneDelta);// 更新视图矩阵和投影矩阵,用于场景渲染lastViewProj_=camera_.GetViewProjectionMatrix();lastView_=camera_.GetViewMatrix();lastProj_=camera_.GetProjectionMatrix();// 相机运动数据结构体,设置每帧实时相机运动数据ABR_CameraData cameraData;// 相机每帧实时位移数据cameraData.position=static_cast<ABR_Vector3>(camera_.GetPosition());// 相机每帧实时旋转数据cameraData.rotation=static_cast<ABR_Vector3>(camera_.GetRotation());// 每帧相机运动数据更新ABR_ErrorCode errorCode=HMS_ABR_UpdateCameraData(context_,&cameraData);if(errorCode!=ABR_SUCCESS){GOLOGE("HMS_ABR_UpdateCameraData execution failed, error code: %d.",errorCode);}// 渲染前的准备,绑定目标帧缓冲索引,清空颜色缓冲renderer_->BeginRenderTarget(fbo,BACKGROUND.x_,BACKGROUND.y_,BACKGROUND.z_,1.0F);// 在Buffer渲染前调用,执行失败不影响Buffer正常渲染errorCode=HMS_ABR_MarkFrameBuffer_GLES(context_);if(errorCode!=ABR_SUCCESS){GOLOGE("HMS_ABR_MarkFrameBuffer_GLES execution failed, error code: %d.",errorCode);}// 调用绘制方法进行渲染opaqueLayer_.Render(sceneDelta,camera_.GetViewMatrix(),lastViewProj_);// 获取每帧的缩放信息floatscale;errorCode=HMS_ABR_GetScale(context_,&scale);GOLOGD("Scale is %f.",scale);if(errorCode!=ABR_SUCCESS){GOLOGE("HMS_ABR_GetScale execution failed, error code: %d.",errorCode);}// 将帧缓冲索引绑定为默认值0renderer_->EndRenderTarget();

关键 API 解释:

HMS_ABR_UpdateCameraData(context_, &cameraData)

  • 更新相机的位置和旋转信息
  • ABR 需要知道相机的运动状态来预测 GPU 负载
  • 比如相机快速移动时,可能会看到更多复杂场景

HMS_ABR_MarkFrameBuffer_GLES(context_)

  • 在渲染前调用,告诉 ABR 要调整哪个帧缓冲的分辨率
  • 这个函数执行失败不影响正常渲染,只是 ABR 功能不生效

HMS_ABR_GetScale(context_, &scale)

  • 获取当前帧的缩放系数
  • 可以用来显示调试信息或者做其他处理

销毁 ABR 实例

在 Surface 销毁时,销毁 ABR 实例:

// 销毁ABR上下文实例并释放内存资源ABR_ErrorCode errorCode=HMS_ABR_DestroyContext(&context_);if(errorCode!=ABR_SUCCESS){GOLOGE("HMS_ABR_DestroyContext execution failed, error code: %d.",errorCode);returnfalse;}

记得在不需要 ABR 的时候销毁它,释放内存资源。

ABR 的工作原理

让我用更通俗的语言解释 ABR 是怎么工作的:

  1. 监控帧率:ABR 会持续监控应用的帧率
  2. 预测负载:根据相机运动、场景复杂度等信息,预测下一帧的 GPU 负载
  3. 调整分辨率
    • 如果预测到 GPU 负载会很高(可能掉帧),就降低渲染分辨率
    • 如果 GPU 负载很低(帧率远超目标),就提高渲染分辨率
  4. 平滑过渡:分辨率的变化是渐进的,不会突然跳变

适用场景

ABR 特别适合以下场景:

  • 3D 游戏:场景复杂度变化大的游戏
  • 图形渲染应用:需要稳定帧率的渲染场景
  • VR/AR 应用:对帧率要求极高的场景

注意事项

  1. 分辨率范围设置HMS_ABR_SetScaleRange的参数要根据你的应用来设置。如果最低值设得太低,画质会明显下降;如果设得太高,可能无法有效防止掉帧

  2. 目标帧率设置:要根据你的应用实际需要来设置。比如游戏一般 60fps 或 120fps,普通应用 30fps 就够了

  3. 相机数据更新HMS_ABR_UpdateCameraData要每帧都调用,而且数据要准确,否则 ABR 的预测会不准确

  4. 错误处理:每个 ABR API 都会返回错误码,要检查并处理错误

核心流程图

ABR 自适应缓冲分辨率的工作原理:

创建 ABR 上下文

设置目标帧率

设置分辨率缩放范围

激活 ABR 实例

每帧渲染循环

更新相机运动数据

标记帧缓冲

执行场景渲染

获取当前缩放系数

GPU 负载是否过高?

自动降低渲染分辨率

自动提高渲染分辨率

ABR 生命周期管理:

Surface 创建

HMS_ABR_CreateContext

HMS_ABR_SetTargetFps

HMS_ABR_SetScaleRange

HMS_ABR_Activate

进入渲染循环

HMS_ABR_UpdateCameraData

HMS_ABR_MarkFrameBuffer_GLES

渲染场景

HMS_ABR_GetScale

Surface 销毁

HMS_ABR_DestroyContext

总结

ABR 是一个很实用的图形优化技术,它能让你的应用在不同负载下都能保持稳定的帧率。核心流程:

  1. 创建 ABR 上下文:HMS_ABR_CreateContext
  2. 设置目标帧率:HMS_ABR_SetTargetFps
  3. 设置分辨率范围:HMS_ABR_SetScaleRange
  4. 激活 ABR:HMS_ABR_Activate
  5. 每帧更新相机数据:HMS_ABR_UpdateCameraData
  6. 每帧标记帧缓冲:HMS_ABR_MarkFrameBuffer_GLES
  7. 获取缩放系数(可选):HMS_ABR_GetScale
  8. 销毁上下文:HMS_ABR_DestroyContext

掌握了这些,你就能在 HarmonyOS 应用中实现自适应稳态渲染了。这对于提升用户体验,特别是在复杂场景下保持流畅度,是非常有帮助的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/21 12:51:05

2026年降AI率平台选购指南:三大类10款热门降AI率工具实测

今年AIGC检测真的是让人头大&#xff01;现在用AI写论文初稿早已不是什么秘密&#xff0c;但那股子挥之不去的"AI味儿"&#xff0c;学校检测系统一抓一个准。这俩月我把市面上能找到的降AI工具几乎试了个遍&#xff0c;踩了无数坑&#xff0c;花了好多冤枉钱——要么…

作者头像 李华
网站建设 2026/6/21 12:53:28

计算机视觉深度学习框架YOLOV8模型如何训练水下生物检测数据集 通过训练的权重推理识别检测海底生物检测数据集中的海参海胆扇贝海星鱼类潜水员海龟等

计算机视觉深度学习框架YOLOV8模型如何训练水下生物检测数据集 通过训练的权重推理识别检测海底生物检测数据集中的海参海胆扇贝海星鱼类潜水员海龟等 文章目录**水下目标检测数据集信息表****类别标签对照表&#xff08;共10类&#xff09;****数据集划分统计**✅ 一、环境配置…

作者头像 李华
网站建设 2026/6/21 12:52:26

Sunshine游戏串流:终极指南搭建你的私人云游戏平台

Sunshine游戏串流&#xff1a;终极指南搭建你的私人云游戏平台 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否曾梦想过随时随地畅玩高性能电脑上的3A大作&#xff1f;是否厌…

作者头像 李华
网站建设 2026/6/5 23:57:37

Claude Code 对话导出神器:一行命令,把你的 AI 对话变成永久知识库

一、工具简介 Claude Conversation Extractor 是一款专为 Claude Code 用户设计的命令行工具&#xff0c;用于解决 Claude Code 官方不提供对话导出功能的痛点。它直接读取 Claude Code 存储在本地 ~/.claude/projects/ 目录下的 JSONL 格式日志文件&#xff0c;将其转换为干净…

作者头像 李华
网站建设 2026/6/7 20:21:57

【无人机控制】集群无人机硬件平台,融合PX4 原生控制架构+改进 RPT 鲁棒控制,集成动力学模型、全层级飞控、轨迹生成,支持常规轨迹 机动飞行Matlab仿真

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;擅长毕业设计辅导、数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。&#x1f34e; 往期回顾关注个人主页&#xff1a;Matlab科研工作室&#x1f447; 关注我领取海量matlab电子书和…

作者头像 李华
网站建设 2026/6/5 23:57:26

实战指南:基于快马AI生成支持WebSocket的实时协作白板服务器

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 请生成一个实战级的服务器应用代码&#xff0c;用于支撑一个简单的实时协作白板应用的后端。技术要求&#xff1a;1、使用Node.js和Socket.io库建立WebSocket服务器&#xff0c;实…

作者头像 李华