native-window-guidelines.md 5.8 KB
Newer Older
Z
zengyawen 已提交
1
# NativeWindow开发指导
A
andrewhw 已提交
2 3 4

## 场景介绍

5
NativeWindow是`OpenHarmony`**本地平台化窗口**,表示图形队列的生产者端。开发者可以通过`NativeWindow`接口进行申请和提交`Buffer`,配置`Buffer`属性信息。
A
andrewhw 已提交
6 7
针对NativeWindow,常见的开发场景如下:

S
fix  
shegangbin 已提交
8
* 通过`NativeWindow`提供的Native API接口申请图形`Buffer`,并将生产图形内容写入图形`Buffer`,最终提交`Buffer`到图形队列
A
andrew0229 已提交
9
* 在适配EGL层的`eglswapbuffer`接口时,进行申请和提交`Buffer`
A
andrewhw 已提交
10 11 12 13 14

## 接口说明

| 接口名 | 描述 | 
| -------- | -------- |
15 16 17
| OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*\*buffer, int \*fenceFd) | 通过OHNativeWindow对象申请一块OHNativeWindowBuffer,用以内容生产。 | 
| OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer, int fenceFd, Region region) | 通过OHNativeWindow将生产好内容的OHNativeWindowBuffer放回到Buffer队列中,用以内容消费。 | 
| OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow \*window, int code,...) | 设置/获取OHNativeWindow的属性,包括设置/获取宽高、内容格式等。 | 
A
andrewhw 已提交
18 19 20 21 22

详细的接口说明请参考[native_window](../reference/native-apis/_native_window.md)

## 开发步骤

S
fix  
shegangbin 已提交
23 24
以下步骤描述了在**OpenHarmony**中如何使用`NativeWindow`提供的Native API接口,申请图形`Buffer`,并将生产图形内容写入图形`Buffer`后,最终提交`Buffer`到图形队列。

S
shegangbin 已提交
25
**头文件**
S
fix  
shegangbin 已提交
26 27 28
```c++
#include <native_window/external_window.h>
```
A
andrewhw 已提交
29

30
1. **获取OHNativeWindow实例**。可在[`OH_NativeXComponent_Callback`](../reference/native-apis/_o_h___native_x_component___callback.md)提供的接口中获取。
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
   1. 在xxx.ets 中定义 XComponent。
        ```ts
        XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'nativerender'})
            .onLoad((context) => {
                this.context = context;
            })
            .onDestroy(() => {
            })
        ```
   2. 在 native c++ 层获取 NativeXComponent。
       ```c++
       napi_value exportInstance = nullptr;
       napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);

       OH_NativeXComponent *nativeXComponent = nullptr;
       napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));

       char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = { };
       uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
       OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize);
        ```
   3. 定义 OH_NativeXComponent_Callback
       ```c++
       // 定义回调函数
       void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window)
       {
57
           // 可获取 OHNativeWindow 实例
58 59 60 61 62
           OHNativeWindow* nativeWindow = window;
           // ...
       }
       void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window)
       {
63
           // 可获取 OHNativeWindow 实例
64 65 66 67 68
           OHNativeWindow* nativeWindow = window;
           // ...
       }
       void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window)
       {
69
           // 可获取 OHNativeWindow 实例
70 71 72 73 74
           OHNativeWindow* nativeWindow = window;
           // ...
       }
       void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
       {
75
           // 可获取 OHNativeWindow 实例
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
           OHNativeWindow* nativeWindow = window;
           // ...
       }
       ```
       ```c++
       // 初始化 OH_NativeXComponent_Callback
       OH_NativeXComponent_Callback callback_;
       callback_->OnSurfaceCreated = OnSurfaceCreatedCB;
       callback_->OnSurfaceChanged = OnSurfaceChangedCB;
       callback_->OnSurfaceDestroyed = OnSurfaceDestroyedCB;
       callback_->DispatchTouchEvent = DispatchTouchEventCB;
       ```
   4. 将 OH_NativeXComponent_Callback 注册给 NativeXComponent。
       ```c++
       OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback_);
       ```
A
andrewhw 已提交
92

S
fix  
shegangbin 已提交
93
2. **设置OHNativeWindowBuffer的属性**。使用`OH_NativeWindow_NativeWindowHandleOpt`设置`OHNativeWindowBuffer`的属性。
A
andrewhw 已提交
94
    ```c++
S
fix  
shegangbin 已提交
95
    // 设置 OHNativeWindowBuffer 的宽高
A
andrew0229 已提交
96 97 98 99
    code = SET_BUFFER_GEOMETRY;
    int32_t width = 0x100;
    int32_t height = 0x100;
    ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height);
S
fix  
shegangbin 已提交
100
    // 设置 OHNativeWindowBuffer 的步长
A
andrew0229 已提交
101 102 103
    code = SET_STRIDE;
    int32_t stride = 0x8;
    ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride);
A
andrewhw 已提交
104 105
    ```

S
fix  
shegangbin 已提交
106
3. **从图形队列申请OHNativeWindowBuffer**
A
andrew0229 已提交
107
    ```c++
S
fix  
shegangbin 已提交
108
    OHNativeWindowBuffer* buffer = nullptr;
A
andrew0229 已提交
109
    int fenceFd;
S
fix  
shegangbin 已提交
110
    // 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例
A
andrew0229 已提交
111 112 113 114
    OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer, &fenceFd);
    // 通过 OH_NativeWindow_GetNativeBufferHandleFromNative 获取 buffer 的 handle
    BufferHandle* bufferHandle = OH_NativeWindow_GetNativeBufferHandleFromNative(buffer);
    ```
A
andrewhw 已提交
115

S
fix  
shegangbin 已提交
116
4. **将生产的内容写入OHNativeWindowBuffer**
A
andrewhw 已提交
117
    ```c++
A
andrew0229 已提交
118 119 120 121 122 123 124 125 126
    auto image = static_cast<uint8_t *>(buffer->sfbuffer->GetVirAddr());
    static uint32_t value = 0x00;
    value++;

    uint32_t *pixel = static_cast<uint32_t *>(image);
    for (uint32_t x = 0; x < width; x++) {
        for (uint32_t y = 0;  y < height; y++) {
            *pixel++ = value;
        }
A
andrewhw 已提交
127 128 129
    }
    ```

S
fix  
shegangbin 已提交
130
5. **提交OHNativeWindowBuffer到图形队列**
A
andrewhw 已提交
131
    ```c++
S
fix  
shegangbin 已提交
132
    // 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为OHNativeWindowBuffer全部有内容更改。
A
andrew0229 已提交
133 134 135
    Region region{nullptr, 0};
    // 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。
    OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer, fenceFd, region);
A
andrewhw 已提交
136
    ```