鸿蒙 与Android NativeWindow 接口对比及实现分析
Android 的图形栈大家都熟悉SurfaceFlingerBufferQueueANativeWindow。鸿蒙也是类似的生产者-消费者模型只是接口命名和实现细节有些不同。作为 GPU 开发者需要在 winsys 层对接系统窗口。Android 用ANativeWindow_*鸿蒙用OH_NativeWindow_*看着差不多真移植起来发现坑不少。一、核心接口映射功能Android鸿蒙 OHOS 6.1请求 BufferANativeWindow_dequeueBuffer()OH_NativeWindow_NativeWindowRequestBuffer()提交 BufferANativeWindow_queueBuffer()OH_NativeWindow_NativeWindowFlushBuffer()取消 BufferANativeWindow_cancelBuffer()OH_NativeWindow_NativeWindowAbortBuffer()获取 BufferHandleANativeWindowBuffer_getHardwareBuffer()OH_NativeWindow_GetBufferHandleFromNative()引用计数1ANativeWindow_acquire()OH_NativeWindow_NativeObjectReference()引用计数-1ANativeWindow_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{.rectsnullptr,// nullptr 全屏.rectNumber0};OH_NativeWindow_NativeWindowFlushBuffer(window,buffer,release_fence,region);四、NativeWindowOperation 枚举CodeAndroid 等效参数SET_BUFFER_GEOMETRYsetBuffersDimensionsint32_t width, int32_t heightGET_BUFFER_GEOMETRYquery width/heightint32_t *height, int32_t *widthSET_FORMATsetBuffersFormatint32_t formatGET_FORMATgetFormatint32_t *formatSET_USAGEsetUsageuint64_t usageGET_USAGEquery usageuint64_t *usageSET_TIMEOUT无int32_t timeout (ms)GET_TIMEOUT无int32_t *timeoutSET_COLOR_GAMUTsetBuffersDataSpaceint32_t colorGamutGET_COLOR_GAMUTgetBuffersDataSpaceint32_t *colorGamutSET_TRANSFORMsetBuffersTransformint32_t transformGET_TRANSFORMquery transformint32_t *transformSET_UI_TIMESTAMPsetBuffersTimestampuint64_t timestampGET_BUFFERQUEUE_SIZEquery min undequeuedint32_t *sizeSET_SOURCE_TYPE无int32_t sourceTypeGET_SOURCE_TYPE无int32_t *sourceTypeSET_APP_FRAMEWORK_TYPE无char *frameworkTypeGET_APP_FRAMEWORK_TYPE无char **frameworkTypeSET_HDR_WHITE_POINT_BRIGHTNESS无float brightnessSET_SDR_WHITE_POINT_BRIGHTNESS无float brightnessSET_DESIRED_PRESENT_TIMESTAMP无int64_t timestamp五、鸿蒙特有接口接口功能OH_NativeWindow_LockBuffer()CPU 锁定 Buffer 直接访问OH_NativeWindow_UnlockAndFlushBuffer()CPU 解锁并提交OH_NativeWindow_PreAllocBuffers()预分配 BufferOH_NativeWindow_CleanCache()清理 Buffer 缓存OH_NativeWindow_NativeWindowAttachBuffer()Attach Buffer 到窗口OH_NativeWindow_NativeWindowDetachBuffer()从窗口 Detach BufferOH_NativeWindow_GetSurfaceId()获取 SurfaceIdOH_NativeWindow_CreateNativeWindowFromSurfaceId()从 SurfaceId 创建窗口OH_NativeWindow_WriteToParcel()/ReadFromParcel()IPC 序列化OH_NativeWindow_GetLastFlushedBufferV2()获取最后提交的 BufferOH_NativeWindow_SetBufferHold()保持 Buffer 不被回收六、BufferHandle 结构AndroidAHardwareBuffer// 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*handleOH_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::mapint,std::functionvoid(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);autoitoperationMap.find(code);if(it!operationMap.end()){it-second(window,args);}va_end(args);returnOHOS::GSERROR_OK;}九、头文件与链接库Android鸿蒙头文件android/native_window.hnative_window/external_window.handroid/hardware_buffer.hnative_buffer/buffer_handle.h链接库-lui -lgui-lnative_window -lsurface.z近期我将android gpu代码移植鸿蒙发现不少知识点在此总结。后续会讲部分实现接口