• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# NativeWindow Development
2
3## When to Use
4
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.
6
7The following scenarios are common for NativeWindow development:
8
9* 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.
10* Request and flush a buffer when adapting to the **eglswapbuffer** interface at the EGL.
11
12## Available APIs
13
14| API| Description|
15| -------- | -------- |
16| OH_NativeWindow_NativeWindowRequestBuffer (OHNativeWindow \*window, OHNativeWindowBuffer \*\*buffer, int \*fenceFd) | Requests an **OHNativeWindowBuffer** through an **OHNativeWindow** instance for content production.|
17| 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.|
18| OH_NativeWindow_NativeWindowHandleOpt (OHNativeWindow \*window, int code,...) | Sets or obtains the attributes of an **OHNativeWindow**, including the width, height, and content format.|
19
20For details about the APIs, see [native_window](../reference/native-apis/_native_window.md).
21
22## How to Develop
23
24The 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.
25
26**Adding Dynamic Link Libraries**
27
28Add the following libraries to **CMakeLists.txt**:
29```txt
30libace_ndk.z.so
31libnative_window.so
32```
33
34**Header File**
35```c++
36#include <ace/xcomponent/native_interface_xcomponent.h>
37#include <native_window/external_window.h>
38```
39
401. Obtain an **OHNativeWindow** instance.
41
42    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](../ui/arkts-common-components-xcomponent.md).
43    1. Add an **\<XComponent>** to the .ets file.
44        ```ts
45        XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'entry'})
46            .width(360)
47            .height(360)
48        ```
49    2. Obtain **NativeXComponent** at the native C++ layer.
50        ```c++
51        napi_value exportInstance = nullptr;
52        // Parse the attribute of the wrapped NativeXComponent pointer.
53        napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance);
54        OH_NativeXComponent *nativeXComponent = nullptr;
55        // Use the napi_unwrap API to parse the NativeXComponent instance pointer.
56        napi_unwrap(env, exportInstance, reinterpret_cast<void**>(&nativeXComponent));
57        ```
58    3. Define **OH_NativeXComponent_Callback**.
59        ```c++
60        // Define the callback.
61        void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window)
62        {
63            // Obtain an OHNativeWindow instance.
64            OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
65            // ...
66        }
67        void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window)
68        {
69            // Obtain an OHNativeWindow instance.
70            OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
71            // ...
72        }
73        void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window)
74        {
75            // Obtain an OHNativeWindow instance.
76            OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
77            // ...
78        }
79        void DispatchTouchEventCB(OH_NativeXComponent* component, void* window)
80        {
81            // Obtain an OHNativeWindow instance.
82            OHNativeWindow* nativeWindow = static_cast<OHNativeWindow*>(window);
83            // ...
84        }
85        ```
86        ```c++
87        // Initialize OH_NativeXComponent_Callback.
88        OH_NativeXComponent_Callback callback;
89        callback.OnSurfaceCreated = OnSurfaceCreatedCB;
90        callback.OnSurfaceChanged = OnSurfaceChangedCB;
91        callback.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
92        callback.DispatchTouchEvent = DispatchTouchEventCB;
93        ```
94   4. Register **OH_NativeXComponent_Callback** with **NativeXComponent**.
95        ```c++
96        // Register the callback.
97        OH_NativeXComponent_RegisterCallback(nativeXComponent, &callback);
98        ```
99
1002. Set the attributes of an **OHNativeWindowBuffer** by using **OH_NativeWindow_NativeWindowHandleOpt**.
101    ```c++
102    // Set the width and height of the OHNativeWindowBuffer.
103    int32_t code = SET_BUFFER_GEOMETRY;
104    int32_t width = 0x100;
105    int32_t height = 0x100;
106    // The nativeWindow instance is obtained from the callback in the previous step.
107    int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height);
108    // Set the step of the OHNativeWindowBuffer.
109    code = SET_STRIDE;
110    int32_t stride = 0x8;
111    ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, stride);
112    ```
113
1143. Request an **OHNativeWindowBuffer** from the graphics queue.
115    ```c++
116    OHNativeWindowBuffer* buffer = nullptr;
117    int fenceFd;
118    // Obtain the OHNativeWindowBuffer instance by calling OH_NativeWindow_NativeWindowRequestBuffer.
119    OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer, &fenceFd);
120    // Obtain the buffer handle by calling OH_NativeWindow_GetBufferHandleFromNative.
121    BufferHandle* bufferHandle = OH_NativeWindow_GetBufferHandleFromNative(buffer);
122    ```
123
1244. Map memory.
125    ```c++
126    #include <sys/mman.h>
127
128    // Use mmap() to obtain the memory virtual address of buffer handle.
129    void* mappedAddr = mmap(bufferHandle->virAddr, bufferHandle->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle->fd, 0);
130    if (mappedAddr == MAP_FAILED) {
131        // mmap failed
132    }
133    ```
134
1355. Write the produced content to the **OHNativeWindowBuffer**.
136    ```c++
137    static uint32_t value = 0x00;
138    value++;
139    uint32_t *pixel = static_cast<uint32_t *>(mappedAddr); // Use the address obtained by mmap() to access the memory.
140    for (uint32_t x = 0; x < width; x++) {
141        for (uint32_t y = 0;  y < height; y++) {
142            *pixel++ = value;
143        }
144    }
145    ```
146
1475. Flush the **OHNativeWindowBuffer** to the graphics queue.
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.
150    Region region{nullptr, 0};
151    // 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);
153    ```
1546. Unmap memory.
155    ```c++
156    // Unmap the memory when the memory is no longer required.
157    int result = munmap(mappedAddr, bufferHandle->size);
158    if (result == -1) {
159        // munmap failed
160    }
161    ```
162