鸿蒙 与Android NativeWindow 接口对比及实现分析
·
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);
// 查询
int width, 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);
// 查询
int width, height;
OH_NativeWindow_NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &height, &width);
三、提交 Buffer 差异
Android
// 仅需 release fence
ANativeWindow_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
// 明确定义,直接访问
typedef struct BufferHandle {
int32_t fd; // DMA-BUF fd
uint32_t reserveInts; // reserve 数组大小
int32_t reserve[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.cpp
static std::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_t OH_NativeWindow_NativeWindowHandleOpt(OHNativeWindow *window, int code, ...)
{
va_list args;
va_start(args, code);
auto it = operationMap.find(code);
if (it != operationMap.end()) {
it->second(window, args);
}
va_end(args);
return OHOS::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代码移植鸿蒙发现不少知识点,在此总结。后续会讲部分实现接口!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)