native-window-guidelines.md 7.0 KB
Newer Older
1
# NativeWindow Development
W
wusongqing 已提交
2 3 4

## When to Use

5
**NativeWindow** is a local platform-based window of OpenHarmony that represents the producer of a graphics queue. It provides APIs for you to request and flush a buffer and configure buffer attributes.
W
wusongqing 已提交
6

7 8 9
The following scenarios are common for NativeWindow development:

* Request a graphics buffer by using the native API provided by **NativeWindow**, write the produced graphics content to the buffer, and flush the buffer to the graphics queue.
G
Gloria 已提交
10
* Request and flush a buffer when adapting to the **eglswapbuffer** interface at the EGL.
W
wusongqing 已提交
11 12 13

## Available APIs

G
Gloria 已提交
14
| API| Description| 
W
wusongqing 已提交
15
| -------- | -------- |
G
Gloria 已提交
16 17 18
| OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*\*buffer, int \*fenceFd) | Requests an **OHNativeWindowBuffer** through an **OHNativeWindow** instance for content production.| 
| OH_NativeWindow_NativeWindowFlushBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*buffer, int fenceFd, Region region) | Flushes the **OHNativeWindowBuffer** filled with the content to the buffer queue through an **OHNativeWindow** instance for content consumption.| 
| OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow \*window, int code,...) | Sets or obtains the attributes of an **OHNativeWindow**, including the width, height, and content format.| 
19 20

For details about the APIs, see [native_window](../reference/native-apis/_native_window.md).
W
wusongqing 已提交
21 22 23

## How to Develop

24 25
The following describes how to use the native APIs provided by **NativeWindow** to request a graphics buffer, write the produced graphics content to the buffer, and flush the buffer to the graphics queue.

26 27 28 29 30 31 32 33
**Adding Dynamic Link Libraries**

Add the following libraries to **CMakeLists.txt**:
```txt
libace_ndk.z.so
libnative_window.so
```

34 35
**Header File**
```c++
36
#include <ace/xcomponent/native_interface_xcomponent.h>
37 38
#include <native_window/external_window.h>
```
W
wusongqing 已提交
39

G
Gloria 已提交
40
1. Obtain an **OHNativeWindow** instance.
41 42 43

    You can call the APIs provided by [OH_NativeXComponent_Callback](../reference/native-apis/_o_h___native_x_component___callback.md) to obtain an **OHNativeWindow** instance. An example code snippet is provided below. For details about how to use the **\<XComponent>**, see [XComponent Development](xcomponent-guidelines.md).
    1. Add an **\<XComponent>** to the .ets file.
G
Gloria 已提交
44
        ```ts
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
        XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'entry'})
            .width(360)
            .height(360)
        ```
    2. Obtain **NativeXComponent** at the native C++ layer.
        ```c++
        napi_value exportInstance = nullptr;
        // Parse the attribute of the wrapped NativeXComponent pointer.
        napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
        OH_NativeXComponent *nativeXComponent = nullptr;
        // Use the napi_unwrap API to parse the NativeXComponent instance pointer.
        napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
        ```
    3. Define **OH_NativeXComponent_Callback**.
        ```c++
        // Define the callback.
        void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window)
        {
            // Obtain an OHNativeWindow instance.
            OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
            // ...
        }
        void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window)
        {
            // Obtain an OHNativeWindow instance.
            OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
            // ...
        }
        void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window)
        {
            // Obtain an OHNativeWindow instance.
            OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
            // ...
        }
        void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
        {
            // Obtain an OHNativeWindow instance.
            OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
            // ...
        }
        ```
        ```c++
        // Initialize OH_NativeXComponent_Callback.
        OH_NativeXComponent_Callback callback;
        callback.OnSurfaceCreated = OnSurfaceCreatedCB;
        callback.OnSurfaceChanged = OnSurfaceChangedCB;
        callback.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
        callback.DispatchTouchEvent = DispatchTouchEventCB;
G
Gloria 已提交
93 94
        ```
   4. Register **OH_NativeXComponent_Callback** with **NativeXComponent**.
95 96 97 98
        ```c++
        // Register the callback.
        OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback);
        ```
W
wusongqing 已提交
99

100
2. Set the attributes of an **OHNativeWindowBuffer** by using **OH_NativeWindow_NativeWindowHandleOpt**.
W
wusongqing 已提交
101
    ```c++
102
    // Set the width and height of the OHNativeWindowBuffer.
103
    int32_t code = SET_BUFFER_GEOMETRY;
G
Gloria 已提交
104 105
    int32_t width = 0x100;
    int32_t height = 0x100;
106 107
    // The nativeWindow instance is obtained from the callback in the previous step.
    int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height);
108
    // Set the step of the OHNativeWindowBuffer.
G
Gloria 已提交
109 110 111 112
    code = SET_STRIDE;
    int32_t stride = 0x8;
    ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride);
    ```
W
wusongqing 已提交
113

114
3. Request an **OHNativeWindowBuffer** from the graphics queue.
G
Gloria 已提交
115
    ```c++
116
    OHNativeWindowBuffer* buffer = nullptr;
G
Gloria 已提交
117
    int fenceFd;
118
    // Obtain the OHNativeWindowBuffer instance by calling OH_NativeWindow_NativeWindowRequestBuffer.
119 120 121 122 123 124 125 126 127 128 129 130 131 132
    OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer, &fenceFd);
    // Obtain the buffer handle by calling OH_NativeWindow_GetBufferHandleFromNative.
    BufferHandle* bufferHandle = OH_NativeWindow_GetBufferHandleFromNative(buffer);
    ```

4. Map memory.
    ```c++
    #include <sys/mman.h>

    // Use mmap() to obtain the memory virtual address of buffer handle.
    void* mappedAddr = mmap(bufferHandle->virAddr, bufferHandle->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle->fd, 0);
    if (mappedAddr == MAP_FAILED) {
        // mmap failed
    }
G
Gloria 已提交
133
    ```
W
wusongqing 已提交
134

135
5. Write the produced content to the **OHNativeWindowBuffer**.
G
Gloria 已提交
136 137 138
    ```c++
    static uint32_t value = 0x00;
    value++;
139
    uint32_t *pixel = static_cast<uint32_t *>(mappedAddr); // Use the address obtained by mmap() to access the memory.
G
Gloria 已提交
140 141 142 143
    for (uint32_t x = 0; x < width; x++) {
        for (uint32_t y = 0;  y < height; y++) {
            *pixel++ = value;
        }
W
wusongqing 已提交
144 145 146
    }
    ```

147
5. Flush the **OHNativeWindowBuffer** to the graphics queue.
W
wusongqing 已提交
148
    ```c++
149
    // Set the refresh region. If Rect in Region is a null pointer or rectNumber is 0, all contents in the OHNativeWindowBuffer are changed.
G
Gloria 已提交
150 151
    Region region{nullptr, 0};
    // Flush the buffer to the consumer through OH_NativeWindow_NativeWindowFlushBuffer, for example, by displaying it on the screen.
152
    OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region);
W
wusongqing 已提交
153
    ```
154 155 156 157 158 159 160 161
6. Unmap memory.
    ```c++
    // Unmap the memory when the memory is no longer required.
    int result = munmap(mappedAddr, bufferHandle->size);
    if (result == -1) {
        // munmap failed
    }
    ```