1# NativeWindow 开发指导 2 3## 场景介绍 4 5NativeWindow是`OpenHarmony`**本地平台化窗口**,表示图形队列的生产者端。接口能力包括从`Surface`构建`NativeWindow`的能力,从`SurfaceBuffer`构建出`NativeWindowBuffer`的能力,开发者可以通过`NativeWindow`接口进行申请和提交`Buffer`。 6针对NativeWindow,常见的开发场景如下: 7 8* 通过`NativeWindow`提供的`NAPI`接口申请图形`Buffer`,并将生产图形内容写入图形`Buffer`,最终提交`Buffer`到图形队列 9* 在适配EGL层的`eglswapbuffer`接口时,进行申请和提交`Buffer` 10 11## 接口说明 12 13| 接口名 | 描述 | 14| -------- | -------- | 15| OH_NativeWindow_CreateNativeWindowFromSurface (void \*pSurface) | 创建NativeWindow实例,每次调用都会产生一个新的NativeWindow实例。 | 16| OH_NativeWindow_DestroyNativeWindow (OHNativeWindow \*window) | 将NativeWindow对象的引用计数减1,当引用计数为0的时候,该NativeWindow对象会被析构掉。 | 17| OH_NativeWindow_CreateNativeWindowBufferFromSurfaceBuffer (void \*pSurfaceBuffer) | 创建NativeWindowBuffer实例,每次调用都会产生一个新的NativeWindowBuffer实例。 | 18| OH_NativeWindow_DestroyNativeWindowBuffer (OHNativeWindowBuffer \*buffer) | 将NativeWindowBuffer对象的引用计数减1,当引用计数为0的时候,该NativeWindowBuffer对象会被析构掉。 | 19| OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*\*buffer, int \*fenceFd) | 通过NativeWindow对象申请一块NativeWindowBuffer,用以内容生产。 | 20| OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer, int fenceFd, Region region) | 通过NativeWindow将生产好内容的NativeWindowBuffer放回到Buffer队列中,用以内容消费。 | 21| OH_NativeWindow_NativeWindowAbortBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer) | 通过NativeWindow将之前申请出来的NativeWindowBuffer返还到Buffer队列中,供下次再申请。 | 22| OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow \*window, int code,...) | 设置/获取NativeWindow的属性,包括设置/获取宽高、内容格式等。 | 23| OH_NativeWindow_GetBufferHandleFromNative (OHNativeWindowBuffer \*buffer) | 通过NativeWindowBuffer获取该buffer的BufferHandle指针。 | 24| OH_NativeWindow_NativeObjectReference (void \*obj) | 增加一个NativeObject的引用计数。 | 25| OH_NativeWindow_NativeObjectUnreference (void \*obj) | 减少一个NativeObject的引用计数,当引用计数减少为0时,该NativeObject将被析构掉。 | 26| OH_NativeWindow_GetNativeObjectMagic (void \*obj) | 获取NativeObject的MagicId。 | 27| OH_NativeWindow_NativeWindowSetScalingMode (OHNativeWindow \*window, uint32_t sequence, OHScalingMode scalingMode) | 设置NativeWindow的缩放模式。 | 28| OH_NativeWindow_NativeWindowSetMetaData(OHNativeWindow \*window, uint32_t sequence, int32_t size, const OHHDRMetaData \*metaData) | 设置NativeWindow的HDR静态元数据。 | 29| OH_NativeWindow_NativeWindowSetMetaDataSet(OHNativeWindow \*window, uint32_t sequence, OHHDRMetadataKey key, int32_t size, const uint8_t \*metaData) | 设置NativeWindow的HDR静态元数据集。 | 30| OH_NativeWindow_NativeWindowSetTunnelHandle(OHNativeWindow \*window, const OHExtDataHandle \*handle) | 设置NativeWindow的TunnelHandle。 | 31 32详细的接口说明请参考[native_window](../reference/native-apis/_native_window.md)。 33 34## 开发步骤 35 36以下步骤描述了在**OpenHarmony**中如何使用`NativeWindow`提供的`NAPI`接口,申请图形`Buffer`,并将生产图形内容写入图形`Buffer`后,最终提交`Buffer`到图形队列。 37 381. **获取NativeWindow实例**。可在[`OH_NativeXComponent_Callback`](../reference/native-apis/_o_h___native_x_component___callback.md)提供的接口中获取。 39 1. 在xxx.ets 中定义 XComponent。 40 ```ts 41 XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'nativerender'}) 42 .onLoad((context) => { 43 this.context = context; 44 }) 45 .onDestroy(() => { 46 }) 47 ``` 48 2. 在 native c++ 层获取 NativeXComponent。 49 ```c++ 50 napi_value exportInstance = nullptr; 51 napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance); 52 53 OH_NativeXComponent *nativeXComponent = nullptr; 54 napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent)); 55 56 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { }; 57 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; 58 OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize); 59 ``` 60 3. 定义 OH_NativeXComponent_Callback。 61 ```c++ 62 // 定义回调函数 63 void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window) 64 { 65 // 可获取 NativeWindow 实例 66 OHNativeWindow* nativeWindow = window; 67 // ... 68 } 69 void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window) 70 { 71 // 可获取 NativeWindow 实例 72 OHNativeWindow* nativeWindow = window; 73 // ... 74 } 75 void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window) 76 { 77 // 可获取 NativeWindow 实例 78 OHNativeWindow* nativeWindow = window; 79 // ... 80 } 81 void DispatchTouchEventCB(OH_NativeXComponent* component, void* window) 82 { 83 // 可获取 NativeWindow 实例 84 OHNativeWindow* nativeWindow = window; 85 // ... 86 } 87 ``` 88 ```c++ 89 // 初始化 OH_NativeXComponent_Callback 90 OH_NativeXComponent_Callback callback_; 91 callback_->OnSurfaceCreated = OnSurfaceCreatedCB; 92 callback_->OnSurfaceChanged = OnSurfaceChangedCB; 93 callback_->OnSurfaceDestroyed = OnSurfaceDestroyedCB; 94 callback_->DispatchTouchEvent = DispatchTouchEventCB; 95 ``` 96 4. 将 OH_NativeXComponent_Callback 注册给 NativeXComponent。 97 ```c++ 98 OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback_); 99 ``` 100 1012. **设置NativeWindowBuffer的属性**。使用`OH_NativeWindow_NativeWindowHandleOpt`设置`NativeWindowBuffer`的属性。 102 ```c++ 103 // 设置 NativeWindowBuffer 的读写场景 104 int code = SET_USAGE; 105 int32_t usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA; 106 int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, usage); 107 // 设置 NativeWindowBuffer 的宽高 108 code = SET_BUFFER_GEOMETRY; 109 int32_t width = 0x100; 110 int32_t height = 0x100; 111 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height); 112 // 设置 NativeWindowBuffer 的步长 113 code = SET_STRIDE; 114 int32_t stride = 0x8; 115 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride); 116 // 设置 NativeWindowBuffer 的格式 117 code = SET_FORMAT; 118 int32_t format = PIXEL_FMT_RGBA_8888; 119 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, format); 120 ``` 121 1223. **从图形队列申请NativeWindowBuffer**。 123 ```c++ 124 struct NativeWindowBuffer* buffer = nullptr; 125 int fenceFd; 126 // 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 NativeWindowBuffer 实例 127 OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer, &fenceFd); 128 // 通过 OH_NativeWindow_GetNativeBufferHandleFromNative 获取 buffer 的 handle 129 BufferHandle* bufferHandle = OH_NativeWindow_GetNativeBufferHandleFromNative(buffer); 130 ``` 131 1324. **将生产的内容写入NativeWindowBuffer**。 133 ```c++ 134 auto image = static_cast<uint8_t *>(buffer->sfbuffer->GetVirAddr()); 135 static uint32_t value = 0x00; 136 value++; 137 138 uint32_t *pixel = static_cast<uint32_t *>(image); 139 for (uint32_t x = 0; x < width; x++) { 140 for (uint32_t y = 0; y < height; y++) { 141 *pixel++ = value; 142 } 143 } 144 ``` 145 1465. **提交NativeWindowBuffer到图形队列**。 147 ```c++ 148 // 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为NativeWindowBuffer全部有内容更改。 149 Region region{nullptr, 0}; 150 // 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。 151 OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer, fenceFd, region); 152 ``` 153 154## 相关实例 155 156针对NativeWindow的使用,有以下相关实例可供参考: 157 158- [使用NativeWindow接口获取并提交Buffer](https://gitee.com/openharmony/graphic_graphic_2d/blob/master/rosen/samples/hello_native_window/hello_native_window.cpp) 159