• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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