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 "test_base.h"
17
18 #include <fcntl.h>
19 #include <memory>
20 #include <multimedia/image_framework/image/pixelmap_native.h>
21 #include <multimedia/image_framework/image/image_packer_native.h>
22 #include <native_drawing/drawing_brush.h>
23 #include <native_drawing/drawing_color.h>
24 #include <native_drawing/drawing_filter.h>
25 #include <native_drawing/drawing_image.h>
26 #include <native_drawing/drawing_mask_filter.h>
27 #include <native_drawing/drawing_matrix.h>
28 #include <native_drawing/drawing_path.h>
29 #include <native_drawing/drawing_path_effect.h>
30 #include <native_drawing/drawing_pen.h>
31 #include <native_drawing/drawing_point.h>
32 #include <native_drawing/drawing_rect.h>
33 #include <native_drawing/drawing_round_rect.h>
34 #include <native_drawing/drawing_sampling_options.h>
35 #include <native_drawing/drawing_shader_effect.h>
36 #include <sstream>
37 #include <string>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <sys/time.h>
41 #include <sys/timerfd.h>
42 #include <unistd.h>
43 #include <unordered_map>
44 #include "common/log_common.h"
45
46 const int SECOND_TO_NANO = 1000000000;
47
SetFileName(std::string fileName)48 void TestBase::SetFileName(std::string fileName)
49 {
50 fileName_ = fileName;
51 }
52
SetTestCount(uint32_t testCount)53 void TestBase::SetTestCount(uint32_t testCount)
54 {
55 testCount_ = testCount;
56 }
57
GetBitmap()58 OH_Drawing_Bitmap* TestBase::GetBitmap()
59 {
60 return bitmap_;
61 }
62
GetTime()63 uint32_t TestBase::GetTime()
64 {
65 return usedTime_;
66 }
67
ClipCanvasToDrawSize(OH_Drawing_Canvas * canvas)68 void TestBase::ClipCanvasToDrawSize(OH_Drawing_Canvas *canvas)
69 {
70 OH_Drawing_Rect *rect = OH_Drawing_RectCreate(0, 0, bitmapWidth_, bitmapHeight_);
71 OH_Drawing_CanvasClipRect(canvas, rect, OH_Drawing_CanvasClipOp::INTERSECT, false);
72 OH_Drawing_RectDestroy(rect);
73 }
74
TestFunctionCpu(napi_env env)75 void TestBase::TestFunctionCpu(napi_env env)
76 {
77 CreateBitmapCanvas();
78 OnTestFunction(bitmapCanvas_);
79 BitmapCanvasToFile();
80 }
81
TestFunctionGpu(napi_env env)82 void TestBase::TestFunctionGpu(napi_env env)
83 {
84 CreateGpuCanvas();
85 OnTestFunction(gpuCanvas_);
86 GpuCanvasToFile(env, true);
87 Destroy();
88 }
89
TestStabilityCpu()90 void TestBase::TestStabilityCpu()
91 {
92 CreateBitmapCanvas();
93 OnTestStability(bitmapCanvas_);
94 BitmapCanvasToFile();
95 }
96
TestFunctionGpu(OH_Drawing_Canvas * canvas)97 void TestBase::TestFunctionGpu(OH_Drawing_Canvas *canvas) { OnTestFunction(canvas); }
98
LogStart()99 unsigned long long TestBase::LogStart()
100 {
101 unsigned long long start = 0;
102 struct timespec tv {};
103 if (clock_gettime(CLOCK_BOOTTIME, &tv) >= 0) {
104 start = tv.tv_sec * SECOND_TO_NANO + tv.tv_nsec;
105 }
106 return start;
107 }
108
LogEnd(unsigned long long start)109 void TestBase::LogEnd(unsigned long long start)
110 {
111 unsigned long long end = 0;
112 struct timespec tv {};
113 if (clock_gettime(CLOCK_BOOTTIME, &tv) >= 0) {
114 end = tv.tv_sec * SECOND_TO_NANO + tv.tv_nsec;
115 }
116 // LOGE is to avoid log loss
117 DRAWING_LOGE("DrawingApiTest TotalApiCallCount: [%{public}u]", testCount_);
118 usedTime_ = end - start;
119 DRAWING_LOGE("DrawingApiTest TotalApiCallTime: [%{public}u]", usedTime_);
120 }
121
TestPerformanceGpu(OH_Drawing_Canvas * canvas)122 void TestBase::TestPerformanceGpu(OH_Drawing_Canvas *canvas)
123 {
124 StyleSettings(canvas, styleType_);
125 auto start = LogStart();
126 OnTestPerformance(canvas);
127 LogEnd(start);
128 StyleSettingsDestroy(canvas);
129 }
130
TestPerformanceCpu(napi_env env)131 void TestBase::TestPerformanceCpu(napi_env env)
132 {
133 CreateBitmapCanvas();
134 StyleSettings(bitmapCanvas_, styleType_);
135 auto start = LogStart();
136
137 OnTestPerformance(bitmapCanvas_);
138
139 LogEnd(start);
140 StyleSettingsDestroy(bitmapCanvas_);
141 }
142
TestPerformanceGpu(napi_env env)143 void TestBase::TestPerformanceGpu(napi_env env)
144 {
145 CreateGpuCanvas();
146 StyleSettings(gpuCanvas_, styleType_);
147 auto start = LogStart();
148
149 OnTestPerformance(gpuCanvas_);
150
151 LogEnd(start);
152 GpuCanvasToFile(env, false);
153 StyleSettingsDestroy(gpuCanvas_);
154 Destroy();
155 }
156
CreateBitmapCanvas()157 void TestBase::CreateBitmapCanvas()
158 {
159 // 创建一个bitmap对象
160 if (bitmap_) {
161 OH_Drawing_BitmapDestroy(bitmap_);
162 }
163 bitmap_ = OH_Drawing_BitmapCreate();
164 // 定义bitmap的像素格式
165 OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_PREMUL};
166 // 构造对应格式的bitmap
167 OH_Drawing_BitmapBuild(bitmap_, bitmapWidth_, bitmapHeight_, &cFormat);
168
169 // 创建一个canvas对象
170 if (bitmapCanvas_) {
171 OH_Drawing_CanvasDestroy(bitmapCanvas_);
172 }
173 bitmapCanvas_ = OH_Drawing_CanvasCreate();
174 // 将画布与bitmap绑定,画布画的内容会输出到绑定的bitmap内存中
175 OH_Drawing_CanvasBind(bitmapCanvas_, bitmap_);
176 // 使用白色清除画布内容
177 OH_Drawing_CanvasClear(bitmapCanvas_, OH_Drawing_ColorSetArgb(backgroundA_,
178 backgroundR_, backgroundG_, backgroundB_));
179 }
180
CreateGpuCanvas()181 void TestBase::CreateGpuCanvas()
182 {
183 OH_Drawing_GpuContextOptions options{false};
184 imageInfo_ = {static_cast<int32_t>(bitmapWidth_), static_cast<int32_t>(bitmapHeight_),
185 COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_PREMUL};
186 gpuContext_ = OH_Drawing_GpuContextCreateFromGL(options);
187 surface_ = OH_Drawing_SurfaceCreateFromGpuContext(gpuContext_, true, imageInfo_);
188 gpuCanvas_ = OH_Drawing_SurfaceGetCanvas(surface_);
189 OH_Drawing_CanvasClear(gpuCanvas_, OH_Drawing_ColorSetArgb(backgroundA_, backgroundR_, backgroundG_, backgroundB_));
190 }
191
BitmapCanvasToFile()192 void TestBase::BitmapCanvasToFile()
193 {
194 DRAWING_LOGE("BitmapCanvasToFile");
195 //创建pixmap
196 OH_Pixelmap_InitializationOptions *createOps = nullptr;
197 auto ret = OH_PixelmapInitializationOptions_Create(&createOps);
198 if (ret != IMAGE_SUCCESS || !createOps) {
199 DRAWING_LOGE("BitmapCanvasToFile OH_PixelmapInitializationOptions_Create failed %{public}d", ret);
200 return;
201 }
202
203 OH_PixelmapInitializationOptions_SetWidth(createOps, bitmapWidth_);
204 OH_PixelmapInitializationOptions_SetHeight(createOps, bitmapHeight_);
205 OH_PixelmapInitializationOptions_SetPixelFormat(createOps, 3); // 3 is RGBA fromat
206 OH_PixelmapInitializationOptions_SetSrcPixelFormat(createOps, 3); // 3 is RGBA fromat
207 OH_PixelmapInitializationOptions_SetAlphaType(createOps, 2); // 2 is ALPHA_FORMAT_PREMUL
208
209 size_t bufferSize = bitmapWidth_ * bitmapHeight_ * 4;
210 void *bitmapAddr = OH_Drawing_BitmapGetPixels(bitmap_);
211 OH_PixelmapNative *pixelMap = nullptr;
212 ret = OH_PixelmapNative_CreatePixelmap((uint8_t *)bitmapAddr, bufferSize, createOps, &pixelMap);
213 if (ret != IMAGE_SUCCESS || pixelMap == nullptr) {
214 DRAWING_LOGE(" failed to OH_PixelMap_CreatePixelMap width = %{public}u, height = %{public}u",
215 bitmapWidth_, bitmapHeight_);
216 OH_PixelmapInitializationOptions_Release(createOps);
217 return;
218 }
219
220 Pixmap2RawFile(bitmapAddr, bufferSize);
221 Pixmap2ImageFile(pixelMap);
222
223 OH_PixelmapNative_Release(pixelMap);
224 OH_PixelmapInitializationOptions_Release(createOps);
225 }
226
GpuCanvasToFile(napi_env env,bool saveFile)227 void TestBase::GpuCanvasToFile(napi_env env, bool saveFile)
228 {
229 DRAWING_LOGI("GpuCanvasToFile");
230 //创建pixmap
231 OH_Pixelmap_InitializationOptions *createOps = nullptr;
232 auto ret = OH_PixelmapInitializationOptions_Create(&createOps);
233 if (ret != IMAGE_SUCCESS || !createOps) {
234 DRAWING_LOGE("GpuCanvasToFile OH_PixelmapInitializationOptions_Create failed %{public}d", ret);
235 return;
236 }
237
238 OH_PixelmapInitializationOptions_SetWidth(createOps, bitmapWidth_);
239 OH_PixelmapInitializationOptions_SetHeight(createOps, bitmapHeight_);
240 OH_PixelmapInitializationOptions_SetPixelFormat(createOps, 3); // 3 is RGBA fromat
241 OH_PixelmapInitializationOptions_SetSrcPixelFormat(createOps, 3); // 3 is RGBA fromat
242 OH_PixelmapInitializationOptions_SetAlphaType(createOps, 2); // 2 is ALPHA_FORMAT_PREMUL
243
244 size_t bufferSize = bitmapWidth_ * bitmapHeight_ * 4;
245 if (dstPixels_) {
246 free(dstPixels_);
247 dstPixels_ = nullptr;
248 }
249 dstPixels_ = malloc(bitmapWidth_ * bitmapHeight_ * 4); // 4 for rgba
250 if (dstPixels_ == nullptr) {
251 DRAWING_LOGE("dstPixels_ malloc failed");
252 OH_PixelmapInitializationOptions_Release(createOps);
253 return;
254 }
255 bool output = OH_Drawing_CanvasReadPixels(gpuCanvas_, &imageInfo_, dstPixels_, 4 * bitmapWidth_, 0, 0);
256 if (!output) {
257 DRAWING_LOGE("read pixels failed");
258 OH_PixelmapInitializationOptions_Release(createOps);
259 return;
260 }
261 if (bitmap_) {
262 OH_Drawing_BitmapDestroy(bitmap_);
263 }
264 bitmap_ = OH_Drawing_BitmapCreateFromPixels(&imageInfo_, dstPixels_, 4 * bitmapWidth_); // 4 for rgba
265
266 OH_PixelmapNative *pixelMap = nullptr;
267 ret = OH_PixelmapNative_CreatePixelmap((uint8_t *)dstPixels_, bufferSize, createOps, &pixelMap);
268 if (ret != IMAGE_SUCCESS || pixelMap == nullptr) {
269 DRAWING_LOGE("failed to CreatePixelMap width = %{public}u, height = %{public}u", bitmapWidth_, bitmapHeight_);
270 return;
271 }
272
273 if (saveFile) {
274 Pixmap2RawFile(dstPixels_, bufferSize);
275 Pixmap2ImageFile(pixelMap);
276 }
277 }
278
Pixmap2RawFile(void * pixelmap,uint32_t pixelMapSize)279 void TestBase::Pixmap2RawFile(void *pixelmap, uint32_t pixelMapSize)
280 {
281 // 打开需要输出的文件(请确保应用有权限访问这个路径)
282 std::string path = "/data/storage/el2/base/files/" + fileName_ + ".dat";
283 auto err = remove(path.c_str());
284 if (err) {
285 DRAWING_LOGE("failed to remove path: %{public}s", path.c_str());
286 }
287 int fd = open(path.c_str(), O_RDWR | O_CREAT);
288 if (fd <= 0) {
289 DRAWING_LOGE("failed to open fd = %{public}d path = %{public}s", fd, path.c_str());
290 return;
291 }
292
293 auto result = write(fd, pixelmap, pixelMapSize);
294 if (result != pixelMapSize) {
295 DRAWING_LOGE("failed to Pixmap2RawFile");
296 }
297 // 关闭输出文件
298 close(fd);
299 }
300
Pixmap2ImageFile(OH_PixelmapNative * pixelMap)301 void TestBase::Pixmap2ImageFile(OH_PixelmapNative* pixelMap)
302 {
303 OH_ImagePackerNative *packer = nullptr;
304 auto result = OH_ImagePackerNative_Create(&packer);
305 if (result != IMAGE_SUCCESS || !packer) {
306 DRAWING_LOGE("failed to OH_ImagePackerNative_Create");
307 return;
308 }
309
310 OH_PackingOptions *opts = nullptr;
311 result = OH_PackingOptions_Create(&opts);
312 if (result != IMAGE_SUCCESS || !opts) {
313 DRAWING_LOGE("failed to OH_PackingOptions_Create");
314 return;
315 }
316
317 char format[] = "image/png";
318 Image_MimeType imageMimeType { format, strlen(format) };
319 OH_PackingOptions_SetMimeType(opts, &imageMimeType);
320 uint32_t quality = 100;
321 OH_PackingOptions_SetQuality(opts, quality);
322
323 // 打开需要输出的文件(请确保应用有权限访问这个路径)
324 std::string path = "/data/storage/el2/base/files/" + fileName_ + ".png";
325 auto err = remove(path.c_str());
326 if (err) {
327 DRAWING_LOGE("failed to remove path: %{public}s", path.c_str());
328 }
329 int fd = open(path.c_str(), O_RDWR | O_CREAT);
330 if (fd <= 0) {
331 DRAWING_LOGE("failed to open fd = %{public}d path = %{public}s", fd, path.c_str());
332 OH_PackingOptions_Release(opts);
333 OH_ImagePackerNative_Release(packer);
334 return;
335 }
336
337 // 开始对输入source进行编码过程,返回result为 IMAGE_RESULT_SUCCESS则编码成功
338 result = OH_ImagePackerNative_PackToFileFromPixelmap(packer, opts, pixelMap, fd);
339 if (result != IMAGE_SUCCESS) {
340 DRAWING_LOGE("failed to OH_ImagePackerNative_PackToFileFromImageSource");
341 close(fd);
342 OH_PackingOptions_Release(opts);
343 OH_ImagePackerNative_Release(packer);
344 return;
345 }
346
347 // 关闭输出文件
348 close(fd);
349 OH_PackingOptions_Release(opts);
350 OH_ImagePackerNative_Release(packer);
351 }
352
Destroy()353 void TestBase::Destroy()
354 {
355 if (surface_) {
356 OH_Drawing_SurfaceDestroy(surface_);
357 surface_ = nullptr;
358 }
359 if (gpuContext_) {
360 OH_Drawing_GpuContextDestroy(gpuContext_);
361 gpuContext_ = nullptr;
362 }
363 }
364
StyleSettings(OH_Drawing_Canvas * canvas,int32_t type)365 void TestBase::StyleSettings(OH_Drawing_Canvas* canvas, int32_t type)
366 {
367 if (canvas == nullptr) {
368 return;
369 }
370 StyleSettingsDestroy(canvas);
371 if (type == DRAW_STYLE_COMPLEX) {
372 styleBrush_ = OH_Drawing_BrushCreate();
373 OH_Drawing_BrushSetColor(styleBrush_, 0xFFFF0000);
374 OH_Drawing_CanvasAttachBrush(canvas, styleBrush_);
375 }
376 }
377
StyleSettingsDestroy(OH_Drawing_Canvas * canvas)378 void TestBase::StyleSettingsDestroy(OH_Drawing_Canvas *canvas)
379 {
380 if (canvas != nullptr) {
381 OH_Drawing_CanvasDetachPen(canvas);
382 OH_Drawing_CanvasDetachBrush(canvas);
383 }
384 if (stylePen_ != nullptr) {
385 OH_Drawing_PenDestroy(stylePen_);
386 stylePen_ = nullptr;
387 }
388 if (styleBrush_ != nullptr) {
389 OH_Drawing_BrushDestroy(styleBrush_);
390 styleBrush_ = nullptr;
391 }
392 if (styleMask_ != nullptr) {
393 OH_Drawing_MaskFilterDestroy(styleMask_);
394 styleMask_ = nullptr;
395 }
396 if (styleFilter_ != nullptr) {
397 OH_Drawing_FilterDestroy(styleFilter_);
398 styleFilter_ = nullptr;
399 }
400 if (styleCenter_ != nullptr) {
401 OH_Drawing_PointDestroy(styleCenter_);
402 styleCenter_ = nullptr;
403 }
404 if (styleEffect_ != nullptr) {
405 OH_Drawing_ShaderEffectDestroy(styleEffect_);
406 styleEffect_ = nullptr;
407 }
408 if (stylePathEffect_ != nullptr) {
409 OH_Drawing_PathEffectDestroy(stylePathEffect_);
410 stylePathEffect_ = nullptr;
411 }
412 }
413
GetBitmapWidth()414 uint32_t TestBase::GetBitmapWidth()
415 {
416 return bitmapWidth_;
417 }
418
GetBitmapHeight()419 uint32_t TestBase::GetBitmapHeight()
420 {
421 return bitmapHeight_;
422 }