Android 的图形栈大家都熟悉:SurfaceFlinger+BufferQueue+ANativeWindow。鸿蒙也是类似的生产者-消费者模型,只是接口命名和实现细节有些不同。
作为 GPU 开发者,需要在 winsys 层对接系统窗口。Android 用ANativeWindow_*,鸿蒙用OH_NativeWindow_*,看着差不多,真移植起来发现坑不少。
![]()
一、核心接口映射
| 功能 | Android | 鸿蒙 OHOS 6.1 |
|---|
| 请求 Buffer | ANativeWindow_dequeueBuffer() | OH_NativeWindow_NativeWindowRequestBuffer() |
| 提交 Buffer | ANativeWindow_queueBuffer() | OH_NativeWindow_NativeWindowFlushBuffer() |
| 取消 Buffer | ANativeWindow_cancelBuffer() | OH_NativeWindow_NativeWindowAbortBuffer() |
| 获取 BufferHandle | ANativeWindowBuffer_getHardwareBuffer() | OH_NativeWindow_GetBufferHandleFromNative() |
| 引用计数+1 | ANativeWindow_acquire() | OH_NativeWindow_NativeObjectReference() |
| 引用计数-1 | ANativeWindow_release() | OH_NativeWindow_NativeObjectUnreference() |
二、属性操作对比
Android:独立函数
ANativeWindow_setUsage(window,usage);ANativeWindow_setBuffersDimensions(window,width,height);ANativeWindow_setBuffersFormat(window,format);ANativeWindow_setBuffersTransform(window,transform);ANativeWindow_setSwapInterval(window,interval);// 查询intwidth,height;ANativeWindow_query(window,ANATIVEWINDOW_QUERY_DEFAULT_WIDTH,&width);
鸿蒙:统一 HandleOpt
// 设置OH_NativeWindow_NativeWindowHandleOpt(window,SET_USAGE,usage);OH_NativeWindow_NativeWindowHandleOpt(window,SET_BUFFER_GEOMETRY,width,height);OH_NativeWindow_NativeWindowHandleOpt(window,SET_FORMAT,format);OH_NativeWindow_NativeWindowHandleOpt(window,SET_TRANSFORM,transform);// 查询intwidth,height;OH_NativeWindow_NativeWindowHandleOpt(window,GET_BUFFER_GEOMETRY,&height,&width);
三、提交 Buffer 差异
Android
// 仅需 release fenceANativeWindow_queueBuffer(window,buffer,release_fence);
鸿蒙
// 需要 release fence + Region 脏区Region region={.rects=nullptr,// nullptr = 全屏.rectNumber=0};OH_NativeWindow_NativeWindowFlushBuffer(window,buffer,release_fence,region);
四、NativeWindowOperation 枚举
| Code | Android 等效 | 参数 |
|---|
SET_BUFFER_GEOMETRY | setBuffersDimensions | int32_t width, int32_t height |
GET_BUFFER_GEOMETRY | query width/height | int32_t *height, int32_t *width |
SET_FORMAT | setBuffersFormat | int32_t format |
GET_FORMAT | getFormat | int32_t *format |
SET_USAGE | setUsage | uint64_t usage |
GET_USAGE | query usage | uint64_t *usage |
SET_TIMEOUT | 无 | int32_t timeout (ms) |
GET_TIMEOUT | 无 | int32_t *timeout |
SET_COLOR_GAMUT | setBuffersDataSpace | int32_t colorGamut |
GET_COLOR_GAMUT | getBuffersDataSpace | int32_t *colorGamut |
SET_TRANSFORM | setBuffersTransform | int32_t transform |
GET_TRANSFORM | query transform | int32_t *transform |
SET_UI_TIMESTAMP | setBuffersTimestamp | uint64_t timestamp |
GET_BUFFERQUEUE_SIZE | query min undequeued | int32_t *size |
SET_SOURCE_TYPE | 无 | int32_t sourceType |
GET_SOURCE_TYPE | 无 | int32_t *sourceType |
SET_APP_FRAMEWORK_TYPE | 无 | char *frameworkType |
GET_APP_FRAMEWORK_TYPE | 无 | char **frameworkType |
SET_HDR_WHITE_POINT_BRIGHTNESS | 无 | float brightness |
SET_SDR_WHITE_POINT_BRIGHTNESS | 无 | float brightness |
SET_DESIRED_PRESENT_TIMESTAMP | 无 | int64_t timestamp |
五、鸿蒙特有接口
| 接口 | 功能 |
|---|
OH_NativeWindow_LockBuffer() | CPU 锁定 Buffer 直接访问 |
OH_NativeWindow_UnlockAndFlushBuffer() | CPU 解锁并提交 |
OH_NativeWindow_PreAllocBuffers() | 预分配 Buffer |
OH_NativeWindow_CleanCache() | 清理 Buffer 缓存 |
OH_NativeWindow_NativeWindowAttachBuffer() | Attach Buffer 到窗口 |
OH_NativeWindow_NativeWindowDetachBuffer() | 从窗口 Detach Buffer |
OH_NativeWindow_GetSurfaceId() | 获取 SurfaceId |
OH_NativeWindow_CreateNativeWindowFromSurfaceId() | 从 SurfaceId 创建窗口 |
OH_NativeWindow_WriteToParcel()/ReadFromParcel() | IPC 序列化 |
OH_NativeWindow_GetLastFlushedBufferV2() | 获取最后提交的 Buffer |
OH_NativeWindow_SetBufferHold() | 保持 Buffer 不被回收 |
六、BufferHandle 结构
Android:AHardwareBuffer
// opaque 结构,通过 API 访问AHardwareBuffer_Desc desc;AHardwareBuffer_describe(buffer,&desc);
鸿蒙:BufferHandle
// 明确定义,直接访问typedefstructBufferHandle{int32_tfd;// DMA-BUF fduint32_treserveInts;// reserve 数组大小int32_treserve[0];// 变长数据:width, height, stride, format...}BufferHandle;// 获取方式BufferHandle*handle=OH_NativeWindow_GetBufferHandleFromNative(buffer);// 直接访问:handle->fd, handle->reserve[0]...
七、完整流程对比
Buffer 获取与提交
Android: ANativeWindow_dequeueBuffer() │ ▼ ┌───────────────┐ │ acquire_fence │ └───────┬───────┘ │ ▼ GPU 渲染完成 │ ▼ ANativeWindow_queueBuffer() (buffer, release_fence) 鸿蒙: OH_NativeWindow_NativeWindowRequestBuffer() │ ▼ ┌───────────────┐ │ acquire_fence │ └───────┬───────┘ │ ▼ GPU 渲染完成 │ ▼ OH_NativeWindow_NativeWindowFlushBuffer() (buffer, release_fence, Region)
八、HandleOpt 分发表实现
// foundation/graphic/graphic_surface/surface/src/native_window.cppstaticstd::map<int,std::function<void(OHNativeWindow*,va_list)>>operationMap={{SET_USAGE,HandleNativeWindowSetUsage},{SET_BUFFER_GEOMETRY,HandleNativeWindowSetBufferGeometry},{SET_FORMAT,HandleNativeWindowSetFormat},{SET_TIMEOUT,HandleNativeWindowSetTimeout},{SET_COLOR_GAMUT,HandleNativeWindowSetColorGamut},{SET_TRANSFORM,HandleNativeWindowSetTransform},{SET_UI_TIMESTAMP,HandleNativeWindowSetUiTimestamp},{SET_SOURCE_TYPE,HandleNativeWindowSetSurfaceSourceType},{SET_APP_FRAMEWORK_TYPE,HandleNativeWindowSetSurfaceAppFrameworkType},{SET_HDR_WHITE_POINT_BRIGHTNESS,HandleNativeWindowSetHdrWhitePointBrightness},{SET_SDR_WHITE_POINT_BRIGHTNESS,HandleNativeWindowSetSdrWhitePointBrightness},{SET_DESIRED_PRESENT_TIMESTAMP,HandleNativeWindowSetDesiredPresentTimestamp},{GET_USAGE,HandleNativeWindowGetUsage},{GET_BUFFER_GEOMETRY,HandleNativeWindowGetBufferGeometry},{GET_FORMAT,HandleNativeWindowGetFormat},{GET_TIMEOUT,HandleNativeWindowGetTimeout},{GET_COLOR_GAMUT,HandleNativeWindowGetColorGamut},{GET_TRANSFORM,HandleNativeWindowGetTransform},{GET_BUFFERQUEUE_SIZE,HandleNativeWindowGetBufferQueueSize},{GET_SOURCE_TYPE,HandleNativeWindowGetSurfaceSourceType},{GET_APP_FRAMEWORK_TYPE,HandleNativeWindowGetSurfaceAppFrameworkType},};int32_tOH_NativeWindow_NativeWindowHandleOpt(OHNativeWindow*window,intcode,...){va_list args;va_start(args,code);autoit=operationMap.find(code);if(it!=operationMap.end()){it->second(window,args);}va_end(args);returnOHOS::GSERROR_OK;}
九、头文件与链接库
| Android | 鸿蒙 |
|---|
| 头文件 | <android/native_window.h> | <native_window/external_window.h> |
<android/hardware_buffer.h> | <native_buffer/buffer_handle.h> |
| 链接库 | -lui -lgui | -lnative_window -lsurface.z |
近期我将android gpu代码移植鸿蒙发现不少知识点,在此总结。后续会讲部分实现接口!