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 width_ = 0x100;
152 height_ = 0x100;
153 GLuint textureId;
154 glGenTextures(1, &textureId);
155 // Create a NativeImage instance and associate it with OpenGL textures
156 image_ = OH_NativeImage_Create(textureId, GL_TEXTURE_2D);
157
158 int32_t ret = OH_ConsumerSurface_SetDefaultSize(image_, width_, height_);
159 if (ret != 0) {
160 LOGE("NativeImageAdaptor OH_ConsumerSurface_SetDefaultSize fail");
161 }
162
163 uint64_t defaultUsage = NATIVEBUFFER_USAGE_CPU_READ |
164 NATIVEBUFFER_USAGE_CPU_WRITE |
165 NATIVEBUFFER_USAGE_MEM_DMA |
166 1ULL<<50;
167 ret = OH_ConsumerSurface_SetDefaultUsage(image_, defaultUsage);
168 if (ret != 0) {
169 LOGE("NativeImageAdaptor OH_ConsumerSurface_SetDefaultUsage fail");
170 }
171
172 // Obtain Producer NativeWindow
173 nativeWindow_ = OH_NativeImage_AcquireNativeWindow(image_);
174 if (nativeWindow_ == nullptr) {
175 LOGE("NativeImageAdaptor OH_NativeImage_AcquireNativeWindow fail");
176 }
177 OH_OnFrameAvailableListener listener;
178 listener.context = static_cast<void*>(image_);
179 listener.onFrameAvailable = NativeImageAdaptor::OnFrameAvailable;
180 ret = OH_NativeImage_SetOnFrameAvailableListener(image_, listener);
181
182 uint64_t surfaceId;
183 ret = OH_NativeImage_GetSurfaceId(image_, &surfaceId);
184 if (ret != 0) {
185 LOGE("OH_NativeImage_GetSurfaceId fail");
186 return false;
187 }
188
189 OHNativeWindow *nativeWindow = nullptr;
190 ret = OH_NativeWindow_CreateNativeWindowFromSurfaceId(surfaceId, &nativeWindow);
191 if (ret != 0 || nativeWindow != nativeWindow_) {
192 LOGE("OH_NativeWindow_CreateNativeWindowFromSurfaceId fail");
193 return false;
194 }
195
196 uint64_t surfaceIdTmp = 0;
197 ret = OH_NativeWindow_GetSurfaceId(nativeWindow, &surfaceIdTmp);
198 if (ret != 0 || surfaceIdTmp != surfaceId) {
199 LOGE("OH_NativeWindow_GetSurfaceId fail");
200 }
201 OH_NativeWindow_DestroyNativeWindow(nativeWindow);
202
203 return true;
204 }
205
InitNativeWindowCache()206 bool NativeImageAdaptor::InitNativeWindowCache()
207 {
208 GLuint textureId;
209 glGenTextures(1, &textureId);
210 imageCache_ = OH_NativeImage_Create(textureId, GL_TEXTURE_2D);
211 nativeWindowCache_ = OH_NativeImage_AcquireNativeWindow(imageCache_);
212
213 int code = SET_BUFFER_GEOMETRY;
214 width_ = 0x100;
215 height_ = 0x100;
216 int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindowCache_, code, width_, height_);
217 if (ret != 0) {
218 LOGE("NativeImageAdaptor OH_NativeWindow_NativeWindowHandleOpt fail");
219 }
220
221 code = SET_USAGE;
222 int32_t usage = NATIVEBUFFER_USAGE_CPU_READ | NATIVEBUFFER_USAGE_CPU_WRITE | NATIVEBUFFER_USAGE_MEM_DMA;
223 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindowCache_, code, usage);
224
225 for (int i = 0; i < NATIVE_CACHE_BUFFER; i++) {
226 ProduceBuffer(0x00, nativeWindowCache_);
227 }
228
229 return true;
230 }
231
NapiOnAttachBuffer(napi_env env,napi_callback_info info)232 napi_value NativeImageAdaptor::NapiOnAttachBuffer(napi_env env, napi_callback_info info)
233 {
234 NativeImageAdaptor::GetInstance()->AttachBuffer();
235 return nullptr;
236 }
237
NapiOnDettachBuffer(napi_env env,napi_callback_info info)238 napi_value NativeImageAdaptor::NapiOnDettachBuffer(napi_env env, napi_callback_info info)
239 {
240 NativeImageAdaptor::GetInstance()->DettachBuffer();
241 return nullptr;
242 }
243
AttachBuffer()244 void NativeImageAdaptor::AttachBuffer()
245 {
246 if (bufferCache_.size() == 0) {
247 LOGE("bufferCache_ empty");
248 return;
249 }
250
251 NativeWindowBuffer* buffer = bufferCache_.front();
252 int ret = OH_NativeWindow_NativeWindowAttachBuffer(nativeWindowCache_, buffer);
253 if (ret != 0) {
254 LOGE("OH_NativeWindow_NativeWindowAttachBuffer fail");
255 return;
256 }
257
258 bufferAttached_.push(buffer);
259 bufferCache_.pop();
260 }
261
DettachBuffer()262 void NativeImageAdaptor::DettachBuffer()
263 {
264 if (bufferAttached_.size() == 0) {
265 LOGE("bufferAttached_ empty");
266 return;
267 }
268
269 NativeWindowBuffer *buffer = bufferAttached_.front();
270 int ret = OH_NativeWindow_NativeWindowDetachBuffer(nativeWindowCache_, buffer);
271 if (ret != 0) {
272 LOGE("OH_NativeWindow_NativeWindowDetachBuffer fail");
273 return;
274 }
275
276 bufferCache_.push(buffer);
277 bufferAttached_.pop();
278 }
279
SetConfigAndGetValue()280 void NativeImageAdaptor::SetConfigAndGetValue()
281 {
282 static int32_t g_cnt = 0;
283 int32_t code = SET_FORMAT;
284 int32_t value = NATIVEBUFFER_PIXEL_FMT_CLUT1;
285 int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, value);
286 if (ret != 0) {
287 LOGE("SetConfigAndGetValue SET_FORMAT fail");
288 }
289 value = 0;
290 code = GET_FORMAT;
291 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &value);
292 if (ret != 0 || value != NATIVEBUFFER_PIXEL_FMT_CLUT1) {
293 LOGE("SetConfigAndGetValue GET_FORMAT fail");
294 }
295 code = SET_TRANSFORM;
296 value = NATIVEBUFFER_ROTATE_180;
297 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, value);
298 if (ret != 0) {
299 LOGE("SetConfigAndGetValue SET_TRANSFORM fail");
300 }
301 code = GET_TRANSFORM;
302 value = 0;
303 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &value);
304 if (ret != 0 || value != NATIVEBUFFER_ROTATE_180) {
305 LOGE("SetConfigAndGetValue GET_TRANSFORM fail");
306 }
307 code = SET_COLOR_GAMUT;
308 value = NATIVEBUFFER_COLOR_GAMUT_STANDARD_BT709;
309 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, value);
310 if (ret != 0) {
311 LOGE("SetConfigAndGetValue SET_COLOR_GAMUT fail");
312 }
313 code = GET_COLOR_GAMUT;
314 value = 0;
315 ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &value);
316 if (ret != 0 || value != NATIVEBUFFER_COLOR_GAMUT_STANDARD_BT709) {
317 LOGE("SetConfigAndGetValue GET_COLOR_GAMUT fail");
318 }
319 code = SET_FORMAT;
320 if (g_cnt % 2 == 0) { // 2 : 每次执行使用不同的format类型
321 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, NATIVEBUFFER_PIXEL_FMT_RGBA_8888);
322 } else {
323 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, NATIVEBUFFER_PIXEL_FMT_YCBCR_420_SP);
324 }
325 code = SET_TRANSFORM;
326 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, NATIVEBUFFER_ROTATE_NONE);
327 code = SET_COLOR_GAMUT;
328 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, NATIVEBUFFER_COLOR_GAMUT_SRGB);
329 g_cnt++;
330 }
331
GetBufferMapPlanes(NativeWindowBuffer * buffer)332 void NativeImageAdaptor::GetBufferMapPlanes(NativeWindowBuffer *buffer)
333 {
334 void *virAddr = nullptr;
335 OH_NativeBuffer_Planes outPlanes;
336 OH_NativeBuffer *nativeBuffer = nullptr;
337
338 int32_t ret = OH_NativeBuffer_FromNativeWindowBuffer(buffer, &nativeBuffer);
339 if (ret != 0) {
340 LOGE("OH_NativeBuffer_FromNativeWindowBuffer fail");
341 return;
342 }
343 ret = OH_NativeBuffer_MapPlanes(nativeBuffer, &virAddr, &outPlanes);
344 if (ret != 0) {
345 LOGE("OH_NativeBuffer_MapPlanes fail");
346 return;
347 }
348 LOGD("Get planeCount: %{public}d", outPlanes.planeCount);
349 for (int32_t i = 0; i < outPlanes.planeCount; i++) {
350 LOGD("Get offset: %{public}lu rowStride: %{public}d columnStride: %{public}d", outPlanes.planes[i].offset,
351 outPlanes.planes[i].rowStride, outPlanes.planes[i].columnStride);
352 }
353 }
354
ProduceBuffer(uint32_t value,OHNativeWindow * InNativeWindow)355 int32_t NativeImageAdaptor::ProduceBuffer(uint32_t value, OHNativeWindow *InNativeWindow)
356 {
357 if (InNativeWindow == nativeWindow_) {
358 SetConfigAndGetValue();
359 }
360
361 NativeWindowBuffer *buffer = nullptr;
362 int fenceFd = -1;
363 int ret = OH_NativeWindow_NativeWindowRequestBuffer(InNativeWindow, &buffer, &fenceFd);
364 if (ret != 0) {
365 LOGE("OH_NativeWindow_NativeWindowRequestBuffer fail");
366 return GSERROR_FAILD;
367 }
368 GetBufferMapPlanes(buffer);
369
370 if (InNativeWindow == nativeWindowCache_) {
371 OH_NativeWindow_NativeWindowDetachBuffer(nativeWindowCache_, buffer);
372 bufferCache_.push(buffer);
373 return GSERROR_OK;
374 }
375 int32_t code = GET_FORMAT;
376 int32_t formatType = NATIVEBUFFER_PIXEL_FMT_CLUT1;
377 OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &formatType);
378
379 BufferHandle *handle = OH_NativeWindow_GetBufferHandleFromNative(buffer);
380 // Obtain the memory virtual address of bufferHandle using the system mmap interface
381 void *mappedAddr = mmap(handle->virAddr, handle->size, PROT_READ | PROT_WRITE, MAP_SHARED, handle->fd, 0);
382 if (formatType == NATIVEBUFFER_PIXEL_FMT_RGBA_8888) {
383 uint32_t *pixel = static_cast<uint32_t *>(mappedAddr);
384 for (uint32_t x = 0; x < width_; x++) {
385 for (uint32_t y = 0; y < height_; y++) {
386 *pixel++ = value;
387 }
388 }
389 }
390
391 // Remember to remove memory mapping after using memory
392 int result = munmap(mappedAddr, handle->size);
393 if (result == -1) {
394 LOGE("munmap fail");
395 }
396
397 struct Region *region = new Region();
398 struct Region::Rect *rect = new Region::Rect();
399 rect->x = 0x100;
400 rect->y = 0x100;
401 rect->w = 0x100;
402 rect->h = 0x100;
403 region->rects = rect;
404 ret = OH_NativeWindow_NativeWindowFlushBuffer(InNativeWindow, buffer, fenceFd, *region);
405 if (ret != 0) {
406 LOGE("OH_NativeWindow_NativeWindowFlushBuffer fail");
407 return GSERROR_FAILD;
408 }
409
410 delete region;
411 return GSERROR_OK;
412 }
413
ConsumerBuffer(uint32_t value,OHNativeWindow * InNativeWindow)414 int32_t NativeImageAdaptor::ConsumerBuffer(uint32_t value, OHNativeWindow *InNativeWindow)
415 {
416 std::lock_guard<std::mutex> lockGuard(opMutex_);
417 NativeWindowBuffer *buffer = nullptr;
418 int fenceFd = -1;
419 int ret = OH_NativeImage_AcquireNativeWindowBuffer(image_, &buffer, &fenceFd);
420 if (ret != 0) {
421 LOGE("OH_NativeImage_AcquireNativeWindowBuffer fail, ret:%{public}d", ret);
422 return GSERROR_FAILD;
423 }
424 ret = OH_NativeImage_ReleaseNativeWindowBuffer(image_, buffer, fenceFd);
425 if (ret != 0) {
426 LOGE("OH_NativeImage_ReleaseNativeWindowBuffer fail, ret:%{public}d", ret);
427 return GSERROR_FAILD;
428 }
429 availableBufferCount_--;
430 return GSERROR_OK;
431 }
432
OnFrameAvailable(void * context)433 void NativeImageAdaptor::OnFrameAvailable(void *context)
434 {
435 NativeImageAdaptor::GetInstance()->DealCallback(context);
436 return;
437 }
438
DealCallback(void * context)439 void NativeImageAdaptor::DealCallback(void *context)
440 {
441 std::lock_guard<std::mutex> lockGuard(opMutex_);
442 LOGD("NativeImageAdaptor success OnFrameAvailable, %{public}d", availableBufferCount_);
443 if (isAutoConsumer_) {
444 int32_t ret = OH_NativeImage_UpdateSurfaceImage(image_);
445 if (ret != 0) {
446 LOGE("OH_NativeImage_UpdateSurfaceImage fail");
447 }
448 } else {
449 availableBufferCount_++;
450 }
451 return;
452 }
453
GetCount()454 int32_t NativeImageAdaptor::GetCount()
455 {
456 std::lock_guard<std::mutex> lockGuard(opMutex_);
457 return availableBufferCount_;
458 }
459
GetAttachBufferCount()460 int32_t NativeImageAdaptor::GetAttachBufferCount()
461 {
462 return bufferAttached_.size();
463 }
464
GetBufferQueueSize()465 int32_t NativeImageAdaptor::GetBufferQueueSize()
466 {
467 int code = GET_BUFFERQUEUE_SIZE;
468 int bufferQueueSize = 0;
469 int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, code, &bufferQueueSize);
470 LOGD("NativeImageAdaptor success GetAttachBufferCount, %{public}d", bufferQueueSize);
471 return bufferQueueSize;
472 }
473
GetCacheBufferCount()474 int32_t NativeImageAdaptor::GetCacheBufferCount()
475 {
476 return bufferCache_.size();
477 }
478
ChangeIsAutoConsumer()479 bool NativeImageAdaptor::ChangeIsAutoConsumer()
480 {
481 std::lock_guard<std::mutex> lockGuard(opMutex_);
482 isAutoConsumer_ = !isAutoConsumer_;
483 return isAutoConsumer_;
484 }
485
GetAvailableCount(napi_env env,napi_callback_info info)486 napi_value NativeImageAdaptor::GetAvailableCount(napi_env env, napi_callback_info info)
487 {
488 napi_value val = nullptr;
489 int32_t count = NativeImageAdaptor::GetInstance()->GetCount();
490 (void)napi_create_int32(env, count, &val);
491 return val;
492 }
493
NapiOnGetBufferQueueSize(napi_env env,napi_callback_info info)494 napi_value NativeImageAdaptor::NapiOnGetBufferQueueSize(napi_env env, napi_callback_info info)
495 {
496 napi_value val = nullptr;
497 int32_t count = NativeImageAdaptor::GetInstance()->GetBufferQueueSize();
498 (void)napi_create_int32(env, count, &val);
499 return val;
500 }
501
NapiOnGetAttachBufferCount(napi_env env,napi_callback_info info)502 napi_value NativeImageAdaptor::NapiOnGetAttachBufferCount(napi_env env, napi_callback_info info)
503 {
504 napi_value val = nullptr;
505 int32_t count = NativeImageAdaptor::GetInstance()->GetAttachBufferCount();
506 (void)napi_create_int32(env, count, &val);
507 return val;
508 }
509
NapiOnGetCacheBufferCount(napi_env env,napi_callback_info info)510 napi_value NativeImageAdaptor::NapiOnGetCacheBufferCount(napi_env env, napi_callback_info info)
511 {
512 napi_value val = nullptr;
513 int32_t count = NativeImageAdaptor::GetInstance()->GetCacheBufferCount();
514 (void)napi_create_int32(env, count, &val);
515 return val;
516 }
517
NapiOnChangeIsAutoConsumer(napi_env env,napi_callback_info info)518 napi_value NativeImageAdaptor::NapiOnChangeIsAutoConsumer(napi_env env, napi_callback_info info)
519 {
520 napi_value val = nullptr;
521 bool isAutoConsumer = NativeImageAdaptor::GetInstance()->ChangeIsAutoConsumer();
522 (void)napi_get_boolean(env, isAutoConsumer, &val);
523 return val;
524 }
525
NapiOnProduceBuffer(napi_env env,napi_callback_info info)526 napi_value NativeImageAdaptor::NapiOnProduceBuffer(napi_env env, napi_callback_info info)
527 {
528 napi_value val = nullptr;
529 int32_t ret = NativeImageAdaptor::GetInstance()->
530 ProduceBuffer(0x00, NativeImageAdaptor::GetInstance()->nativeWindow_);
531 (void)napi_create_int32(env, ret, &val);
532 return val;
533 }
534
NapiOnConsumerBuffer(napi_env env,napi_callback_info info)535 napi_value NativeImageAdaptor::NapiOnConsumerBuffer(napi_env env, napi_callback_info info)
536 {
537 napi_value val = nullptr;
538 int32_t ret = NativeImageAdaptor::GetInstance()->
539 ConsumerBuffer(0x00, NativeImageAdaptor::GetInstance()->nativeWindow_);
540 (void)napi_create_int32(env, ret, &val);
541 return val;
542 }
543
~NativeImageAdaptor()544 NativeImageAdaptor::~NativeImageAdaptor()
545 {
546 OH_NativeImage_UnsetOnFrameAvailableListener(image_);
547 OH_NativeWindow_DestroyNativeWindow(nativeWindow_);
548 OH_NativeImage_Destroy(&image_);
549 }
550 }