1e41f4b71Sopenharmony_ci# Native Image Development (C/C++)
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## When to Use
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ciThe native image module is used for associating a surface with an OpenGL external texture. It functions as the consumer of a graphics queue. You can use the APIs of this module to obtain and use a buffer, and output the buffer content to an OpenGL external texture.
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciThe following scenario is common for native image development:
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciUse the native image APIs to create an **OH_NativeImage** instance as the consumer and obtain the corresponding **OHNativeWindow** instance (functioning as the producer). Use the native window APIs to fill in and flush the buffer, and then use the native image APIs to update the buffer content to an OpenGL ES texture.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ciThe native image module must be used together with the native window, native buffer, EGL, and GLES3 modules.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci## Available APIs
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ci| API                                                      | Description                                                        |
16e41f4b71Sopenharmony_ci| ------------------------------------------------------------ | ------------------------------------------------------------ |
17e41f4b71Sopenharmony_ci| OH_NativeImage_Create (uint32_t textureId, uint32_t textureTarget) | Creates an **OH_NativeImage** instance to be associated with the specified OpenGL ES texture ID and target.|
18e41f4b71Sopenharmony_ci| OH_NativeImage_AcquireNativeWindow (OH_NativeImage \*image)  | Obtains an **OHNativeWindow** instance associated with an **OH_NativeImage** instance. You need to call **OH_NativeWindow_DestroyNativeWindow** to release the **OHNativeWindow** instance when it is no longer needed.|
19e41f4b71Sopenharmony_ci| OH_NativeImage_AttachContext (OH_NativeImage \*image, uint32_t textureId) | Attaches an **OH_NativeImage** instance to the current OpenGL ES context. The OpenGL ES texture will be bound to an **GL_TEXTURE_EXTERNAL_OES** instance and updated through the **OH_NativeImage** instance.|
20e41f4b71Sopenharmony_ci| OH_NativeImage_DetachContext (OH_NativeImage \*image)        | Detaches an **OH_NativeImage** instance from the current OpenGL ES context.             |
21e41f4b71Sopenharmony_ci| OH_NativeImage_UpdateSurfaceImage (OH_NativeImage \*image)   | Updates the OpenGL ES texture associated with the latest frame through an **OH_NativeImage** instance.     |
22e41f4b71Sopenharmony_ci| OH_NativeImage_GetTimestamp (OH_NativeImage \*image)         | Obtains the timestamp of the texture image that recently called the **OH_NativeImage_UpdateSurfaceImage** function.|
23e41f4b71Sopenharmony_ci| OH_NativeImage_GetTransformMatrix (OH_NativeImage \*image, float matrix[16]) | Obtains the transformation matrix of the texture image that recently called the **OH_NativeImage_UpdateSurfaceImage** function.|
24e41f4b71Sopenharmony_ci| OH_NativeImage_Destroy (OH_NativeImage \*\*image)            | Destroys an **OH_NativeImage** instance created by calling **OH_NativeImage_Create**. After the instance is destroyed, the pointer to it is assigned **NULL**.|
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ciFor details about the APIs, see [native_image](../reference/apis-arkgraphics2d/_o_h___native_image.md).
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci## How to Develop
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ciThe following steps describe how to use the native Image APIs to create an **OH_NativeImage** instance as the consumer and update the data to a OpenGL external texture.
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ci**Adding Dynamic Link Libraries**
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ciAdd the following libraries to **CMakeLists.txt**:
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci```txt
37e41f4b71Sopenharmony_cilibEGL.so
38e41f4b71Sopenharmony_cilibGLESv3.so
39e41f4b71Sopenharmony_cilibnative_image.so
40e41f4b71Sopenharmony_cilibnative_window.so
41e41f4b71Sopenharmony_cilibnative_buffer.so
42e41f4b71Sopenharmony_ci```
43e41f4b71Sopenharmony_ci
44e41f4b71Sopenharmony_ci**Including Header Files**
45e41f4b71Sopenharmony_ci
46e41f4b71Sopenharmony_ci```c++
47e41f4b71Sopenharmony_ci#include <iostream>
48e41f4b71Sopenharmony_ci#include <string>
49e41f4b71Sopenharmony_ci#include <EGL/egl.h>
50e41f4b71Sopenharmony_ci#include <EGL/eglext.h>
51e41f4b71Sopenharmony_ci#include <GLES3/gl3.h>
52e41f4b71Sopenharmony_ci#include <GLES2/gl2ext.h>
53e41f4b71Sopenharmony_ci#include <sys/mman.h>
54e41f4b71Sopenharmony_ci#include <native_image/native_image.h>
55e41f4b71Sopenharmony_ci#include <native_window/external_window.h>
56e41f4b71Sopenharmony_ci#include <native_buffer/native_buffer.h>
57e41f4b71Sopenharmony_ci```
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci1. Initialize the EGL environment.
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci   Refer to the code snippet below. For details about how to use the **\<XComponent>**, see [XComponent Development](../ui/napi-xcomponent-guidelines.md).
62e41f4b71Sopenharmony_ci   ```c++   
63e41f4b71Sopenharmony_ci   using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC;
64e41f4b71Sopenharmony_ci   constexpr const char *EGL_EXT_PLATFORM_WAYLAND = "EGL_EXT_platform_wayland";
65e41f4b71Sopenharmony_ci   constexpr const char *EGL_KHR_PLATFORM_WAYLAND = "EGL_KHR_platform_wayland";
66e41f4b71Sopenharmony_ci   constexpr int32_t EGL_CONTEXT_CLIENT_VERSION_NUM = 2;
67e41f4b71Sopenharmony_ci   constexpr char CHARACTER_WHITESPACE = ' ';
68e41f4b71Sopenharmony_ci   constexpr const char *CHARACTER_STRING_WHITESPACE = " ";
69e41f4b71Sopenharmony_ci   constexpr const char *EGL_GET_PLATFORM_DISPLAY_EXT = "eglGetPlatformDisplayEXT";
70e41f4b71Sopenharmony_ci   EGLContext eglContext_ = EGL_NO_CONTEXT;
71e41f4b71Sopenharmony_ci   EGLDisplay eglDisplay_ = EGL_NO_DISPLAY;
72e41f4b71Sopenharmony_ci   static inline EGLConfig config_;
73e41f4b71Sopenharmony_ci   static inline EGLSurface eglSurface_;
74e41f4b71Sopenharmony_ci   // OHNativeWindow obtained from the <XComponent>.
75e41f4b71Sopenharmony_ci   OHNativeWindow *eglNativeWindow_;
76e41f4b71Sopenharmony_ci   
77e41f4b71Sopenharmony_ci   // Check the EGL extension.
78e41f4b71Sopenharmony_ci   static bool CheckEglExtension(const char *extensions, const char *extension) {
79e41f4b71Sopenharmony_ci       size_t extlen = strlen(extension);
80e41f4b71Sopenharmony_ci       const char *end = extensions + strlen(extensions);
81e41f4b71Sopenharmony_ci   
82e41f4b71Sopenharmony_ci       while (extensions < end) {
83e41f4b71Sopenharmony_ci           size_t n = 0;
84e41f4b71Sopenharmony_ci           if (*extensions == CHARACTER_WHITESPACE) {
85e41f4b71Sopenharmony_ci               extensions++;
86e41f4b71Sopenharmony_ci               continue;
87e41f4b71Sopenharmony_ci           }
88e41f4b71Sopenharmony_ci           n = strcspn(extensions, CHARACTER_STRING_WHITESPACE);
89e41f4b71Sopenharmony_ci           if (n == extlen && strncmp(extension, extensions, n) == 0) {
90e41f4b71Sopenharmony_ci               return true;
91e41f4b71Sopenharmony_ci           }
92e41f4b71Sopenharmony_ci           extensions += n;
93e41f4b71Sopenharmony_ci       }
94e41f4b71Sopenharmony_ci       return false;
95e41f4b71Sopenharmony_ci   }
96e41f4b71Sopenharmony_ci   
97e41f4b71Sopenharmony_ci   // Obtain the display.
98e41f4b71Sopenharmony_ci   static EGLDisplay GetPlatformEglDisplay(EGLenum platform, void *native_display, const EGLint *attrib_list) {
99e41f4b71Sopenharmony_ci       static GetPlatformDisplayExt eglGetPlatformDisplayExt = NULL;
100e41f4b71Sopenharmony_ci   
101e41f4b71Sopenharmony_ci       if (!eglGetPlatformDisplayExt) {
102e41f4b71Sopenharmony_ci           const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
103e41f4b71Sopenharmony_ci           if (extensions && (CheckEglExtension(extensions, EGL_EXT_PLATFORM_WAYLAND) ||
104e41f4b71Sopenharmony_ci                              CheckEglExtension(extensions, EGL_KHR_PLATFORM_WAYLAND))) {
105e41f4b71Sopenharmony_ci               eglGetPlatformDisplayExt = (GetPlatformDisplayExt)eglGetProcAddress(EGL_GET_PLATFORM_DISPLAY_EXT);
106e41f4b71Sopenharmony_ci           }
107e41f4b71Sopenharmony_ci       }
108e41f4b71Sopenharmony_ci   
109e41f4b71Sopenharmony_ci       if (eglGetPlatformDisplayExt) {
110e41f4b71Sopenharmony_ci           return eglGetPlatformDisplayExt(platform, native_display, attrib_list);
111e41f4b71Sopenharmony_ci       }
112e41f4b71Sopenharmony_ci   
113e41f4b71Sopenharmony_ci       return eglGetDisplay((EGLNativeDisplayType)native_display);
114e41f4b71Sopenharmony_ci   }
115e41f4b71Sopenharmony_ci   
116e41f4b71Sopenharmony_ci   static void InitEGLEnv() {
117e41f4b71Sopenharmony_ci       // Obtain the display.
118e41f4b71Sopenharmony_ci       eglDisplay_ = GetPlatformEglDisplay(EGL_PLATFORM_OHOS_KHR, EGL_DEFAULT_DISPLAY, NULL);
119e41f4b71Sopenharmony_ci       if (eglDisplay_ == EGL_NO_DISPLAY) {
120e41f4b71Sopenharmony_ci           std::cout << "Failed to create EGLDisplay gl errno : " << eglGetError() << std::endl;
121e41f4b71Sopenharmony_ci       }
122e41f4b71Sopenharmony_ci   
123e41f4b71Sopenharmony_ci       EGLint major, minor;
124e41f4b71Sopenharmony_ci       // Initialize the EGL display.
125e41f4b71Sopenharmony_ci       if (eglInitialize(eglDisplay_, &major, &minor) == EGL_FALSE) {
126e41f4b71Sopenharmony_ci           std::cout << "Failed to initialize EGLDisplay" << std::endl;
127e41f4b71Sopenharmony_ci       }
128e41f4b71Sopenharmony_ci   
129e41f4b71Sopenharmony_ci       // Bind the OpenGL ES API.
130e41f4b71Sopenharmony_ci       if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
131e41f4b71Sopenharmony_ci           std::cout << "Failed to bind OpenGL ES API" << std::endl;
132e41f4b71Sopenharmony_ci       }
133e41f4b71Sopenharmony_ci   
134e41f4b71Sopenharmony_ci       unsigned int glRet;
135e41f4b71Sopenharmony_ci       EGLint count;
136e41f4b71Sopenharmony_ci       EGLint config_attribs[] = {EGL_SURFACE_TYPE,
137e41f4b71Sopenharmony_ci                                  EGL_WINDOW_BIT,
138e41f4b71Sopenharmony_ci                                  EGL_RED_SIZE,
139e41f4b71Sopenharmony_ci                                  8,
140e41f4b71Sopenharmony_ci                                  EGL_GREEN_SIZE,
141e41f4b71Sopenharmony_ci                                  8,
142e41f4b71Sopenharmony_ci                                  EGL_BLUE_SIZE,
143e41f4b71Sopenharmony_ci                                  8,
144e41f4b71Sopenharmony_ci                                  EGL_ALPHA_SIZE,
145e41f4b71Sopenharmony_ci                                  8,
146e41f4b71Sopenharmony_ci                                  EGL_RENDERABLE_TYPE,
147e41f4b71Sopenharmony_ci                                  EGL_OPENGL_ES3_BIT,
148e41f4b71Sopenharmony_ci                                  EGL_NONE};
149e41f4b71Sopenharmony_ci   
150e41f4b71Sopenharmony_ci       // Obtain a valid system configuration.
151e41f4b71Sopenharmony_ci       glRet = eglChooseConfig(eglDisplay_, config_attribs, &config_, 1, &count);
152e41f4b71Sopenharmony_ci       if (!(glRet && static_cast<unsigned int>(count) >= 1)) {
153e41f4b71Sopenharmony_ci           std::cout << "Failed to eglChooseConfig" << std::endl;
154e41f4b71Sopenharmony_ci       }
155e41f4b71Sopenharmony_ci   
156e41f4b71Sopenharmony_ci       static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, EGL_CONTEXT_CLIENT_VERSION_NUM, EGL_NONE};
157e41f4b71Sopenharmony_ci   
158e41f4b71Sopenharmony_ci       // Create a context.
159e41f4b71Sopenharmony_ci       eglContext_ = eglCreateContext(eglDisplay_, config_, EGL_NO_CONTEXT, context_attribs);
160e41f4b71Sopenharmony_ci       if (eglContext_ == EGL_NO_CONTEXT) {
161e41f4b71Sopenharmony_ci           std::cout << "Failed to create egl context %{public}x, error:" << eglGetError() << std::endl;
162e41f4b71Sopenharmony_ci       }
163e41f4b71Sopenharmony_ci   
164e41f4b71Sopenharmony_ci       // Create an eglSurface.
165e41f4b71Sopenharmony_ci       eglSurface_ = eglCreateWindowSurface(eglDisplay_, config_, reinterpret_cast<EGLNativeWindowType>(eglNativeWindow_), context_attribs);
166e41f4b71Sopenharmony_ci       if (eglSurface_ == EGL_NO_SURFACE) {
167e41f4b71Sopenharmony_ci           std::cout << "Failed to create egl surface %{public}x, error:" << eglGetError() << std::endl;
168e41f4b71Sopenharmony_ci       }
169e41f4b71Sopenharmony_ci   
170e41f4b71Sopenharmony_ci       // Associate the context.
171e41f4b71Sopenharmony_ci       eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_);
172e41f4b71Sopenharmony_ci   
173e41f4b71Sopenharmony_ci       // The EGL environment initialization is complete.
174e41f4b71Sopenharmony_ci       std::cout << "Create EGL context successfully, version" << major << "." << minor << std::endl;
175e41f4b71Sopenharmony_ci   }
176e41f4b71Sopenharmony_ci   ```
177e41f4b71Sopenharmony_ci
178e41f4b71Sopenharmony_ci2. Create an **OH_NativeImage** instance.
179e41f4b71Sopenharmony_ci   
180e41f4b71Sopenharmony_ci   ```c++
181e41f4b71Sopenharmony_ci   // Create an OpenGL ES texture.
182e41f4b71Sopenharmony_ci   GLuint textureId;
183e41f4b71Sopenharmony_ci   glGenTextures(1, &textureId);
184e41f4b71Sopenharmony_ci   // Create an OH_NativeImage instance, which will be associated with an OpenGL ES texture.
185e41f4b71Sopenharmony_ci   OH_NativeImage* image = OH_NativeImage_Create(textureId, GL_TEXTURE_EXTERNAL_OES);
186e41f4b71Sopenharmony_ci   ```
187e41f4b71Sopenharmony_ci   
188e41f4b71Sopenharmony_ci3. Obtain the **OHNativeWindow** instance that functions as the producer.
189e41f4b71Sopenharmony_ci
190e41f4b71Sopenharmony_ci   ```c++
191e41f4b71Sopenharmony_ci   // Obtain an OHNativeWindow instance.
192e41f4b71Sopenharmony_ci   OHNativeWindow* nativeWindow = OH_NativeImage_AcquireNativeWindow(image);
193e41f4b71Sopenharmony_ci   ```
194e41f4b71Sopenharmony_ci
195e41f4b71Sopenharmony_ci4. Set the width and height of the **OHNativeWindow** instance.
196e41f4b71Sopenharmony_ci
197e41f4b71Sopenharmony_ci   ```c++
198e41f4b71Sopenharmony_ci   int code = SET_BUFFER_GEOMETRY;
199e41f4b71Sopenharmony_ci   int32_t width = 800;
200e41f4b71Sopenharmony_ci   int32_t height = 600;
201e41f4b71Sopenharmony_ci   int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow, code, width, height);
202e41f4b71Sopenharmony_ci   ```
203e41f4b71Sopenharmony_ci
204e41f4b71Sopenharmony_ci5. Write the produced content to an **OHNativeWindowBuffer** instance.
205e41f4b71Sopenharmony_ci
206e41f4b71Sopenharmony_ci   1. Obtain an **OHNativeWindowBuffer** instance from the **OHNativeWindow** instance.
207e41f4b71Sopenharmony_ci
208e41f4b71Sopenharmony_ci      ```c++
209e41f4b71Sopenharmony_ci      OHNativeWindowBuffer *buffer = nullptr;
210e41f4b71Sopenharmony_ci      int fenceFd;
211e41f4b71Sopenharmony_ci      // Obtain an OHNativeWindowBuffer instance by calling OH_NativeWindow_NativeWindowRequestBuffer.
212e41f4b71Sopenharmony_ci      OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &buffer, &fenceFd);
213e41f4b71Sopenharmony_ci       
214e41f4b71Sopenharmony_ci      BufferHandle *handle = OH_NativeWindow_GetBufferHandleFromNative(buffer);
215e41f4b71Sopenharmony_ci      ```
216e41f4b71Sopenharmony_ci
217e41f4b71Sopenharmony_ci   2. Write the produced content to the **OHNativeWindowBuffer** instance.
218e41f4b71Sopenharmony_ci
219e41f4b71Sopenharmony_ci      ```c++
220e41f4b71Sopenharmony_ci      // Use mmap() to obtain the memory virtual address of buffer handle.
221e41f4b71Sopenharmony_ci      void *mappedAddr = mmap(handle->virAddr, handle->size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd, 0);
222e41f4b71Sopenharmony_ci      if (mappedAddr == MAP_FAILED) {
223e41f4b71Sopenharmony_ci          // mmap failed
224e41f4b71Sopenharmony_ci      }
225e41f4b71Sopenharmony_ci      static uint32_t value = 0x00;
226e41f4b71Sopenharmony_ci      value++;
227e41f4b71Sopenharmony_ci      uint32_t *pixel = static_cast<uint32_t *>(mappedAddr);
228e41f4b71Sopenharmony_ci      for (uint32_t x = 0; x < width; x++) {
229e41f4b71Sopenharmony_ci          for (uint32_t y = 0; y < height; y++) {
230e41f4b71Sopenharmony_ci              *pixel++ = value;
231e41f4b71Sopenharmony_ci          }
232e41f4b71Sopenharmony_ci      }
233e41f4b71Sopenharmony_ci      // Unmap the memory when the memory is no longer required.
234e41f4b71Sopenharmony_ci      int result = munmap(mappedAddr, handle->size);
235e41f4b71Sopenharmony_ci      if (result == -1) {
236e41f4b71Sopenharmony_ci          // munmap failed
237e41f4b71Sopenharmony_ci      }
238e41f4b71Sopenharmony_ci      ```
239e41f4b71Sopenharmony_ci
240e41f4b71Sopenharmony_ci   3. Flush the **OHNativeWindowBuffer** to the **OHNativeWindow**.
241e41f4b71Sopenharmony_ci
242e41f4b71Sopenharmony_ci      ```c++
243e41f4b71Sopenharmony_ci      // Set the refresh region. If Rect in Region is a null pointer or rectNumber is 0, all contents in the NativeWindowBuffer are changed.
244e41f4b71Sopenharmony_ci      Region region{nullptr, 0};
245e41f4b71Sopenharmony_ci      // Flush the buffer to the consumer through OH_NativeWindow_NativeWindowFlushBuffer, for example, by displaying it on the screen.
246e41f4b71Sopenharmony_ci      OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, buffer, fenceFd, region);
247e41f4b71Sopenharmony_ci      ```
248e41f4b71Sopenharmony_ci
249e41f4b71Sopenharmony_ci   4. Destroy the **OHNativeWindow** instance when it is no longer needed.
250e41f4b71Sopenharmony_ci
251e41f4b71Sopenharmony_ci      ```c++
252e41f4b71Sopenharmony_ci      OH_NativeWindow_DestroyNativeWindow(nativeWindow);
253e41f4b71Sopenharmony_ci      ```
254e41f4b71Sopenharmony_ci
255e41f4b71Sopenharmony_ci6. Update the content to the OpenGL texture.
256e41f4b71Sopenharmony_ci
257e41f4b71Sopenharmony_ci   ```c++
258e41f4b71Sopenharmony_ci   // Update the content to the OpenGL texture.
259e41f4b71Sopenharmony_ci   ret = OH_NativeImage_UpdateSurfaceImage(image);
260e41f4b71Sopenharmony_ci   if (ret != 0) {
261e41f4b71Sopenharmony_ci       std::cout << "OH_NativeImage_UpdateSurfaceImage failed" << std::endl;
262e41f4b71Sopenharmony_ci   }
263e41f4b71Sopenharmony_ci   // Obtain the timestamp and transformation matrix of the texture image that recently called the **OH_NativeImage_UpdateSurfaceImage** function.
264e41f4b71Sopenharmony_ci   int64_t timeStamp = OH_NativeImage_GetTimestamp(image);
265e41f4b71Sopenharmony_ci   float matrix[16];
266e41f4b71Sopenharmony_ci   ret = OH_NativeImage_GetTransformMatrix(image, matrix);
267e41f4b71Sopenharmony_ci   if (ret != 0) {
268e41f4b71Sopenharmony_ci       std::cout << "OH_NativeImage_GetTransformMatrix failed" << std::endl;
269e41f4b71Sopenharmony_ci   }
270e41f4b71Sopenharmony_ci   
271e41f4b71Sopenharmony_ci   // Perform OpenGL post-processing on the texture, and then display the texture on the screen.
272e41f4b71Sopenharmony_ci   EGLBoolean eglRet = eglSwapBuffers(eglDisplay_, eglSurface_);
273e41f4b71Sopenharmony_ci   if (eglRet == EGL_FALSE) {
274e41f4b71Sopenharmony_ci       std::cout << "eglSwapBuffers failed" << std::endl;
275e41f4b71Sopenharmony_ci   }
276e41f4b71Sopenharmony_ci   ```
277e41f4b71Sopenharmony_ci
278e41f4b71Sopenharmony_ci7. Detach the **OH_NativeImage** from the current OpenGL texture and attach it to a new external texture.
279e41f4b71Sopenharmony_ci
280e41f4b71Sopenharmony_ci   ```c++
281e41f4b71Sopenharmony_ci   // Detach an OH_NativeImage instance from the current OpenGL ES context.
282e41f4b71Sopenharmony_ci   ret = OH_NativeImage_DetachContext(image);
283e41f4b71Sopenharmony_ci   if (ret != 0) {
284e41f4b71Sopenharmony_ci       std::cout << "OH_NativeImage_DetachContext failed" << std::endl;
285e41f4b71Sopenharmony_ci   }
286e41f4b71Sopenharmony_ci   // Attach an OH_NativeImage instance to the current OpenGL ES context. The OpenGL ES texture will be bound to an GL_TEXTURE_EXTERNAL_OES instance and updated through the OH_NativeImage instance.
287e41f4b71Sopenharmony_ci   GLuint textureId2;
288e41f4b71Sopenharmony_ci   glGenTextures(1, &textureId2);
289e41f4b71Sopenharmony_ci   ret = OH_NativeImage_AttachContext(image, textureId2);
290e41f4b71Sopenharmony_ci   ```
291e41f4b71Sopenharmony_ci
292e41f4b71Sopenharmony_ci8. Destroy the **OH_NativeImage** instance when it is no longer needed.
293e41f4b71Sopenharmony_ci
294e41f4b71Sopenharmony_ci   ```c++
295e41f4b71Sopenharmony_ci   // Destroy the OH_NativeImage instance.
296e41f4b71Sopenharmony_ci   OH_NativeImage_Destroy(&image);
297e41f4b71Sopenharmony_ci   ```
298e41f4b71Sopenharmony_ci
299