NativeWindow 开发指导
场景介绍
NativeWindow是OpenHarmony
本地平台化窗口,包括从Surface
构建NativeWindow
,从SurfaceBuffer
构建出NativeWindowBuffer
的能力,开发者可以通过NativeWindow
接口进行申请和提交Buffer
。
针对NativeWindow,常见的开发场景如下:
- 通过
Native C++
代码绘制内容并显示在屏幕上 - 在适配EGL层的
eglswapbuffer
接口时,进行提交和申请Buffer
接口说明
接口名 | 描述 |
---|---|
OH_NativeWindow_CreateNativeWindowFromSurface (void *pSurface) | 创建NativeWindow实例,每次调用都会产生一个新的NativeWindow实例。 |
OH_NativeWindow_DestroyNativeWindow (struct NativeWindow *window) | 将NativeWindow对象的引用计数减1,当引用计数为0的时候,该NativeWindow对象会被析构掉。 |
OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer (void *pSurfaceBuffer) | 创建NativeWindowBuffer实例,每次调用都会产生一个新的NativeWindowBuffer实例。 |
OH_NativeWindow_DestroyNativeWindowBuffer (struct NativeWindowBuffer *buffer) | 将NativeWindowBuffer对象的引用计数减1,当引用计数为0的时候,该NativeWindowBuffer对象会被析构掉。 |
OH_NativeWindow_NativeWindowRequestBuffer (struct NativeWindow *window, struct NativeWindowBuffer **buffer, int *fenceFd) | 通过NativeWindow对象申请一块NativeWindowBuffer,用以内容生产。 |
OH_NativeWindow_NativeWindowFlushBuffer (struct NativeWindow *window, struct NativeWindowBuffer *buffer, int fenceFd, Region region) | 通过NativeWindow将生产好内容的NativeWindowBuffer放回到Buffer队列中,用以内容消费。 |
OH_NativeWindow_NativeWindowCancelBuffer (struct NativeWindow *window, struct NativeWindowBuffer *buffer) | 通过NativeWindow将之前申请出来的NativeWindowBuffer返还到Buffer队列中,供下次再申请。 |
OH_NativeWindow_NativeWindowHandleOpt (struct NativeWindow *window, int code,...) | 设置/获取NativeWindow的属性,包括设置/获取宽高、内容格式等。 |
OH_NativeWindow_GetBufferHandleFromNative (struct NativeWindowBuffer *buffer) | 通过NativeWindowBuffer获取该buffer的BufferHandle指针。 |
OH_NativeWindow_NativeObjectReference (void *obj) | 增加一个NativeObject的引用计数。 |
OH_NativeWindow_NativeObjectUnreference (void *obj) | 减少一个NativeObject的引用计数,当引用计数减少为0时,该NativeObject将被析构掉。 |
OH_NativeWindow_GetNativeObjectMagic (void *obj) | 获取NativeObject的MagicId。 |
详细的接口说明请参考native_window。
开发步骤
以下步骤描述了在OpenHarmony中如何利用OH_NativeXComponent
通过Native C++
代码绘制内容并显示在屏幕上。
-
在页面中定义XComponent组件,在
index.ets
中定义一个texture
类型的XComponent
,用于显示内容。XComponent({ id: 'xcomponentId', type: 'texture', libraryname: 'nativerender'}) .borderColor(Color.Red) .borderWidth(5) .onLoad(() => {}) .onDestroy(() => {})
-
获取OH_NativeXComponent实例。使用
napi_get_named_property
接口获取一个OH_NativeXComponent
实例nativeXComponent
,通过注册该实例的回调接口获取NativeWindow
实例。// 定义 napi instance napi_value exportInstance = nullptr; // 定义一个 OH_NativeXComponent 实例 OH_NativeXComponent *nativeXComponent = nullptr; // 通过 OH_NATIVE_XCOMPONENT_OBJ export 实例 napi_getname_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance); // 将 napi instance 转化为 OH_NativeXComponent 实例 napi_unwarp(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
-
定义回调函数OnSurfaceCreated。用于在
Surface
创建时,通过回调函数初始化开发者的渲染环境,例如Skia
渲染环境。并将要显示的内容写入NativeWindow
:void OnSufaceCreatedCB(NativeXComponent* component, void* window) { //获取 native window 的宽高 uint64_t width_ = 0, height_ = 0; OH_NativeXComponent_GetXComponentSize(nativeXComponent, window, &width_, &height_); // 将void* 转换为 NativeWindow 实例,NativeWindow 定义在 native_window/external_window.h 中 NativeWindow* nativeWindow_ = (NativeWindow*)(window); // 通过 OH_NativeWindow_NativeWindowHandleOpt 设置或者获取NativeWindow的属性 // 1.通过 SET_USAGE 设置 Native Window 的 usage 属性, 例如:HBM_USE_CPU_READ OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_USAGE, HBM_USE_CPU_READ | HBM_USE_CPU_WRITE |HBM_USE_MEM_DMA); // 2.通过 SET_BUFFER_GEOMETRY 设置 Native Window 的 宽高属性 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_BUFFER_GEOMETRY, width_, height_); // 3.通过 SET_FORMAT 设置 Native Window 的 format 属性, 例如:PIXEL_FMT_RGBA_8888 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_FORMAT, PIXEL_FMT_RGBA_8888); // 4.通过 SET_STRIDE 设置 Native Window 的 stride 属性 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_STRIDE, 0x8); // 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 NativeWindowBuffer 实例 struct NativeWindowBuffer* buffer = nullptr; int fenceFd; OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer, &fenceFd); // 通过 OH_NativeWindow_GetNativeBufferHandleFromNative 获取 buffer handle BufferHandle* bufferHandle = OH_NativeWindow_GetNativeBufferHandleFromNative(buffer); // 通过 BufferHandle 创建Skia Bitmap SkBitmap bitmap; SkImageInfo imageInfo = ... bitmap.setInfo(imageInfo, bufferHandle->stride); bitmap.setPixels(bufferHandle->virAddr); //创建 Skia Canvas 并将内容写入native window ... //写入完成后,通过OH_NativeWindwo_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上 Regoin region{nullptr, 0}; OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer, fenceFd, region) }
-
注册回调函数OnSurfaceCreated等。使用
OH_NativeXComponent_RegisterCallback
接口注册上一步中创建的回调函数。OH_NativeXComponent_Callback &callback_; callback_->OnSurfaceCreated = OnSufaceCreatedCB; callback_->OnSurfaceChanged = OnSufaceChangedCB; callback_->OnSurfaceDestroyed = OnSufaceDestroyedCB; callback_->DispatchTouchEvent = DispatchTouchEventCB; OH_NativeXComponent_RegisterCallback(nativeXComponent, callback_)
相关实例
针对NativeWindow的使用,有以下相关实例可供参考: