1 /*
2 * Copyright (c) 2024 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 "common/log_common.h"
17 #include <bits/alltypes.h>
18 #include <chrono>
19 #include <fcntl.h>
20 #include <memory>
21 #include <native_drawing/drawing_font_collection.h>
22 #include <native_drawing/drawing_text_typography.h>
23 #include <native_buffer/native_buffer.h>
24 #include <sstream>
25 #include <string>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <unordered_map>
30 #include "my_xcomponent.h"
31 #include "plugin/plugin_manager.h"
32 #include "testcasefactory.h"
33 #include "test_common.h"
34 #include <iostream>
35 #include <thread>
36
37 static std::unordered_map<std::string, MyXComponent *> g_instance;
38
getConfig(int version,EGLDisplay eglDisplay)39 EGLConfig getConfig(int version, EGLDisplay eglDisplay)
40 {
41 int attribList[] = {EGL_SURFACE_TYPE,
42 EGL_WINDOW_BIT,
43 EGL_RED_SIZE,
44 8,
45 EGL_GREEN_SIZE,
46 8,
47 EGL_BLUE_SIZE,
48 8,
49 EGL_ALPHA_SIZE,
50 8,
51 EGL_RENDERABLE_TYPE,
52 EGL_OPENGL_ES2_BIT,
53 EGL_NONE};
54 EGLConfig configs = NULL;
55 int configsNum;
56
57 if (!eglChooseConfig(eglDisplay, attribList, &configs, 1, &configsNum)) {
58 DRAWING_LOGE("eglChooseConfig ERROR");
59 return NULL;
60 }
61
62 return configs;
63 }
64
OnSurfaceCreatedCB(OH_NativeXComponent * component,void * window)65 static void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window)
66 {
67 DRAWING_LOGI("OnSurfaceCreatedCB");
68 if ((component == nullptr) || (window == nullptr)) {
69 DRAWING_LOGE("OnSurfaceCreatedCB: component or window is null");
70 return;
71 }
72 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
73 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
74 if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
75 DRAWING_LOGE("OnSurfaceCreatedCB: Unable to get XComponent id");
76 return;
77 }
78 std::string id(idStr);
79 auto render = MyXComponent::GetOrCreateInstance(id);
80 if (render == nullptr) {
81 DRAWING_LOGE("OnSurfaceCreatedCB: Failed to get instance");
82 return;
83 }
84 OHNativeWindow *nativeWindow = static_cast<OHNativeWindow *>(window);
85 render->SetNativeWindow(nativeWindow);
86
87 uint64_t width;
88 uint64_t height;
89 int32_t status = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
90 if ((status == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) {
91 render->SetSceenHeight(height);
92 render->SetScreenWidth(width);
93 }
94 }
95
OnSurfaceDestroyedCB(OH_NativeXComponent * component,void * window)96 static void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window)
97 {
98 DRAWING_LOGI("OnSurfaceDestroyedCB");
99 if ((component == nullptr) || (window == nullptr)) {
100 DRAWING_LOGE("OnSurfaceDestroyedCB: component or window is null");
101 return;
102 }
103 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
104 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
105 if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
106 DRAWING_LOGE("OnSurfaceDestroyedCB: Unable to get XComponent id");
107 return;
108 }
109 std::string id(idStr);
110 MyXComponent::Release(id);
111 }
112
113 // 通过callback获取到宽高信息
SetScreenWidth(uint64_t width)114 void MyXComponent::SetScreenWidth(uint64_t width)
115 {
116 screenWidth_ = width;
117 }
118
119 // 通过callback获取到宽高信息
SetSceenHeight(uint64_t height)120 void MyXComponent::SetSceenHeight(uint64_t height)
121 {
122 screenHeight_ = height;
123 }
124
125 // 通过callback获取到window
SetNativeWindow(OHNativeWindow * nativeWindow)126 void MyXComponent::SetNativeWindow(OHNativeWindow *nativeWindow)
127 {
128 nativeWindow_ = nativeWindow;
129 }
130
131 //获取屏幕xcomponent的绘制canvas
InitScreenCanvas()132 void MyXComponent::InitScreenCanvas()
133 {
134 if (nativeWindow_ == nullptr) {
135 DRAWING_LOGE("nativeWindow_ is nullptr");
136 return;
137 }
138 // 这里的nativeWindow是从上一步骤中的回调函数中获得的
139 int32_t usage = NATIVEBUFFER_USAGE_CPU_READ | NATIVEBUFFER_USAGE_CPU_WRITE | NATIVEBUFFER_USAGE_MEM_DMA;
140 int ret = OH_NativeWindow_NativeWindowHandleOpt(nativeWindow_, SET_USAGE, usage);
141 if (ret != 0) {
142 DRAWING_LOGE("failed to OH_NativeWindow_NativeWindowHandleOpt");
143 return;
144 }
145 // 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例
146 ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer_, &fenceFd_);
147 if (ret != 0) {
148 DRAWING_LOGE("failed to NativeWindowRequestBuffer");
149 return;
150 }
151 DRAWING_LOGI("request buffer ret = %{public}d", ret);
152 // 通过 OH_NativeWindow_GetBufferHandleFromNative 获取 buffer 的 handle
153 bufferHandle_ = OH_NativeWindow_GetBufferHandleFromNative(buffer_);
154 // 使用系统mmap接口拿到bufferHandle的内存虚拟地址
155 mappedAddr_ = static_cast<uint32_t *>(
156 mmap(bufferHandle_->virAddr, bufferHandle_->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle_->fd, 0));
157 if (mappedAddr_ == MAP_FAILED) {
158 DRAWING_LOGE("mmap failed");
159 return;
160 }
161
162 if (screenCanvas_) {
163 OH_Drawing_CanvasDestroy(screenCanvas_);
164 screenCanvas_ = nullptr;
165 }
166 if (screenBitmap_) {
167 OH_Drawing_BitmapDestroy(screenBitmap_);
168 screenBitmap_ = nullptr;
169 }
170 screenImageInfo_ = {static_cast<int32_t>(screenWidth_), static_cast<int32_t>(screenHeight_),
171 COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
172 screenBitmap_ = OH_Drawing_BitmapCreateFromPixels(&screenImageInfo_, mappedAddr_, bufferHandle_->stride);
173 screenCanvas_ = OH_Drawing_CanvasCreate();
174 OH_Drawing_CanvasBind(screenCanvas_, screenBitmap_);
175 OH_Drawing_CanvasClear(screenCanvas_, OH_Drawing_ColorSetArgb(0x00, 0x00, 0x00, 0x00));
176 }
177
BitmapToScreenCanvas(OH_Drawing_Bitmap * bitmap)178 void MyXComponent::BitmapToScreenCanvas(OH_Drawing_Bitmap* bitmap)
179 {
180 if (screenCanvas_ == nullptr || bitmap == nullptr) {
181 return;
182 }
183 OH_Drawing_CanvasDrawBitmap(screenCanvas_, bitmap, 0, 0);
184 FlushScreen();
185
186 int result = munmap(mappedAddr_, bufferHandle_->size);
187 if (result == -1) {
188 DRAWING_LOGE("munmap failed!");
189 }
190 mappedAddr_ = nullptr;
191 }
192
FlushScreen()193 void MyXComponent::FlushScreen()
194 {
195 if (nativeWindow_ != nullptr && buffer_ != nullptr) {
196 // 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为OHNativeWindowBuffer全部有内容更改。
197 Region region {nullptr, 0};
198 // 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。
199 OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer_, fenceFd_, region);
200 }
201 }
202
InitializeEglContext()203 int32_t MyXComponent::InitializeEglContext()
204 {
205 mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
206 if (mEGLDisplay == EGL_NO_DISPLAY) {
207 DRAWING_LOGE("unable to get EGL display.");
208 return -1;
209 }
210
211 EGLint eglMajVers;
212 EGLint eglMinVers;
213 if (!eglInitialize(mEGLDisplay, &eglMajVers, &eglMinVers)) {
214 mEGLDisplay = EGL_NO_DISPLAY;
215 DRAWING_LOGE("unable to initialize display");
216 return -1;
217 }
218
219 int version = 3;
220 mEGLConfig = getConfig(version, mEGLDisplay);
221 if (mEGLConfig == nullptr) {
222 DRAWING_LOGE("GLContextInit config ERROR");
223 return -1;
224 }
225
226 /* Create EGLContext from */
227 int attribList[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; // 2 size
228
229 mEGLContext = eglCreateContext(mEGLDisplay, mEGLConfig, EGL_NO_CONTEXT, attribList);
230
231 EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
232 mEGLSurface = eglCreatePbufferSurface(mEGLDisplay, mEGLConfig, attribs);
233 if (!eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
234 DRAWING_LOGE("eglMakeCurrent error = %{public}d", eglGetError());
235 return -1;
236 }
237
238 DRAWING_LOGI("Init success.");
239 return 0;
240 }
241
DeInitializeEglContext()242 void MyXComponent::DeInitializeEglContext()
243 {
244 EGLBoolean ret = eglDestroySurface(mEGLDisplay, mEGLSurface);
245 if (!ret) {
246 DRAWING_LOGW("eglDestroySurface failure.");
247 }
248
249 ret = eglDestroyContext(mEGLDisplay, mEGLContext);
250 if (!ret) {
251 DRAWING_LOGW("eglDestroyContext failure.");
252 }
253
254 ret = eglTerminate(mEGLDisplay);
255 if (!ret) {
256 DRAWING_LOGW("eglTerminate failure.");
257 }
258
259 mEGLSurface = NULL;
260 mEGLContext = NULL;
261 mEGLDisplay = NULL;
262 }
263
TestPerformanceCpu(napi_env env,std::string caseName)264 void MyXComponent::TestPerformanceCpu(napi_env env, std::string caseName)
265 {
266 auto testCase = TestCaseFactory::GetPerformanceCpuCase(caseName);
267 if (testCase == nullptr) {
268 FlushScreen();
269 DRAWING_LOGE("failed to get testcase");
270 return;
271 }
272 testCase->SetTestCount(testCount_);
273 testCase->TestPerformanceCpu(env);
274 usedTime_ = testCase->GetTime();
275 BitmapToScreenCanvas(testCase->GetBitmap());
276 }
277
TestPerformanceGpu(napi_env env,std::string caseName)278 void MyXComponent::TestPerformanceGpu(napi_env env, std::string caseName)
279 {
280 auto testCase = TestCaseFactory::GetPerformanceCpuCase(caseName);
281 if (testCase == nullptr) {
282 FlushScreen();
283 DRAWING_LOGE("failed to get testcase");
284 return;
285 }
286 testCase->SetTestCount(testCount_);
287 testCase->TestPerformanceGpu(env);
288 usedTime_ = testCase->GetTime();
289 BitmapToScreenCanvas(testCase->GetBitmap());
290 }
291
TestFunctionCpu(napi_env env,std::string caseName)292 void MyXComponent::TestFunctionCpu(napi_env env, std::string caseName)
293 {
294 auto testCase = TestCaseFactory::GetFunctionCpuCase(caseName);
295 if (testCase == nullptr) {
296 FlushScreen();
297 DRAWING_LOGE("failed to get testcase");
298 return;
299 }
300 testCase->SetFileName(caseName);
301 testCase->TestFunctionCpu(env);
302 BitmapToScreenCanvas(testCase->GetBitmap());
303 }
304
TestStabilityCpuInner(std::string caseName)305 void MyXComponent::TestStabilityCpuInner(std::string caseName)
306 {
307 if (caseName == "All") {
308 for (auto map: TestCaseFactory::GetStabilityCpuCaseAll()) {
309 auto testCase = map.second();
310 testCase->SetTestCount(testCount_);
311 testCase->SetFileName(map.first);
312 testCase->TestStabilityCpu();
313 BitmapToScreenCanvas(testCase->GetBitmap());
314 }
315 DRAWING_LOGI("TestStabilityCpuAll end");
316 } else {
317 auto testCase = TestCaseFactory::GetStabilityCpuCase(caseName);
318 if (testCase == nullptr) {
319 FlushScreen();
320 DRAWING_LOGE("failed to get testcase");
321 return;
322 }
323 testCase->SetTestCount(testCount_);
324 testCase->SetFileName(caseName);
325 testCase->TestStabilityCpu();
326 BitmapToScreenCanvas(testCase->GetBitmap());
327 DRAWING_LOGI("TestStabilityCpu end");
328 }
329 }
330
TestStabilityCpu(napi_env env,std::string caseName)331 void MyXComponent::TestStabilityCpu(napi_env env, std::string caseName)
332 {
333 std::thread threadObj(std::bind(&MyXComponent::TestStabilityCpuInner, this, std::string(caseName)));
334 threadObj.detach();
335 }
336
TestFunctionGpu(napi_env env,std::string caseName)337 void MyXComponent::TestFunctionGpu(napi_env env, std::string caseName)
338 {
339 auto testCase = TestCaseFactory::GetFunctionCpuCase(caseName);
340 if (testCase == nullptr) {
341 FlushScreen();
342 DRAWING_LOGE("failed to get testcase");
343 return;
344 }
345 testCase->SetFileName(caseName);
346 testCase->TestFunctionGpu(env);
347 BitmapToScreenCanvas(testCase->GetBitmap());
348 }
349
SetTestCount(uint32_t testCount)350 void MyXComponent::SetTestCount(uint32_t testCount)
351 {
352 testCount_ = testCount;
353 }
354
NapiSetTestCount(napi_env env,napi_callback_info info)355 napi_value MyXComponent::NapiSetTestCount(napi_env env, napi_callback_info info)
356 {
357 DRAWING_LOGI("NapiSetTestCount");
358 if ((env == nullptr) || (info == nullptr)) {
359 DRAWING_LOGE("NapiDrawPattern: env or info is null");
360 return nullptr;
361 }
362
363 napi_value thisArg;
364 size_t argc = 1;
365 napi_value argv[1] = {nullptr};
366 if (napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr) != napi_ok) {
367 DRAWING_LOGE("NapiDrawPattern: napi_get_cb_info fail");
368 return nullptr;
369 }
370 uint32_t testCount;
371 if (!ConvertIntFromJsValue(env, argv[0], testCount)) {
372 DRAWING_LOGE("NapiDrawPattern: get caseName fail");
373 return nullptr;
374 }
375 DRAWING_LOGI("testCount = %{public}u", testCount);
376
377 napi_value exportInstance;
378 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
379 DRAWING_LOGE("NapiDrawPattern: napi_get_named_property fail");
380 return nullptr;
381 }
382
383 OH_NativeXComponent *nativeXComponent = nullptr;
384 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
385 DRAWING_LOGE("NapiDrawPattern: napi_unwrap fail");
386 return nullptr;
387 }
388
389 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
390 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
391 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
392 DRAWING_LOGE("NapiDrawPattern: Unable to get XComponent id");
393 return nullptr;
394 }
395 DRAWING_LOGI("ID = %{public}s", idStr);
396 std::string id(idStr);
397 MyXComponent *render = MyXComponent().GetOrCreateInstance(id);
398 if (render != nullptr) {
399 render->SetTestCount(testCount);
400 } else {
401 DRAWING_LOGE("render is nullptr");
402 }
403 return nullptr;
404 }
405
GetTime()406 uint32_t MyXComponent::GetTime()
407 {
408 return usedTime_;
409 }
410
NapiGetTime(napi_env env,napi_callback_info info)411 napi_value MyXComponent::NapiGetTime(napi_env env, napi_callback_info info)
412 {
413 DRAWING_LOGI("MyXComponent NapiGetTime");
414 if ((env == nullptr) || (info == nullptr)) {
415 DRAWING_LOGE("NapiDrawPattern: env or info is null");
416 return nullptr;
417 }
418
419 napi_value thisArg;
420 size_t argc = 1;
421 napi_value argv[1] = {nullptr};
422 if (napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr) != napi_ok) {
423 DRAWING_LOGE("NapiDrawPattern: napi_get_cb_info fail");
424 return nullptr;
425 }
426
427 napi_value exportInstance;
428 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
429 DRAWING_LOGE("NapiDrawPattern: napi_get_named_property fail");
430 return nullptr;
431 }
432
433 OH_NativeXComponent *nativeXComponent = nullptr;
434 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
435 DRAWING_LOGE("NapiDrawPattern: napi_unwrap fail");
436 return nullptr;
437 }
438
439 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
440 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
441 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
442 DRAWING_LOGE("NapiDrawPattern: Unable to get XComponent id");
443 return nullptr;
444 }
445 DRAWING_LOGI("ID = %{public}s", idStr);
446 std::string id(idStr);
447 MyXComponent *render = MyXComponent().GetOrCreateInstance(id);
448 if (render != nullptr) {
449 DRAWING_LOGE("DrawingTest render->GetTime");
450 napi_value value = nullptr;
451 (void)napi_create_int32(env, render->GetTime(), &value);
452 return value;
453 } else {
454 DRAWING_LOGE("DrawingTest render is nullptr");
455 }
456 return nullptr;
457 }
458
GetTestNames()459 std::string MyXComponent::GetTestNames()
460 {
461 std::string str = "";
462 for (auto map: TestCaseFactory::GetFunctionCpuCaseAll()) {
463 if (str == "") {
464 str += map.first;
465 } else {
466 str += "," + map.first;
467 }
468 }
469 return str;
470 }
471
NapiGetTestNames(napi_env env,napi_callback_info info)472 napi_value MyXComponent::NapiGetTestNames(napi_env env, napi_callback_info info)
473 {
474 DRAWING_LOGI("MyXComponent NapiGetTestNames");
475 if ((env == nullptr) || (info == nullptr)) {
476 DRAWING_LOGE("NapiGetTestNames: env or info is null");
477 return nullptr;
478 }
479
480 napi_value thisArg;
481 size_t argc = 1;
482 napi_value argv[1] = {nullptr};
483 if (napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr) != napi_ok) {
484 DRAWING_LOGE("NapiGetTestNames: napi_get_cb_info fail");
485 return nullptr;
486 }
487
488 napi_value exportInstance;
489 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
490 DRAWING_LOGE("NapiGetTestNames: napi_get_named_property fail");
491 return nullptr;
492 }
493
494 OH_NativeXComponent *nativeXComponent = nullptr;
495 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
496 DRAWING_LOGE("NapiGetTestNames: napi_unwrap fail");
497 return nullptr;
498 }
499
500 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
501 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
502 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
503 DRAWING_LOGE("NapiGetTestNames: Unable to get XComponent id");
504 return nullptr;
505 }
506 DRAWING_LOGI("ID = %{public}s", idStr);
507 std::string id(idStr);
508 MyXComponent *render = MyXComponent().GetOrCreateInstance(id);
509 if (render != nullptr) {
510 napi_value value = nullptr;
511 std::string str = render->GetTestNames();
512 (void)napi_create_string_utf8(env, str.c_str(), str.length(), &value);
513 return value;
514 } else {
515 DRAWING_LOGE("NapiGetTestNames: render is nullptr");
516 }
517 return nullptr;
518 }
519
NapiFunctionCpu(napi_env env,napi_callback_info info)520 napi_value MyXComponent::NapiFunctionCpu(napi_env env, napi_callback_info info)
521 {
522 DRAWING_LOGI("NapiFunctionCpu");
523 if ((env == nullptr) || (info == nullptr)) {
524 DRAWING_LOGE("NapiFunctionCpu: env or info is null");
525 return nullptr;
526 }
527
528 napi_value thisArg;
529 size_t argc = 1;
530 napi_value argv[1] = {nullptr};
531 if (napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr) != napi_ok) {
532 DRAWING_LOGE("NapiFunctionCpu: napi_get_cb_info fail");
533 return nullptr;
534 }
535 std::string caseName = "";
536 if (!ConvertStringFromJsValue(env, argv[0], caseName)) {
537 DRAWING_LOGE("NapiFunctionCpu: get caseName fail");
538 return nullptr;
539 }
540 DRAWING_LOGI("caseName = %{public}s", caseName.c_str());
541
542 napi_value exportInstance;
543 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
544 DRAWING_LOGE("NapiFunctionCpu: napi_get_named_property fail");
545 return nullptr;
546 }
547
548 OH_NativeXComponent *nativeXComponent = nullptr;
549 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
550 DRAWING_LOGE("NapiFunctionCpu: napi_unwrap fail");
551 return nullptr;
552 }
553
554 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
555 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
556 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
557 DRAWING_LOGE("NapiFunctionCpu: Unable to get XComponent id");
558 return nullptr;
559 }
560 DRAWING_LOGI("NapiFunctionCpu ID = %{public}s", idStr);
561 std::string id(idStr);
562 MyXComponent *render = MyXComponent().GetOrCreateInstance(id);
563 if (render != nullptr) {
564 render->InitScreenCanvas();
565 render->TestFunctionCpu(env, caseName);
566 } else {
567 DRAWING_LOGE("NapiFunctionCpu: render is nullptr");
568 }
569 return nullptr;
570 }
571
NapiStabilityCpu(napi_env env,napi_callback_info info)572 napi_value MyXComponent::NapiStabilityCpu(napi_env env, napi_callback_info info)
573 {
574 DRAWING_LOGI("NapiStabilityCpu");
575 if ((env == nullptr) || (info == nullptr)) {
576 DRAWING_LOGE("NapiStabilityCpu: env or info is null");
577 return nullptr;
578 }
579
580 napi_value thisArg;
581 size_t argc = 1;
582 napi_value argv[1] = {nullptr};
583 if (napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr) != napi_ok) {
584 DRAWING_LOGE("NapiStabilityCpu: napi_get_cb_info fail");
585 return nullptr;
586 }
587 std::string caseName = "";
588 if (!ConvertStringFromJsValue(env, argv[0], caseName)) {
589 DRAWING_LOGE("NapiStabilityCpu: get caseName fail");
590 return nullptr;
591 }
592 DRAWING_LOGI("caseName = %{public}s", caseName.c_str());
593
594 napi_value exportInstance;
595 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
596 DRAWING_LOGE("NapiStabilityCpu: napi_get_named_property fail");
597 return nullptr;
598 }
599
600 OH_NativeXComponent *nativeXComponent = nullptr;
601 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
602 DRAWING_LOGE("NapiStabilityCpu: napi_unwrap fail");
603 return nullptr;
604 }
605
606 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
607 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
608 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
609 DRAWING_LOGE("NapiStabilityCpu: Unable to get XComponent id");
610 return nullptr;
611 }
612 DRAWING_LOGI("NapiStabilityCpu ID = %{public}s", idStr);
613 std::string id(idStr);
614 MyXComponent *render = MyXComponent().GetOrCreateInstance(id);
615 if (render != nullptr) {
616 render->InitScreenCanvas();
617 render->TestStabilityCpu(env, caseName);
618 } else {
619 DRAWING_LOGE("NapiStabilityCpu: render is nullptr");
620 }
621 return nullptr;
622 }
623
NapiFunctionGpu(napi_env env,napi_callback_info info)624 napi_value MyXComponent::NapiFunctionGpu(napi_env env, napi_callback_info info)
625 {
626 DRAWING_LOGI("NapiFunctionGpu");
627 if ((env == nullptr) || (info == nullptr)) {
628 DRAWING_LOGE("NapiFunctionGpu: env or info is null");
629 return nullptr;
630 }
631
632 napi_value thisArg;
633 size_t argc = 1;
634 napi_value argv[1] = {nullptr};
635 if (napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr) != napi_ok) {
636 DRAWING_LOGE("NapiFunctionGpu: napi_get_cb_info fail");
637 return nullptr;
638 }
639 std::string caseName = "";
640 if (!ConvertStringFromJsValue(env, argv[0], caseName)) {
641 DRAWING_LOGE("NapiFunctionGpu: get caseName fail");
642 return nullptr;
643 }
644 DRAWING_LOGI("caseName = %{public}s", caseName.c_str());
645
646 napi_value exportInstance;
647 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
648 DRAWING_LOGE("NapiFunctionGpu: napi_get_named_property fail");
649 return nullptr;
650 }
651
652 OH_NativeXComponent *nativeXComponent = nullptr;
653 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
654 DRAWING_LOGE("NapiFunctionGpu: napi_unwrap fail");
655 return nullptr;
656 }
657
658 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
659 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
660 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
661 DRAWING_LOGE("NapiFunctionGpu: Unable to get XComponent id");
662 return nullptr;
663 }
664 DRAWING_LOGI("NapiFunctionGpu ID = %{public}s", idStr);
665 std::string id(idStr);
666 MyXComponent *render = MyXComponent().GetOrCreateInstance(id);
667 if (render != nullptr) {
668 render->InitScreenCanvas();
669 render->InitializeEglContext();
670 render->TestFunctionGpu(env, caseName);
671 render->DeInitializeEglContext();
672 } else {
673 DRAWING_LOGE("NapiFunctionGpu: render is nullptr");
674 }
675 return nullptr;
676 }
677
NapiPerformanceCpu(napi_env env,napi_callback_info info)678 napi_value MyXComponent::NapiPerformanceCpu(napi_env env, napi_callback_info info)
679 {
680 DRAWING_LOGI("NapiPerformanceCpu");
681 if ((env == nullptr) || (info == nullptr)) {
682 DRAWING_LOGE("NapiDrawPattern: env or info is null");
683 return nullptr;
684 }
685
686 napi_value thisArg;
687 size_t argc = 1;
688 napi_value argv[1] = {nullptr};
689 if (napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr) != napi_ok) {
690 DRAWING_LOGE("NapiDrawPattern: napi_get_cb_info fail");
691 return nullptr;
692 }
693 std::string caseName = "";
694 if (!ConvertStringFromJsValue(env, argv[0], caseName)) {
695 DRAWING_LOGE("NapiDrawPattern: get caseName fail");
696 return nullptr;
697 }
698 DRAWING_LOGI("caseName = %{public}s", caseName.c_str());
699
700 napi_value exportInstance;
701 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
702 DRAWING_LOGE("NapiDrawPattern: napi_get_named_property fail");
703 return nullptr;
704 }
705
706 OH_NativeXComponent *nativeXComponent = nullptr;
707 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
708 DRAWING_LOGE("NapiDrawPattern: napi_unwrap fail");
709 return nullptr;
710 }
711
712 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
713 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
714 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
715 DRAWING_LOGE("NapiDrawPattern: Unable to get XComponent id");
716 return nullptr;
717 }
718 DRAWING_LOGI("ID = %{public}s", idStr);
719 std::string id(idStr);
720 MyXComponent *render = MyXComponent().GetOrCreateInstance(id);
721 if (render != nullptr) {
722 render->InitScreenCanvas();
723 render->TestPerformanceCpu(env, caseName);
724 } else {
725 DRAWING_LOGE("render is nullptr");
726 }
727
728 return nullptr;
729 }
730
NapiPerformanceGpu(napi_env env,napi_callback_info info)731 napi_value MyXComponent::NapiPerformanceGpu(napi_env env, napi_callback_info info)
732 {
733 DRAWING_LOGI("NapiPerformanceGpu");
734 if ((env == nullptr) || (info == nullptr)) {
735 DRAWING_LOGE("NapiDrawPattern: env or info is null");
736 return nullptr;
737 }
738
739 napi_value thisArg;
740 size_t argc = 1;
741 napi_value argv[1] = {nullptr};
742 if (napi_get_cb_info(env, info, &argc, argv, &thisArg, nullptr) != napi_ok) {
743 DRAWING_LOGE("NapiDrawPattern: napi_get_cb_info fail");
744 return nullptr;
745 }
746 std::string caseName = "";
747 if (!ConvertStringFromJsValue(env, argv[0], caseName)) {
748 DRAWING_LOGE("NapiDrawPattern: get caseName fail");
749 return nullptr;
750 }
751
752 napi_value exportInstance;
753 if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
754 DRAWING_LOGE("NapiDrawPattern: napi_get_named_property fail");
755 return nullptr;
756 }
757
758 OH_NativeXComponent *nativeXComponent = nullptr;
759 if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
760 DRAWING_LOGE("NapiDrawPattern: napi_unwrap fail");
761 return nullptr;
762 }
763
764 char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'};
765 uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1;
766 if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) {
767 DRAWING_LOGE("NapiDrawPattern: Unable to get XComponent id");
768 return nullptr;
769 }
770 std::string id(idStr);
771 MyXComponent *render = MyXComponent().GetOrCreateInstance(id);
772 if (render != nullptr) {
773 render->InitScreenCanvas();
774 render->InitializeEglContext();
775 render->TestPerformanceGpu(env, caseName);
776 render->DeInitializeEglContext();
777 } else {
778 DRAWING_LOGE("render is nullptr");
779 }
780 DRAWING_LOGI("DrawingTest NapiPerformanceGpu, ID = %{public}s, caseName = %{public}s", idStr, caseName.c_str());
781
782 return nullptr;
783 }
784
~MyXComponent()785 MyXComponent::~MyXComponent()
786 {
787 if (screenCanvas_) {
788 OH_Drawing_CanvasDestroy(screenCanvas_);
789 screenCanvas_ = nullptr;
790 }
791 if (screenBitmap_) {
792 OH_Drawing_BitmapDestroy(screenBitmap_);
793 screenBitmap_ = nullptr;
794 }
795
796 if (mappedAddr_ != nullptr && bufferHandle_ != nullptr) {
797 int result = munmap(mappedAddr_, bufferHandle_->size);
798 if (result == -1) {
799 DRAWING_LOGE("munmap failed!");
800 }
801 }
802 buffer_ = nullptr;
803 bufferHandle_ = nullptr;
804 nativeWindow_ = nullptr;
805 mappedAddr_ = nullptr;
806 }
807
Release(std::string & id)808 void MyXComponent::Release(std::string &id)
809 {
810 PluginManager::GetInstance()->ReleaseRender(id);
811 auto map = g_instance.find(id);
812 if (map == g_instance.end()) {
813 return;
814 }
815 MyXComponent *render = g_instance[id];
816 if (render != nullptr) {
817 g_instance.erase(map);
818 delete render;
819 render = nullptr;
820 }
821 }
822
Export(napi_env env,napi_value exports)823 void MyXComponent::Export(napi_env env, napi_value exports)
824 {
825 DRAWING_LOGI("MyXComponent napi init");
826 if ((env == nullptr) || (exports == nullptr)) {
827 DRAWING_LOGE("Export: env or exports is null");
828 return;
829 }
830
831 napi_property_descriptor desc[] = {
832 {"setTestCount", nullptr, MyXComponent::NapiSetTestCount, nullptr, nullptr, nullptr, napi_default, nullptr},
833 {"getTime", nullptr, MyXComponent::NapiGetTime, nullptr, nullptr, nullptr, napi_default, nullptr},
834 {"getTestNames", nullptr, MyXComponent::NapiGetTestNames, nullptr, nullptr, nullptr, napi_default, nullptr},
835 {"testFunctionCpu", nullptr, MyXComponent::NapiFunctionCpu, nullptr, nullptr, nullptr, napi_default, nullptr},
836 {"testFunctionGpu", nullptr, MyXComponent::NapiFunctionGpu, nullptr, nullptr, nullptr, napi_default, nullptr},
837 {"testPerformanceCpu", nullptr, MyXComponent::NapiPerformanceCpu,
838 nullptr, nullptr, nullptr, napi_default, nullptr},
839 {"testPerformanceGpu", nullptr, MyXComponent::NapiPerformanceGpu,
840 nullptr, nullptr, nullptr, napi_default, nullptr},
841 {"testStabilityCpu", nullptr, MyXComponent::NapiStabilityCpu, nullptr, nullptr, nullptr, napi_default, nullptr},
842 };
843 if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
844 DRAWING_LOGE("Export: napi_define_properties failed");
845 }
846 }
847
RegisterCallback(OH_NativeXComponent * nativeXComponent)848 void MyXComponent::RegisterCallback(OH_NativeXComponent *nativeXComponent)
849 {
850 DRAWING_LOGI("register callback");
851 renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
852 renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
853 // Callback must be initialized
854 renderCallback_.DispatchTouchEvent = nullptr;
855 renderCallback_.OnSurfaceChanged = nullptr;
856 OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
857 }
858
GetOrCreateInstance(std::string & id)859 MyXComponent *MyXComponent::GetOrCreateInstance(std::string &id)
860 {
861 if (g_instance.find(id) == g_instance.end()) {
862 MyXComponent *render = new MyXComponent(id);
863 g_instance[id] = render;
864 return render;
865 } else {
866 return g_instance[id];
867 }
868 }
869