鸿蒙开发-怎么知道设备支持哪些GPU特性?GLES扩展查询
想知道你的设备支持哪些 XEngine 图形加速能力?用扩展查询接口一查便知
你在做游戏或者图形应用的时候,经常会碰到一个问题:我写的这些高级渲染效果,用户的手机到底支持不支持?比如说超分辨率、自适应着色率这些能力,不是每台设备都有的。如果你不检查就直接调用,轻则功能没效果,重则直接崩溃。
XEngine Kit 提供了一个专门的扩展查询接口,让你在 OpenGL ES 环境下可以查清楚当前设备支持哪些 XEngine 扩展特性。说白了,就是先"摸底",再决定用什么功能。
先说说这个接口能干什么
XEngine 的 OpenGL ES 扩展查询接口只有一个函数:HMS_XEG_GetString。你传一个参数进去,它就返回一个字符串,告诉你当前设备支持哪些扩展。返回的字符串是用空格分隔的扩展名列表,比如"XEG_spatial_upscale XEG_adaptive_vrs"这样的格式。
这个接口的使用场景很直接:你在渲染管线初始化的时候调一次,看看设备支持什么,然后根据结果决定开启哪些高级特性。
下面是扩展查询的整体流程:
怎么用这个接口
第一步:包含头文件
要使用这个接口,你需要包含 XEngine 的扩展查询头文件:
#include<xengine/xeg_gles_extension.h>这个头文件里定义了HMS_XEG_GetString函数和相关的宏定义。链接的时候记得加上libxengine.so。
第二步:调用查询接口
查询的代码非常简单。你需要传入XEG_EXTENSIONS这个宏作为参数,它告诉接口"我要查 XEngine 的扩展列表":
constGLubyte*extensions=HMS_XEG_GetString(XEG_EXTENSIONS);XEG_EXTENSIONS的值是0x01U,它是专门为这个查询接口定义的枚举值。你不用管它的具体数值,直接用宏就行。
第三步:解析返回的字符串
HMS_XEG_GetString返回的是一个const GLubyte*类型的字符串。这个字符串里包含了当前设备支持的所有 XEngine 扩展名称,每个名称之间用空格分隔。
比如说,返回结果可能是这样的:
"XEG_spatial_upscale XEG_neural_upscale XEG_adaptive_vrs"你需要自己去解析这个字符串,看看你需要的扩展在不在里面。打个比方,你做了一个游戏打算用空域超分功能,那你就要检查返回的字符串里有没有"XEG_spatial_upscale"这个子串。
你可以用strstr函数来检查:
constGLubyte*extensions=HMS_XEG_GetString(XEG_EXTENSIONS);if(extensions!=NULL){if(strstr((constchar*)extensions,"XEG_spatial_upscale")!=NULL){// 设备支持空域GPU超分,可以放心调用相关接口}if(strstr((constchar*)extensions,"XEG_neural_upscale")!=NULL){// 设备支持空域AI超分}if(strstr((constchar*)extensions,"XEG_adaptive_vrs")!=NULL){// 设备支持自适应VRS}if(strstr((constchar*)extensions,"XEG_temporal_upscale")!=NULL){// 设备支持时域AI超分}}else{// 查询失败,可能XEngine没有正确初始化}关于返回值的一些细节
有几个点需要注意:
返回的扩展名之间用空格分隔,但扩展名本身不包含空格字符。所以你可以放心地用空格来分割字符串。
如果查询出错(比如 XEngine 没有初始化),接口会返回空(NULL)。所以在使用返回值之前,记得判空。
这个查询结果是跟当前设备绑定的,不同手机、不同芯片返回的结果可能完全不同。你在开发机上查到支持某个特性,不代表用户的手机也支持。
实际开发中的典型用法
根据查询结果选择最优渲染策略的决策流程:
在实际项目里,你一般会在渲染引擎初始化的时候做这个查询,然后把结果缓存起来。因为扩展列表在运行过程中不会变,没必要每帧都查。
一个典型的初始化流程大概是这样的:
// 初始化阶段查询扩展constGLubyte*extensions=HMS_XEG_GetString(XEG_EXTENSIONS);if(extensions==NULL){// XEngine不可用,走普通渲染路径return;}// 检查是否支持你需要的特性bool supportsSpatialUpscale=strstr((constchar*)extensions,"XEG_spatial_upscale")!=NULL;bool supportsAdaptiveVRS=strstr((constchar*)extensions,"XEG_adaptive_vrs")!=NULL;bool supportsNeuralUpscale=strstr((constchar*)extensions,"XEG_neural_upscale")!=NULL;bool supportsTemporalUpscale=strstr((constchar*)extensions,"XEG_temporal_upscale")!=NULL;// 根据支持情况选择渲染策略if(supportsNeuralUpscale){// 最优方案:用AI超分,画质最好}elseif(supportsSpatialUpscale){// 次选方案:用GPU超分,性能好}else{// 降级方案:不使用超分}这样做的好处是,你的应用可以在不同能力的设备上自动选择最优的渲染方案。高端机用最好的效果,低端机也不至于崩溃。
总结一下
XEngine 的 GLES 扩展查询接口虽然只有一个函数,但它是你使用所有 XEngine 高级特性的"入口"。不管你要用超分、VRS 还是其他什么特性,第一步都是先调HMS_XEG_GetString(XEG_EXTENSIONS)查一下设备支持什么。
记住两个关键点:一是返回的字符串用空格分隔扩展名,二是返回 NULL 表示查询失败。把查询结果缓存好,后面根据它来决定你的渲染策略就行了。
