• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "NativeImageAdaptor.h"
17 #include "logger_common.h"
18 #include "cstdint"
19 
20 namespace NativeWindowSample {
21 using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC;
22 constexpr const char *EGL_EXT_PLATFORM_WAYLAND = "EGL_EXT_platform_wayland";
23 constexpr const char *EGL_KHR_PLATFORM_WAYLAND = "EGL_KHR_platform_wayland";
24 constexpr int32_t EGL_CONTEXT_CLIENT_VERSION_NUM = 2;
25 constexpr char CHARACTER_WHITESPACE = ' ';
26 constexpr const char *CHARACTER_STRING_WHITESPACE = " ";
27 constexpr const char *EGL_GET_PLATFORM_DISPLAY_EXT = "eglGetPlatformDisplayEXT";
28 constexpr int32_t NATIVE_CACHE_BUFFER = 3;
29 constexpr int32_t GSERROR_OK = 0;
30 constexpr int32_t GSERROR_FAILD = 1;
GetInstance()31 NativeImageAdaptor *NativeImageAdaptor::GetInstance()
32 {
33     static NativeImageAdaptor imageAdaptor;
34     return &imageAdaptor;
35 };
36 
CheckEglExtension(const char * eglExtensions,const char * eglExtension)37 bool NativeImageAdaptor::CheckEglExtension(const char *eglExtensions, const char *eglExtension)
38 {
39     // Check egl extension
40     size_t extLenth = strlen(eglExtension);
41     const char *endPos = eglExtensions + strlen(eglExtensions);
42 
43     while (eglExtensions < endPos) {
44         size_t len = 0;
45         if (*eglExtensions == CHARACTER_WHITESPACE) {
46             eglExtensions++;
47             continue;
48         }
49         len = strcspn(eglExtensions, CHARACTER_STRING_WHITESPACE);
50         if (len == extLenth && strncmp(eglExtension, eglExtensions, len) == 0) {
51             return true;
52         }
53         eglExtensions += len;
54     }
55     return false;
56 }
57 
GetPlatformEglDisplay(EGLenum platform,void * native_display,const EGLint * attrib_list)58 EGLDisplay NativeImageAdaptor::GetPlatformEglDisplay(EGLenum platform, void *native_display, const EGLint *attrib_list)
59 {
60     static GetPlatformDisplayExt eglGetPlatformDisplayExt = NULL;
61     if (!eglGetPlatformDisplayExt) {
62         const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
63         if (extensions && (CheckEglExtension(extensions, EGL_EXT_PLATFORM_WAYLAND) ||
64                            CheckEglExtension(extensions, EGL_KHR_PLATFORM_WAYLAND))) {
65             eglGetPlatformDisplayExt = (GetPlatformDisplayExt)eglGetProcAddress(EGL_GET_PLATFORM_DISPLAY_EXT);
66         }
67     }
68 
69     if (eglGetPlatformDisplayExt) {
70         return eglGetPlatformDisplayExt(platform, native_display, attrib_list);
71     }
72 
73     return eglGetDisplay((EGLNativeDisplayType)native_display);
74 }
75 
InitEGLEnv()76 void NativeImageAdaptor::InitEGLEnv()
77 {
78     LOGD("NativeImageAdaptor::InitEGLEnv begin");
79     // Obtain the current display device
80     eglDisplay_ = GetPlatformEglDisplay(EGL_PLATFORM_OHOS_KHR, EGL_DEFAULT_DISPLAY, NULL);
81     if (eglDisplay_ == EGL_NO_DISPLAY) {
82         LOGE("NativeImageAdaptor::InitEGLEnv fail");
83     }
84 
85     EGLint major, minor;
86     // Initialize EGLDisplay
87     if (eglInitialize(eglDisplay_, &major, &minor) == EGL_FALSE) {
88         LOGE("NativeImageAdaptor::eglInitialize fail");
89     }
90     // The API for binding graphic drawing is OpenGLES
91     if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
92         LOGE("eglBindAPI fail");
93     }
94     unsigned int ret;
95     EGLint count;
96     EGLint config_attribs[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE,
97                                8, EGL_ALPHA_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, EGL_NONE};
98 
99     // Obtain a valid system configuration information
100     ret = eglChooseConfig(eglDisplay_, config_attribs, &config_, 1, &count);
101     if (!(ret && static_cast<unsigned int>(count) >= 1)) {
102         LOGE("eglChooseConfig fail");
103     }
104     static const EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, EGL_CONTEXT_CLIENT_VERSION_NUM, EGL_NONE};
105     eglContext_ = eglCreateContext(eglDisplay_, config_, EGL_NO_CONTEXT, context_attribs);
106     if (eglContext_ == EGL_NO_CONTEXT) {
107         LOGE("eglCreateContext fail");
108     }
109     // Associated Context
110     eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext_);
111     LOGD("Create EGL context successfully");
112 }
113 
Export(napi_env env,napi_value exports)114 bool NativeImageAdaptor::Export(napi_env env, napi_value exports)
115 {
116     napi_property_descriptor desc[] = {
117         {"GetAvailableCount", nullptr, NativeImageAdaptor::GetAvailableCount, nullptr, nullptr, nullptr, napi_default,
118          nullptr},
119         {"GetBufferQueueSize", nullptr, NativeImageAdaptor::NapiOnGetBufferQueueSize, nullptr, nullptr, nullptr,
120          napi_default, nullptr},
121         {"GetAttachBufferCount", nullptr, NativeImageAdaptor::NapiOnGetAttachBufferCount, nullptr, nullptr, nullptr,
122          napi_default, nullptr},
123         {"GetCacheBufferCount", nullptr, NativeImageAdaptor::NapiOnGetCacheBufferCount, nullptr, nullptr, nullptr,
124          napi_default, nullptr},
125         {"ProduceBuffer", nullptr, NativeImageAdaptor::NapiOnProduceBuffer, nullptr, nullptr, nullptr, napi_default,
126          nullptr},
127         {"ConsumerBuffer", nullptr, NativeImageAdaptor::NapiOnConsumerBuffer, nullptr, nullptr, nullptr, napi_default,
128          nullptr},
129         {"AttachBuffer", nullptr, NativeImageAdaptor::NapiOnAttachBuffer, nullptr, nullptr, nullptr, napi_default,
130          nullptr},
131         {"DettachBuffer", nullptr, NativeImageAdaptor::NapiOnDettachBuffer, nullptr, nullptr, nullptr, napi_default,
132          nullptr},
133         {"ChangeIsAutoConsumer", nullptr, NativeImageAdaptor::NapiOnChangeIsAutoConsumer, nullptr, nullptr, nullptr,
134          napi_default, nullptr},
135     };
136     napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
137 
138     eglContext_ = EGL_NO_CONTEXT;
139     eglDisplay_ = EGL_NO_DISPLAY;
140     availableBufferCount_ = 0;
141     // Creating OpenGL textures
142     InitEGLEnv();
143     bool ret = InitNativeWindow();
144     ret = InitNativeWindowCache() && ret;
145 
146     return ret;
147 }
148 
InitNativeWindow()149 bool NativeImageAdaptor::InitNativeWindow()
150 {
151     GLuint textureId;
152     glGenTextures(1, &textureId);
153     // Create a NativeImage instance and associate it with OpenGL textures
154     image_ = OH_NativeImage_Create(textureId, GL_TEXTURE_2D);
155     // Obtain Producer NativeWindow
156     nativeWindow_ = OH_NativeImage_AcquireNativeWindow(image_);
157 
158     int code = SET_BUFFER_GEOMETRY;
159     width_ = 0x100;
160     height_ = 0x100;
161     int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, width_, height_);
162     if (ret != 0) {
163         LOGE("NativeImageAdaptor OH_NativeWindow_NativeWindowHandleOpt fail");
164     }
165 
166     code = SET_USAGE;
167     int32_t usage = NATIVEBUFFER_USAGE_CPU_READ | NATIVEBUFFER_USAGE_CPU_WRITE | NATIVEBUFFER_USAGE_MEM_DMA;
168     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, usage);
169 
170     OH_OnFrameAvailableListener listener;
171     listener.context = static_cast<void*>(image_);
172     listener.onFrameAvailable = NativeImageAdaptor::OnFrameAvailable;
173     ret = OH_NativeImage_SetOnFrameAvailableListener(image_, listener);
174 
175     uint64_t surfaceId;
176     ret = OH_NativeImage_GetSurfaceId(image_, &surfaceId);
177     if (ret != 0) {
178         LOGE("OH_NativeImage_GetSurfaceId fail");
179         return false;
180     }
181 
182     OHNativeWindow *nativeWindow = nullptr;
183     ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(surfaceId, &nativeWindow);
184     if (ret != 0 || nativeWindow != nativeWindow_) {
185         LOGE("OH_NativeWindow_CreateNativeWindowFromSurfaceId fail");
186         return false;
187     }
188 
189     uint64_t surfaceIdTmp = 0;
190     ret = OH_NativeWindow_GetSurfaceId(nativeWindow, &surfaceIdTmp);
191     if (ret != 0 || surfaceIdTmp != surfaceId) {
192         LOGE("OH_NativeWindow_GetSurfaceId fail");
193     }
194     OH_NativeWindow_DestroyNativeWindow(nativeWindow);
195 
196     return true;
197 }
198 
InitNativeWindowCache()199 bool NativeImageAdaptor::InitNativeWindowCache()
200 {
201     GLuint textureId;
202     glGenTextures(1, &textureId);
203     imageCache_ = OH_NativeImage_Create(textureId, GL_TEXTURE_2D);
204     nativeWindowCache_ = OH_NativeImage_AcquireNativeWindow(imageCache_);
205 
206     int code = SET_BUFFER_GEOMETRY;
207     width_ = 0x100;
208     height_ = 0x100;
209     int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindowCache_, code, width_, height_);
210     if (ret != 0) {
211         LOGE("NativeImageAdaptor OH_NativeWindow_NativeWindowHandleOpt fail");
212     }
213 
214     code = SET_USAGE;
215     int32_t usage = NATIVEBUFFER_USAGE_CPU_READ | NATIVEBUFFER_USAGE_CPU_WRITE | NATIVEBUFFER_USAGE_MEM_DMA;
216     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindowCache_, code, usage);
217 
218     for (int i = 0; i < NATIVE_CACHE_BUFFER; i++) {
219         ProduceBuffer(0x00, nativeWindowCache_);
220     }
221 
222     return true;
223 }
224 
NapiOnAttachBuffer(napi_env env,napi_callback_info info)225 napi_value NativeImageAdaptor::NapiOnAttachBuffer(napi_env env, napi_callback_info info)
226 {
227     NativeImageAdaptor::GetInstance()->AttachBuffer();
228     return nullptr;
229 }
230 
NapiOnDettachBuffer(napi_env env,napi_callback_info info)231 napi_value NativeImageAdaptor::NapiOnDettachBuffer(napi_env env, napi_callback_info info)
232 {
233     NativeImageAdaptor::GetInstance()->DettachBuffer();
234     return nullptr;
235 }
236 
AttachBuffer()237 void NativeImageAdaptor::AttachBuffer()
238 {
239     if (bufferCache_.size() == 0) {
240         LOGE("bufferCache_ empty");
241         return;
242     }
243 
244     NativeWindowBuffer* buffer = bufferCache_.front();
245     int ret = OH_NativeWindow_NativeWindowAttachBuffer(nativeWindowCache_, buffer);
246     if (ret != 0) {
247         LOGE("OH_NativeWindow_NativeWindowAttachBuffer fail");
248         return;
249     }
250 
251     bufferAttached_.push(buffer);
252     bufferCache_.pop();
253 }
254 
DettachBuffer()255 void NativeImageAdaptor::DettachBuffer()
256 {
257     if (bufferAttached_.size() == 0) {
258         LOGE("bufferAttached_ empty");
259         return;
260     }
261 
262     NativeWindowBuffer *buffer = bufferAttached_.front();
263     int ret = OH_NativeWindow_NativeWindowDetachBuffer(nativeWindowCache_, buffer);
264     if (ret != 0) {
265         LOGE("OH_NativeWindow_NativeWindowDetachBuffer fail");
266         return;
267     }
268 
269     bufferCache_.push(buffer);
270     bufferAttached_.pop();
271 }
272 
SetConfigAndGetValue()273 void NativeImageAdaptor::SetConfigAndGetValue()
274 {
275     static int32_t g_cnt = 0;
276     int32_t code = SET_FORMAT;
277     int32_t value = NATIVEBUFFER_PIXEL_FMT_CLUT1;
278     int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, value);
279     if (ret != 0) {
280         LOGE("SetConfigAndGetValue SET_FORMAT fail");
281     }
282     value = 0;
283     code = GET_FORMAT;
284     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &value);
285     if (ret != 0 || value != NATIVEBUFFER_PIXEL_FMT_CLUT1) {
286         LOGE("SetConfigAndGetValue GET_FORMAT fail");
287     }
288     code = SET_TRANSFORM;
289     value = NATIVEBUFFER_ROTATE_180;
290     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, value);
291     if (ret != 0) {
292         LOGE("SetConfigAndGetValue SET_TRANSFORM fail");
293     }
294     code = GET_TRANSFORM;
295     value = 0;
296     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &value);
297     if (ret != 0 || value != NATIVEBUFFER_ROTATE_180) {
298         LOGE("SetConfigAndGetValue GET_TRANSFORM fail");
299     }
300     code = SET_COLOR_GAMUT;
301     value = NATIVEBUFFER_COLOR_GAMUT_STANDARD_BT709;
302     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, value);
303     if (ret != 0) {
304         LOGE("SetConfigAndGetValue SET_COLOR_GAMUT fail");
305     }
306     code = GET_COLOR_GAMUT;
307     value = 0;
308     ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &value);
309     if (ret != 0 || value != NATIVEBUFFER_COLOR_GAMUT_STANDARD_BT709) {
310         LOGE("SetConfigAndGetValue GET_COLOR_GAMUT fail");
311     }
312     code = SET_FORMAT;
313     if (g_cnt % 2 == 0) {  // 2 : 每次执行使用不同的format类型
314         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, NATIVEBUFFER_PIXEL_FMT_RGBA_8888);
315     } else {
316         OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, NATIVEBUFFER_PIXEL_FMT_YCBCR_420_SP);
317     }
318     code = SET_TRANSFORM;
319     OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, NATIVEBUFFER_ROTATE_NONE);
320     code = SET_COLOR_GAMUT;
321     OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, NATIVEBUFFER_COLOR_GAMUT_SRGB);
322     g_cnt++;
323 }
324 
GetBufferMapPlanes(NativeWindowBuffer * buffer)325 void NativeImageAdaptor::GetBufferMapPlanes(NativeWindowBuffer *buffer)
326 {
327     void *virAddr = nullptr;
328     OH_NativeBuffer_Planes outPlanes;
329     OH_NativeBuffer *nativeBuffer = nullptr;
330 
331     int32_t ret = OH_NativeBuffer_FromNativeWindowBuffer(buffer, &nativeBuffer);
332     if (ret != 0) {
333         LOGE("OH_NativeBuffer_FromNativeWindowBuffer fail");
334         return;
335     }
336     ret = OH_NativeBuffer_MapPlanes(nativeBuffer, &virAddr, &outPlanes);
337     if (ret != 0) {
338         LOGE("OH_NativeBuffer_MapPlanes fail");
339         return;
340     }
341     LOGD("Get planeCount: %{public}d", outPlanes.planeCount);
342     for (int32_t i = 0; i < outPlanes.planeCount; i++) {
343         LOGD("Get offset: %{public}llu rowStride: %{public}d columnStride: %{public}d", outPlanes.planes[i].offset,
344              outPlanes.planes[i].rowStride, outPlanes.planes[i].columnStride);
345     }
346 }
347 
ProduceBuffer(uint32_t value,OHNativeWindow * InNativeWindow)348 int32_t NativeImageAdaptor::ProduceBuffer(uint32_t value, OHNativeWindow *InNativeWindow)
349 {
350     if (InNativeWindow == nativeWindow_) {
351         SetConfigAndGetValue();
352     }
353 
354     NativeWindowBuffer *buffer = nullptr;
355     int fenceFd = -1;
356     int ret = OH_NativeWindow_NativeWindowRequestBuffer(InNativeWindow, &buffer, &fenceFd);
357     if (ret != 0) {
358         LOGE("OH_NativeWindow_NativeWindowRequestBuffer fail");
359         return GSERROR_FAILD;
360     }
361     GetBufferMapPlanes(buffer);
362 
363     if (InNativeWindow == nativeWindowCache_) {
364         OH_NativeWindow_NativeWindowDetachBuffer(nativeWindowCache_, buffer);
365         bufferCache_.push(buffer);
366         return GSERROR_OK;
367     }
368     int32_t code = GET_FORMAT;
369     int32_t formatType = NATIVEBUFFER_PIXEL_FMT_CLUT1;
370     OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &formatType);
371 
372     BufferHandle *handle = OH_NativeWindow_GetBufferHandleFromNative(buffer);
373     // Obtain the memory virtual address of bufferHandle using the system mmap interface
374     void *mappedAddr = mmap(handle->virAddr, handle->size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd, 0);
375     if (formatType == NATIVEBUFFER_PIXEL_FMT_RGBA_8888) {
376         uint32_t *pixel = static_cast<uint32_t *>(mappedAddr);
377         for (uint32_t x = 0; x < width_; x++) {
378             for (uint32_t y = 0; y < height_; y++) {
379                 *pixel++ = value;
380             }
381         }
382     }
383 
384     // Remember to remove memory mapping after using memory
385     int result = munmap(mappedAddr, handle->size);
386     if (result == -1) {
387         LOGE("munmap fail");
388     }
389 
390     struct Region *region = new Region();
391     struct Region::Rect *rect = new Region::Rect();
392     rect->x = 0x100;
393     rect->y = 0x100;
394     rect->w = 0x100;
395     rect->h = 0x100;
396     region->rects = rect;
397     ret = OH_NativeWindow_NativeWindowFlushBuffer(InNativeWindow, buffer, fenceFd, *region);
398     if (ret != 0) {
399         LOGE("OH_NativeWindow_NativeWindowFlushBuffer fail");
400         GSERROR_FAILD;
401     }
402 
403     delete region;
404     return GSERROR_OK;
405 }
406 
ConsumerBuffer(uint32_t value,OHNativeWindow * InNativeWindow)407 int32_t NativeImageAdaptor::ConsumerBuffer(uint32_t value, OHNativeWindow *InNativeWindow)
408 {
409     std::lock_guard<std::mutex> lockGuard(opMutex_);
410     NativeWindowBuffer *buffer = nullptr;
411     int fenceFd = -1;
412     int ret = OH_NativeImage_AcquireNativeWindowBuffer(image_, &buffer, &fenceFd);
413     if (ret != 0) {
414         LOGE("OH_NativeImage_AcquireNativeWindowBuffer fail, ret:%{public}d", ret);
415         return GSERROR_FAILD;
416     }
417     ret = OH_NativeImage_ReleaseNativeWindowBuffer(image_, buffer, fenceFd);
418     if (ret != 0) {
419         LOGE("OH_NativeImage_ReleaseNativeWindowBuffer fail, ret:%{public}d", ret);
420         return GSERROR_FAILD;
421     }
422     availableBufferCount_--;
423     return GSERROR_OK;
424 }
425 
OnFrameAvailable(void * context)426 void NativeImageAdaptor::OnFrameAvailable(void *context)
427 {
428     NativeImageAdaptor::GetInstance()->DealCallback(context);
429     return;
430 }
431 
DealCallback(void * context)432 void NativeImageAdaptor::DealCallback(void *context)
433 {
434     std::lock_guard<std::mutex> lockGuard(opMutex_);
435     LOGD("NativeImageAdaptor success OnFrameAvailable, %{public}d", availableBufferCount_);
436     if (isAutoConsumer_) {
437         int32_t ret = OH_NativeImage_UpdateSurfaceImage(image_);
438         if (ret != 0) {
439             LOGE("OH_NativeImage_UpdateSurfaceImage fail");
440         }
441     } else {
442         availableBufferCount_++;
443     }
444     return;
445 }
446 
GetCount()447 int32_t NativeImageAdaptor::GetCount()
448 {
449     std::lock_guard<std::mutex> lockGuard(opMutex_);
450     return availableBufferCount_;
451 }
452 
GetAttachBufferCount()453 int32_t NativeImageAdaptor::GetAttachBufferCount()
454 {
455     return bufferAttached_.size();
456 }
457 
GetBufferQueueSize()458 int32_t NativeImageAdaptor::GetBufferQueueSize()
459 {
460     int code = GET_BUFFERQUEUE_SIZE;
461     int bufferQueueSize = 0;
462     int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &bufferQueueSize);
463     LOGD("NativeImageAdaptor success GetAttachBufferCount, %{public}d", bufferQueueSize);
464     return bufferQueueSize;
465 }
466 
GetCacheBufferCount()467 int32_t NativeImageAdaptor::GetCacheBufferCount()
468 {
469     return bufferCache_.size();
470 }
471 
ChangeIsAutoConsumer()472 bool NativeImageAdaptor::ChangeIsAutoConsumer()
473 {
474     std::lock_guard<std::mutex> lockGuard(opMutex_);
475     isAutoConsumer_ = !isAutoConsumer_;
476     return isAutoConsumer_;
477 }
478 
GetAvailableCount(napi_env env,napi_callback_info info)479 napi_value NativeImageAdaptor::GetAvailableCount(napi_env env, napi_callback_info info)
480 {
481     napi_value val = nullptr;
482     int32_t count = NativeImageAdaptor::GetInstance()->GetCount();
483     (void)napi_create_int32(env, count, &val);
484     return val;
485 }
486 
NapiOnGetBufferQueueSize(napi_env env,napi_callback_info info)487 napi_value NativeImageAdaptor::NapiOnGetBufferQueueSize(napi_env env, napi_callback_info info)
488 {
489     napi_value val = nullptr;
490     int32_t count = NativeImageAdaptor::GetInstance()->GetBufferQueueSize();
491     (void)napi_create_int32(env, count, &val);
492     return val;
493 }
494 
NapiOnGetAttachBufferCount(napi_env env,napi_callback_info info)495 napi_value NativeImageAdaptor::NapiOnGetAttachBufferCount(napi_env env, napi_callback_info info)
496 {
497     napi_value val = nullptr;
498     int32_t count = NativeImageAdaptor::GetInstance()->GetAttachBufferCount();
499     (void)napi_create_int32(env, count, &val);
500     return val;
501 }
502 
NapiOnGetCacheBufferCount(napi_env env,napi_callback_info info)503 napi_value NativeImageAdaptor::NapiOnGetCacheBufferCount(napi_env env, napi_callback_info info)
504 {
505     napi_value val = nullptr;
506     int32_t count = NativeImageAdaptor::GetInstance()->GetCacheBufferCount();
507     (void)napi_create_int32(env, count, &val);
508     return val;
509 }
510 
NapiOnChangeIsAutoConsumer(napi_env env,napi_callback_info info)511 napi_value NativeImageAdaptor::NapiOnChangeIsAutoConsumer(napi_env env, napi_callback_info info)
512 {
513     napi_value val = nullptr;
514     bool isAutoConsumer = NativeImageAdaptor::GetInstance()->ChangeIsAutoConsumer();
515     (void)napi_get_boolean(env, isAutoConsumer, &val);
516     return val;
517 }
518 
NapiOnProduceBuffer(napi_env env,napi_callback_info info)519 napi_value NativeImageAdaptor::NapiOnProduceBuffer(napi_env env, napi_callback_info info)
520 {
521     napi_value val = nullptr;
522     int32_t ret = NativeImageAdaptor::GetInstance()->
523         ProduceBuffer(0x00, NativeImageAdaptor::GetInstance()->nativeWindow_);
524     (void)napi_create_int32(env, ret, &val);
525     return val;
526 }
527 
NapiOnConsumerBuffer(napi_env env,napi_callback_info info)528 napi_value NativeImageAdaptor::NapiOnConsumerBuffer(napi_env env, napi_callback_info info)
529 {
530     napi_value val = nullptr;
531     int32_t ret = NativeImageAdaptor::GetInstance()->
532         ConsumerBuffer(0x00, NativeImageAdaptor::GetInstance()->nativeWindow_);
533     (void)napi_create_int32(env, ret, &val);
534     return val;
535 }
536 
~NativeImageAdaptor()537 NativeImageAdaptor::~NativeImageAdaptor()
538 {
539     OH_NativeImage_UnsetOnFrameAvailableListener(image_);
540     OH_NativeWindow_DestroyNativeWindow(nativeWindow_);
541     OH_NativeImage_Destroy(&image_);
542 }
543 }