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 #include <cstdlib>
16 #include <gtest/gtest.h>
17 #include <securec.h>
18 #include <sys/time.h>
19
20 #define private public
21 #define protected public
22 #include "astc_codec.h"
23 #include "buffer_packer_stream.h"
24 #ifdef ENABLE_ASTC_ENCODE_BASED_GPU
25 #include "image_compressor.h"
26 #endif
27 #include "image_source_util.h"
28 #include "image_source.h"
29 #include "image_system_properties.h"
30 #include "image_utils.h"
31 #include "media_errors.h"
32
33 using namespace testing::ext;
34 using namespace OHOS::Media;
35 using namespace OHOS::ImagePlugin;
36 namespace OHOS {
37 namespace Media {
38
39 #ifdef ENABLE_ASTC_ENCODE_BASED_GPU
40 using namespace AstcEncBasedCl;
41 constexpr uint8_t RGBA_BYTES_PIXEL_LOG2 = 2;
42 constexpr int32_t RGBA_MAX_WIDTH = 8192;
43 constexpr int32_t RGBA_MAX_HEIGHT = 8192;
44 #endif
45
46 constexpr int32_t RGBA_TEST0001_WIDTH = 256;
47 constexpr int32_t RGBA_TEST0001_HEIGHT = 256;
48 constexpr int32_t PIXEL_VALUE_MAX = 256;
49 constexpr int32_t TEXTURE_BLOCK_BYTES = 16;
50 constexpr int32_t TEXTURE_HEAD_BYTES = 16;
51 constexpr int32_t ASTC_BLOCK_WIDTH = 4;
52 constexpr int32_t ASTC_BLOCK_HEIGHT = 4;
53 constexpr int32_t OUTPUT_SIZE_MAX = 200000;
54 constexpr int32_t BYTES_PER_PIXEL = 4;
55 constexpr int64_t SECOND_TO_MICROS = 1000000;
56 constexpr size_t FILE_NAME_LENGTH = 512;
57 constexpr uint32_t EXTEND_BUFFER_SUM_BYTES = 6;
58 constexpr uint32_t EXTEND_INFO_DEFINITION = 6;
59 constexpr uint32_t ASTC_WIDTH = 256;
60 constexpr uint32_t ASTC_HEIGHT = 256;
61 // 16 means header bytes
62 constexpr uint32_t HEADER_BYTES = 16;
63 // 4 means ASTC compression format is 4x4
64 constexpr uint32_t COMPRESSION_FORMAT = 4;
65 // 16 means ASTC per block bytes and header bytes
66 constexpr uint32_t PER_BLOCK_BYTES = 16;
67 constexpr uint32_t BLOCK_SIZE = 4;
68 constexpr uint8_t ASTC_PER_BLOCK_BYTES = 16;
69 constexpr uint8_t ASTC_MAGIC_0 = 0x13; // ASTC MAGIC ID 0x13
70 constexpr uint8_t ASTC_MAGIC_1 = 0xAB; // ASTC MAGIC ID 0xAB
71 constexpr uint8_t ASTC_MAGIC_2 = 0xA1; // ASTC MAGIC ID 0xA1
72 constexpr uint8_t ASTC_MAGIC_3 = 0x5C; // ASTC MAGIC ID 0x5C
73 constexpr uint8_t MASKBITS_FOR_8BIT = 0xFF;
74 constexpr uint8_t ASTC_1TH_BYTES = 8;
75 constexpr uint8_t ASTC_2TH_BYTES = 16;
76 constexpr uint8_t COLOR_SPACE_NAME = 4;
77 constexpr uint8_t COLOR_SPACE_OFFSET = 9;
78 constexpr uint8_t ASTC_BLOCK4X4_FIT_SUT_ASTC_EXAMPLE0[ASTC_PER_BLOCK_BYTES] = {
79 0x43, 0x80, 0xE9, 0xE8, 0xFA, 0xFC, 0x14, 0x17, 0xFF, 0xFF, 0x81, 0x42, 0x12, 0x5A, 0xD4, 0xE9
80 };
81 struct AstcEncTestPara {
82 TextureEncodeOptions param;
83 int32_t width;
84 int32_t height;
85 uint8_t block;
86 size_t frames;
87 bool isBasedOnGpu;
88 bool isSelfCreatePixMap;
89 QualityProfile privateProfile;
90 int64_t totalTime;
91 bool sutEncEnable;
92 };
93
94 enum class TestEncRet {
95 ERR_OK = 0,
96 ERR_FILE_NOT_FIND,
97 ERR_ENC_FAILED,
98 ERR_LOW_LEVEL_FAILED
99 };
100
101 class PluginTextureEncodeTest : public testing::Test {
102 public:
PluginTextureEncodeTest()103 PluginTextureEncodeTest() {}
~PluginTextureEncodeTest()104 ~PluginTextureEncodeTest() {}
105 };
106
CreateDefaultEncParam()107 static TextureEncodeOptions CreateDefaultEncParam()
108 {
109 TextureEncodeOptions param;
110 param.width_ = RGBA_TEST0001_WIDTH;
111 param.height_ = RGBA_TEST0001_HEIGHT;
112 param.stride_ = RGBA_TEST0001_WIDTH;
113 param.blockX_ = ASTC_BLOCK_WIDTH;
114 param.blockY_ = ASTC_BLOCK_HEIGHT;
115 return param;
116 }
117
ConstructPixmap(int32_t width,int32_t height)118 static std::unique_ptr<PixelMap> ConstructPixmap(int32_t width, int32_t height)
119 {
120 std::unique_ptr<PixelMap> pixelMap = std::make_unique<PixelMap>();
121 ImageInfo info;
122 info.size.width = width;
123 info.size.height = height;
124 info.pixelFormat = PixelFormat::RGBA_8888;
125 info.colorSpace = ColorSpace::SRGB;
126 info.alphaType = AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL;
127 pixelMap->SetImageInfo(info);
128
129 int32_t bytesPerPixel = BYTES_PER_PIXEL;
130 int32_t rowDataSize = width * bytesPerPixel;
131 uint32_t bufferSize = rowDataSize * height;
132 if (bufferSize <= 0) {
133 return nullptr;
134 }
135 void *buffer = malloc(bufferSize);
136 if (buffer == nullptr) {
137 return nullptr;
138 }
139 uint8_t *ch = static_cast<uint8_t *>(buffer);
140 for (unsigned int i = 0; i < bufferSize; ++i) {
141 *(ch++) = static_cast<uint8_t>(i % PIXEL_VALUE_MAX);
142 }
143
144 pixelMap->SetPixelsAddr(buffer, nullptr, bufferSize, AllocatorType::HEAP_ALLOC, nullptr);
145
146 return pixelMap;
147 }
148
ConstructAstcBody(uint8_t * astcBody,size_t & blockNums,const uint8_t * astcBlockPart)149 bool ConstructAstcBody(uint8_t* astcBody, size_t& blockNums, const uint8_t* astcBlockPart)
150 {
151 if (astcBody == nullptr || astcBlockPart == nullptr) {
152 return false;
153 }
154
155 uint8_t* astcBuf = astcBody;
156 for (size_t blockIdx = 0; blockIdx < blockNums; blockIdx++) {
157 if (memcpy_s(astcBuf, ASTC_PER_BLOCK_BYTES, astcBlockPart, ASTC_PER_BLOCK_BYTES) != 0) {
158 return false;
159 }
160 astcBuf += ASTC_PER_BLOCK_BYTES;
161 }
162 return true;
163 }
164
GenAstcHeader(uint8_t * header,size_t blockSize,size_t width,size_t height)165 bool GenAstcHeader(uint8_t* header, size_t blockSize, size_t width, size_t height)
166 {
167 if (header == nullptr) {
168 return false;
169 }
170 uint8_t* tmp = header;
171 *tmp++ = ASTC_MAGIC_0;
172 *tmp++ = ASTC_MAGIC_1;
173 *tmp++ = ASTC_MAGIC_2;
174 *tmp++ = ASTC_MAGIC_3;
175 *tmp++ = static_cast<uint8_t>(blockSize);
176 *tmp++ = static_cast<uint8_t>(blockSize);
177 // 1 means 3D block size
178 *tmp++ = 1;
179 *tmp++ = width & MASKBITS_FOR_8BIT;
180 *tmp++ = (width >> ASTC_1TH_BYTES) & MASKBITS_FOR_8BIT;
181 *tmp++ = (width >> ASTC_2TH_BYTES) & MASKBITS_FOR_8BIT;
182 *tmp++ = height & MASKBITS_FOR_8BIT;
183 *tmp++ = (height >> ASTC_1TH_BYTES) & MASKBITS_FOR_8BIT;
184 *tmp++ = (height >> ASTC_2TH_BYTES) & MASKBITS_FOR_8BIT;
185 // astc support 3D, for 2D,the 3D size is 1
186 *tmp++ = 1;
187 *tmp++ = 0;
188 *tmp++ = 0;
189 return true;
190 }
191
ConstructPixelAstc(int32_t width,int32_t height,std::unique_ptr<Media::PixelMap> & pixelMap)192 bool ConstructPixelAstc(int32_t width, int32_t height, std::unique_ptr<Media::PixelMap>& pixelMap)
193 {
194 SourceOptions opts;
195 size_t blockNum = ((ASTC_WIDTH + COMPRESSION_FORMAT - 1) / COMPRESSION_FORMAT) *
196 ((height + COMPRESSION_FORMAT - 1) / COMPRESSION_FORMAT);
197 size_t size = blockNum * PER_BLOCK_BYTES + HEADER_BYTES;
198 // malloc data here
199 uint8_t* data = (uint8_t*)malloc(size);
200 if (!GenAstcHeader(data, BLOCK_SIZE, width, height)) {
201 GTEST_LOG_(ERROR) << "ConstructPixelAstc GenAstcHeader failed\n";
202 return false;
203 }
204 if (!ConstructAstcBody(data + HEADER_BYTES, blockNum, ASTC_BLOCK4X4_FIT_SUT_ASTC_EXAMPLE0)) {
205 GTEST_LOG_(ERROR) << "ConstructAstcBody ConstructAstcBody failed\n";
206 return false;
207 }
208 uint32_t errorCode = 0;
209 std::unique_ptr<ImageSource> imageSource = ImageSource::CreateImageSource(data, size, opts, errorCode);
210 if (errorCode != SUCCESS || !imageSource) {
211 return false;
212 }
213 DecodeOptions decodeOpts;
214 pixelMap = imageSource->CreatePixelMap(decodeOpts, errorCode);
215 if (errorCode != SUCCESS) {
216 return false;
217 }
218 return true;
219 }
220
CurrentTimeInUs(void)221 static int64_t CurrentTimeInUs(void)
222 {
223 struct timeval tv;
224 gettimeofday(&tv, nullptr);
225 return tv.tv_sec * SECOND_TO_MICROS + tv.tv_usec;
226 }
227
228 /**
229 * @tc.name: ASTCEncode001
230 * @tc.desc: Test the AstcSoftwareEncode function
231 * @tc.type: FUNC
232 */
233 HWTEST_F(PluginTextureEncodeTest, ASTCEncode001, TestSize.Level3)
234 {
235 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode001 start";
236
237 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
238 ASSERT_NE(pixelMap, nullptr);
239 PixelMap *pixelMapPtr = pixelMap.get();
240 ASSERT_NE(pixelMapPtr, nullptr);
241
242 uint8_t *output = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
243 ASSERT_NE(output, nullptr);
244 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output, OUTPUT_SIZE_MAX);
245 ASSERT_NE(stream, nullptr);
246
247 struct PlEncodeOptions option = { "image/astc/4*4", 100, 1 }; // quality set to 100
248 AstcCodec astcEncoder;
249 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
250 ASSERT_EQ(setRet, SUCCESS);
251 uint32_t astcRet = astcEncoder.ASTCEncode();
252 ASSERT_EQ(astcRet, SUCCESS);
253
254 option.quality = 20; // quality 20: HIGH_SPEED_PROFILE
255 setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
256 ASSERT_EQ(setRet, SUCCESS);
257 astcRet = astcEncoder.ASTCEncode();
258 ASSERT_EQ(astcRet, SUCCESS);
259
260 if (output != nullptr) {
261 free(output);
262 output = nullptr;
263 }
264 if (stream != nullptr) {
265 delete stream;
266 stream = nullptr;
267 }
268 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode001 end";
269 }
270
271 /**
272 * @tc.name: ASTCEncode002
273 * @tc.desc: Test the SetAstcEncode function
274 * @tc.desc: Set outputStream to nullptr
275 * @tc.type: FUNC
276 */
277 HWTEST_F(PluginTextureEncodeTest, ASTCEncode002, TestSize.Level3)
278 {
279 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode002 start";
280
281 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
282 ASSERT_NE(pixelMap, nullptr);
283 Media::PixelMap *pixelMapPtr = pixelMap.get();
284 ASSERT_NE(pixelMapPtr, nullptr);
285
286 BufferPackerStream *stream = nullptr;
287
288 struct PlEncodeOptions option = { "image/astc/4*4", 100, 1 }; // quality set to 100
289 AstcCodec astcEncoder;
290 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
291 ASSERT_EQ(setRet, ERROR);
292 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode002 end";
293 }
294
295 /**
296 * @tc.name: ASTCEncode003
297 * @tc.desc: Test the SetAstcEncode function
298 * @tc.desc: Set pixelMap to nullptr
299 * @tc.type: FUNC
300 */
301 HWTEST_F(PluginTextureEncodeTest, ASTCEncode003, TestSize.Level3)
302 {
303 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode003 start";
304
305 Media::PixelMap *pixelMapPtr = nullptr;
306
307 uint8_t *output = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
308 ASSERT_NE(output, nullptr);
309 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output, OUTPUT_SIZE_MAX);
310 ASSERT_NE(stream, nullptr);
311
312 struct PlEncodeOptions option = { "image/astc/4*4", 100, 1 }; // quality set to 100
313 AstcCodec astcEncoder;
314 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
315 ASSERT_EQ(setRet, ERROR);
316
317 if (output != nullptr) {
318 free(output);
319 output = nullptr;
320 }
321 if (stream != nullptr) {
322 delete stream;
323 stream = nullptr;
324 }
325 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode003 end";
326 }
327
328 /**
329 * @tc.name: ASTCEncode004
330 * @tc.desc: AstcSoftwareEncode return error test
331 * @tc.type: FUNC
332 */
333 HWTEST_F(PluginTextureEncodeTest, ASTCEncode004, TestSize.Level3)
334 {
335 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode004 start";
336
337 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
338 ASSERT_NE(pixelMap, nullptr);
339 Media::PixelMap *pixelMapPtr = pixelMap.get();
340 ASSERT_NE(pixelMapPtr, nullptr);
341
342 uint8_t *output = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
343 ASSERT_NE(output, nullptr);
344 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output, OUTPUT_SIZE_MAX);
345 ASSERT_NE(stream, nullptr);
346
347 struct PlEncodeOptions option = { "image/astc/7*7", 100, 1 }; // quality set to 100
348 AstcCodec astcEncoder;
349 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
350 ASSERT_EQ(setRet, SUCCESS);
351 uint32_t astcRet = astcEncoder.ASTCEncode();
352 ASSERT_EQ(astcRet, ERROR);
353
354 if (output != nullptr) {
355 free(output);
356 output = nullptr;
357 }
358 if (stream != nullptr) {
359 delete stream;
360 stream = nullptr;
361 }
362 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode004 end";
363 }
364
365 /**
366 * @tc.name: ASTCEncode005
367 * @tc.desc: AstcSoftwareEncode return error test
368 * @tc.type: FUNC
369 */
370 HWTEST_F(PluginTextureEncodeTest, ASTCEncode005, TestSize.Level3)
371 {
372 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode005 start";
373
374 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
375 ASSERT_NE(pixelMap, nullptr);
376 Media::PixelMap *pixelMapPtr = pixelMap.get();
377 ASSERT_NE(pixelMapPtr, nullptr);
378
379 uint8_t *output = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
380 ASSERT_NE(output, nullptr);
381 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output, OUTPUT_SIZE_MAX);
382 ASSERT_NE(stream, nullptr);
383
384 struct PlEncodeOptions option = { "image/sdr_astc_4x4", 92, 1 };
385 AstcCodec astcEncoder;
386 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
387 ASSERT_EQ(setRet, SUCCESS);
388 uint32_t astcRet = astcEncoder.ASTCEncode();
389 ASSERT_NE(astcRet, SUCCESS);
390
391 option.quality = 20;
392 setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
393 ASSERT_EQ(setRet, SUCCESS);
394 astcRet = astcEncoder.ASTCEncode();
395 ASSERT_NE(astcRet, SUCCESS);
396
397 if (output != nullptr) {
398 free(output);
399 output = nullptr;
400 }
401 if (stream != nullptr) {
402 delete stream;
403 stream = nullptr;
404 }
405 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode005 end";
406 }
407
408 /**
409 * @tc.name: ASTCEncode006
410 * @tc.desc: AstcSoftwareEncode return error test
411 * @tc.type: FUNC
412 */
413 HWTEST_F(PluginTextureEncodeTest, ASTCEncode006, TestSize.Level3)
414 {
415 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode006 start";
416
417 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
418 ASSERT_NE(pixelMap, nullptr);
419 Media::PixelMap *pixelMapPtr = pixelMap.get();
420 ASSERT_NE(pixelMapPtr, nullptr);
421
422 uint8_t *output = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
423 ASSERT_NE(output, nullptr);
424 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output, OUTPUT_SIZE_MAX);
425 ASSERT_NE(stream, nullptr);
426
427 struct PlEncodeOptions option = { "image/sdr_sut_superfast_4x4", 92, 1 };
428 AstcCodec astcEncoder;
429 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
430 ASSERT_EQ(setRet, SUCCESS);
431 uint32_t astcRet = astcEncoder.ASTCEncode();
432 ASSERT_NE(astcRet, SUCCESS);
433
434 option.quality = 20;
435 setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
436 ASSERT_EQ(setRet, SUCCESS);
437 astcRet = astcEncoder.ASTCEncode();
438 ASSERT_NE(astcRet, SUCCESS);
439
440 if (output != nullptr) {
441 free(output);
442 output = nullptr;
443 }
444 if (stream != nullptr) {
445 delete stream;
446 stream = nullptr;
447 }
448 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode006 end";
449 }
450
451 /**
452 * @tc.name: ASTCEncode007
453 * @tc.desc: AstcSoftwareEncode return error test
454 * @tc.type: FUNC
455 */
456 HWTEST_F(PluginTextureEncodeTest, ASTCEncode007, TestSize.Level3)
457 {
458 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode007 start";
459
460 std::unique_ptr<PixelMap> pixelMap = nullptr;
461 ConstructPixelAstc(ASTC_WIDTH, ASTC_HEIGHT, pixelMap);
462 ASSERT_NE(pixelMap, nullptr);
463 Media::PixelMap *pixelMapPtr = pixelMap.get();
464 ASSERT_NE(pixelMapPtr, nullptr);
465
466 uint8_t *output = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
467 ASSERT_NE(output, nullptr);
468 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output, OUTPUT_SIZE_MAX);
469 ASSERT_NE(stream, nullptr);
470
471 struct PlEncodeOptions option = { "image/sdr_sut_superfast_4x4", 92, 1 };
472 AstcCodec astcEncoder;
473 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
474 ASSERT_EQ(setRet, SUCCESS);
475 uint32_t astcRet = astcEncoder.ASTCEncode();
476 ASSERT_NE(astcRet, SUCCESS);
477
478 if (output != nullptr) {
479 free(output);
480 output = nullptr;
481 }
482 if (stream != nullptr) {
483 delete stream;
484 stream = nullptr;
485 }
486 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode007 end";
487 }
488
489 /**
490 * @tc.name: ASTCEncode008
491 * @tc.desc: AstcSoftwareEncode return error test
492 * @tc.type: FUNC
493 */
494 HWTEST_F(PluginTextureEncodeTest, ASTCEncode008, TestSize.Level3)
495 {
496 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode008 start";
497
498 std::unique_ptr<PixelMap> pixelMap = nullptr;
499 ConstructPixelAstc(ASTC_WIDTH, ASTC_HEIGHT, pixelMap);
500 ASSERT_NE(pixelMap, nullptr);
501 Media::PixelMap *pixelMapPtr = pixelMap.get();
502 ASSERT_NE(pixelMapPtr, nullptr);
503
504 uint8_t *output = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
505 ASSERT_NE(output, nullptr);
506 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output, OUTPUT_SIZE_MAX);
507 ASSERT_NE(stream, nullptr);
508
509 struct PlEncodeOptions option = { "image/sdr_astc_4x4", 92, 1 };
510 AstcCodec astcEncoder;
511 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
512 ASSERT_EQ(setRet, SUCCESS);
513 uint32_t astcRet = astcEncoder.ASTCEncode();
514 ASSERT_EQ(astcRet, SUCCESS);
515
516 if (output != nullptr) {
517 free(output);
518 output = nullptr;
519 }
520 if (stream != nullptr) {
521 delete stream;
522 stream = nullptr;
523 }
524 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: ASTCEncode008 end";
525 }
526
527 /**
528 * @tc.name: AstcSoftwareEncode001
529 * @tc.desc: Test the AstcSoftwareEncode function
530 * @tc.desc: Set enableQualityCheck to true
531 * @tc.type: FUNC
532 */
533 HWTEST_F(PluginTextureEncodeTest, AstcSoftwareEncode001, TestSize.Level3)
534 {
535 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcSoftwareEncode001 start";
536
537 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
538 ASSERT_NE(pixelMap, nullptr);
539 Media::PixelMap *pixelMapPtr = pixelMap.get();
540 ASSERT_NE(pixelMapPtr, nullptr);
541
542 uint8_t *output = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
543 ASSERT_NE(output, nullptr);
544 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output, OUTPUT_SIZE_MAX);
545 ASSERT_NE(stream, nullptr);
546
547 TextureEncodeOptions param = CreateDefaultEncParam();
548 param.privateProfile_ = QualityProfile::HIGH_QUALITY_PROFILE;
549 int32_t blocksNum = ((param.width_ + param.blockX_ - 1) / param.blockX_) *
550 ((param.height_ + param.blockY_ - 1) / param.blockY_);
551 int32_t outSize = blocksNum * TEXTURE_BLOCK_BYTES + TEXTURE_BLOCK_BYTES;
552 auto outBuffer = static_cast<uint8_t *>(malloc(outSize));
553 ASSERT_NE(outBuffer, nullptr);
554
555 bool enableQualityCheck = true;
556
557 struct PlEncodeOptions option = { "image/astc/4*4", 100, 1 }; // quality set to 100
558 AstcCodec astcEncoder;
559 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
560 ASSERT_EQ(setRet, SUCCESS);
561 uint32_t softwareRet = astcEncoder.AstcSoftwareEncode(param, enableQualityCheck, blocksNum, outBuffer, outSize);
562 ASSERT_EQ(softwareRet, SUCCESS);
563
564 param.privateProfile_ = QualityProfile::HIGH_SPEED_PROFILE;
565 softwareRet = astcEncoder.AstcSoftwareEncode(param, enableQualityCheck, blocksNum, outBuffer, outSize);
566 ASSERT_EQ(softwareRet, SUCCESS);
567
568 if (output != nullptr) {
569 free(output);
570 output = nullptr;
571 }
572 if (stream != nullptr) {
573 delete stream;
574 stream = nullptr;
575 }
576 if (outBuffer != nullptr) {
577 free(outBuffer);
578 outBuffer = nullptr;
579 }
580 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcSoftwareEncode001 end";
581 }
582
583 /**
584 * @tc.name: AstcSoftwareEncode002
585 * @tc.desc: GenAstcHeader return error test
586 * @tc.desc: header == nullptr
587 * @tc.type: FUNC
588 */
589 HWTEST_F(PluginTextureEncodeTest, AstcSoftwareEncode002, TestSize.Level3)
590 {
591 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcSoftwareEncode003 start";
592
593 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
594 ASSERT_NE(pixelMap, nullptr);
595 Media::PixelMap *pixelMapPtr = pixelMap.get();
596 ASSERT_NE(pixelMapPtr, nullptr);
597
598 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(nullptr, OUTPUT_SIZE_MAX);
599 ASSERT_NE(stream, nullptr);
600
601 TextureEncodeOptions param = CreateDefaultEncParam();
602 int32_t blocksNum = ((param.width_ + param.blockX_ - 1) / param.blockX_) *
603 ((param.height_ + param.blockY_ - 1) / param.blockY_);
604 int32_t outSize = blocksNum * TEXTURE_BLOCK_BYTES + TEXTURE_BLOCK_BYTES;
605 bool enableQualityCheck = false;
606 struct PlEncodeOptions option = { "image/astc/4*4", 100, 1 }; // quality set to 100
607 AstcCodec astcEncoder;
608 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
609 ASSERT_EQ(setRet, SUCCESS);
610 uint32_t softwareRet = astcEncoder.AstcSoftwareEncode(param, enableQualityCheck, blocksNum, nullptr, outSize);
611 ASSERT_EQ(softwareRet, ERROR);
612
613 if (stream != nullptr) {
614 delete stream;
615 stream = nullptr;
616 }
617 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcSoftwareEncode003 end";
618 }
619
620 #ifdef ENABLE_ASTC_ENCODE_BASED_GPU
621 /**
622 * @tc.name: AstcEncBasedOnCl001
623 * @tc.desc: Test the AstcClFillImage function
624 * @tc.type: FUNC
625 */
626 HWTEST_F(PluginTextureEncodeTest, AstcEncBasedOnCl001, TestSize.Level3)
627 {
628 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcEncBasedOnCl001 start";
629
630 TextureEncodeOptions param = CreateDefaultEncParam();
631 param.stride_ = param.stride_ << RGBA_BYTES_PIXEL_LOG2;
632 int32_t inputSize = (param.width_ * param.height_) << RGBA_BYTES_PIXEL_LOG2;
633 uint8_t *input = static_cast<uint8_t *>(malloc(inputSize));
634 ASSERT_NE(input, nullptr);
635 for (int32_t i = 0; i < inputSize; ++i) {
636 input[i] = static_cast<uint8_t>(i % PIXEL_VALUE_MAX);
637 }
638
639 ClAstcImageOption imageIn;
640 uint32_t ret = AstcClFillImage(&imageIn, input, param.stride_, param.width_, param.height_);
641 ASSERT_EQ(ret, CL_ASTC_ENC_SUCCESS);
642
643 ret = AstcClFillImage(&imageIn, input, param.stride_, 0, param.height_);
644 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
645
646 ret = AstcClFillImage(&imageIn, input, param.stride_, param.width_, 0);
647 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
648
649 ret = AstcClFillImage(&imageIn, input, param.width_ - 1, param.width_, param.height_);
650 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
651
652 ret = AstcClFillImage(&imageIn, input, param.stride_, RGBA_MAX_WIDTH + 1, param.height_);
653 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
654
655 ret = AstcClFillImage(&imageIn, input, param.stride_, param.width_, RGBA_MAX_HEIGHT + 1);
656 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
657
658 ret = AstcClFillImage(&imageIn, input, param.stride_, RGBA_MAX_WIDTH + 1, RGBA_MAX_HEIGHT + 1);
659 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
660
661 ClAstcImageOption *imageInPtr = nullptr;
662 ret = AstcClFillImage(imageInPtr, input, param.stride_, param.width_, param.height_);
663 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
664
665 if (input != nullptr) {
666 free(input);
667 input = nullptr;
668 }
669
670 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcEncBasedOnCl001 end";
671 }
672
673 /**
674 * @tc.name: AstcEncBasedOnCl002
675 * @tc.desc: AstcClEncImage return failed test
676 * @tc.type: FUNC
677 */
678 HWTEST_F(PluginTextureEncodeTest, AstcEncBasedOnCl002, TestSize.Level3)
679 {
680 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcEncBasedOnCl002 start";
681
682 ClAstcHandle *astcClEncoder = static_cast<ClAstcHandle *>(malloc(sizeof(ClAstcHandle)));
683 uint8_t *buffer = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
684 ClAstcImageOption imageIn;
685
686 uint32_t ret = AstcClEncImage(nullptr, &imageIn, buffer);
687 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
688
689 ret = AstcClEncImage(astcClEncoder, nullptr, buffer);
690 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
691
692 ret = AstcClEncImage(astcClEncoder, &imageIn, nullptr);
693 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
694
695 astcClEncoder->encObj.blockErrs_ = nullptr;
696 ret = AstcClEncImage(astcClEncoder, &imageIn, buffer);
697 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
698
699 if (astcClEncoder != nullptr) {
700 free(astcClEncoder);
701 astcClEncoder = nullptr;
702 }
703 if (buffer != nullptr) {
704 free(buffer);
705 buffer = nullptr;
706 }
707
708 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcEncBasedOnCl002 end";
709 }
710
711 /**
712 * @tc.name: AstcEncBasedOnCl003
713 * @tc.desc: AstcClClose return failed test
714 * @tc.type: FUNC
715 */
716 HWTEST_F(PluginTextureEncodeTest, AstcEncBasedOnCl003, TestSize.Level3)
717 {
718 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcEncBasedOnCl003 start";
719
720 ClAstcHandle *astcClEncoder = static_cast<ClAstcHandle *>(calloc(1, sizeof(ClAstcHandle)));
721 uint32_t ret = AstcClClose(astcClEncoder);
722 ASSERT_EQ(ret, CL_ASTC_ENC_SUCCESS);
723
724 ret = AstcClClose(nullptr);
725 ASSERT_EQ(ret, CL_ASTC_ENC_FAILED);
726
727 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcEncBasedOnCl003 end";
728 }
729 #endif
730
FillEncodeOptions(TextureEncodeOptions & param,int32_t width,int32_t height,uint8_t block,QualityProfile privateProfile)731 static bool FillEncodeOptions(TextureEncodeOptions ¶m,
732 int32_t width, int32_t height, uint8_t block, QualityProfile privateProfile)
733 {
734 param.enableQualityCheck = false;
735 param.hardwareFlag = false;
736 param.sutProfile = SutProfile::SKIP_SUT;
737 param.width_ = width;
738 param.height_ = height;
739 param.stride_ = width;
740 param.privateProfile_ = privateProfile;
741 param.blockX_ = block;
742 param.blockY_ = block;
743 if ((param.blockX_ != 0) && (param.blockY_ != 0)) {
744 param.blocksNum = ((param.width_ + param.blockX_ - 1) / param.blockX_) *
745 ((param.height_ + param.blockY_ - 1) / param.blockY_);
746 } else {
747 return false;
748 }
749 param.astcBytes = param.blocksNum * TEXTURE_BLOCK_BYTES + TEXTURE_HEAD_BYTES;
750 return true;
751 }
752
753 #ifdef ENABLE_ASTC_ENCODE_BASED_GPU
TryAstcEncBasedOnCl(TextureEncodeOptions & param,uint8_t * inData,uint8_t * buffer,const std::string & clBinPath)754 static bool TryAstcEncBasedOnCl(TextureEncodeOptions ¶m, uint8_t *inData,
755 uint8_t *buffer, const std::string &clBinPath)
756 {
757 ClAstcHandle *astcClEncoder = nullptr;
758 if ((inData == nullptr) || (buffer == nullptr)) {
759 GTEST_LOG_(ERROR) << "astc Please check TryAstcEncBasedOnCl input!";
760 return false;
761 }
762 if (AstcClCreate(&astcClEncoder, clBinPath) != CL_ASTC_ENC_SUCCESS) {
763 GTEST_LOG_(ERROR) << "astc AstcClCreate failed!";
764 return false;
765 }
766 ClAstcImageOption imageIn;
767 if (AstcClFillImage(&imageIn, inData, param.stride_, param.width_, param.height_) != CL_ASTC_ENC_SUCCESS) {
768 GTEST_LOG_(ERROR) << "astc AstcClFillImage failed!";
769 AstcClClose(astcClEncoder);
770 return false;
771 }
772 if (AstcClEncImage(astcClEncoder, &imageIn, buffer) != CL_ASTC_ENC_SUCCESS) {
773 GTEST_LOG_(ERROR) << "astc AstcClEncImage failed!";
774 AstcClClose(astcClEncoder);
775 return false;
776 }
777 if (AstcClClose(astcClEncoder) != CL_ASTC_ENC_SUCCESS) {
778 GTEST_LOG_(ERROR) << "astc AstcClClose failed!";
779 return false;
780 }
781 return true;
782 }
783 #endif
784
SelfCreatePixMap(uint8_t * pixelMap,size_t bytesPerFile,size_t idx)785 static void SelfCreatePixMap(uint8_t *pixelMap, size_t bytesPerFile, size_t idx)
786 {
787 uint8_t *buf = pixelMap;
788 for (size_t pixel = 0; pixel < bytesPerFile; pixel++) {
789 *buf++ = (pixel + idx) % PIXEL_VALUE_MAX;
790 }
791 }
792
CheckFileIsExist(const std::string & name)793 static bool CheckFileIsExist(const std::string &name)
794 {
795 return (access(name.c_str(), F_OK) != -1); // -1 means that the file is not exist
796 }
797
ReadFileExtern(uint8_t * pixelMap,size_t bytesPerFile,size_t idx,AstcEncTestPara & testPara)798 static TestEncRet ReadFileExtern(uint8_t *pixelMap, size_t bytesPerFile, size_t idx, AstcEncTestPara &testPara)
799 {
800 const std::string testPath = "/data/local/tmp";
801 char inFile[FILE_NAME_LENGTH];
802 if (sprintf_s(inFile, sizeof(inFile), "%s/%dx%d/a%04ld_%dx%d.rgb", testPath.c_str(),
803 testPara.width, testPara.height, idx + 1, testPara.width, testPara.height) < 0) {
804 return TestEncRet::ERR_LOW_LEVEL_FAILED;
805 }
806 std::string fileStr(inFile);
807 if (!CheckFileIsExist(fileStr)) {
808 GTEST_LOG_(INFO) << "File is not exist: " << inFile;
809 return TestEncRet::ERR_FILE_NOT_FIND;
810 }
811 std::ifstream contents{fileStr};
812 std::string fileContent{std::istreambuf_iterator<char>{contents}, {}};
813 if (fileContent.length() < bytesPerFile) {
814 GTEST_LOG_(ERROR) << "File size is too small: need " << bytesPerFile <<
815 " bytes, but the file only " << fileContent.length() << " bytes in " << inFile;
816 return TestEncRet::ERR_LOW_LEVEL_FAILED;
817 }
818 if (memcpy_s(pixelMap, bytesPerFile, static_cast<const char *>(fileContent.c_str()), bytesPerFile) != 0) {
819 GTEST_LOG_(ERROR) << "file memcpy_s failed";
820 return TestEncRet::ERR_LOW_LEVEL_FAILED;
821 }
822 return TestEncRet::ERR_OK;
823 }
824
FreeMem(uint8_t * pixelMap,uint8_t * astcBuf)825 static void FreeMem(uint8_t *pixelMap, uint8_t *astcBuf)
826 {
827 if (pixelMap != nullptr) {
828 free(pixelMap);
829 }
830 if (astcBuf != nullptr) {
831 free(astcBuf);
832 }
833 }
834
EncodeMutiFrames(AstcEncTestPara & testPara)835 TestEncRet EncodeMutiFrames(AstcEncTestPara &testPara)
836 {
837 testPara.totalTime = 0;
838 size_t bytesPerFile = testPara.width * testPara.height * BYTES_PER_PIXEL;
839 std::string clBinPath = "/sys_prod/etc/graphic/AstcEncShader_ALN-AL00.bin";
840 for (size_t idx = 0; idx < testPara.frames; idx++) {
841 uint8_t *pixelMap = static_cast<uint8_t *>(malloc(bytesPerFile * sizeof(uint8_t)));
842 if (pixelMap == nullptr) {
843 return TestEncRet::ERR_LOW_LEVEL_FAILED;
844 }
845 uint8_t *astcBuf = static_cast<uint8_t *>(malloc(testPara.param.astcBytes * sizeof(uint8_t)));
846 if (astcBuf == nullptr) {
847 free(pixelMap);
848 return TestEncRet::ERR_LOW_LEVEL_FAILED;
849 }
850 if (testPara.isSelfCreatePixMap) {
851 SelfCreatePixMap(pixelMap, bytesPerFile, idx);
852 } else {
853 TestEncRet ret = ReadFileExtern(pixelMap, bytesPerFile, idx, testPara);
854 if (ret != TestEncRet::ERR_OK) {
855 FreeMem(pixelMap, astcBuf);
856 return ret;
857 }
858 }
859 int64_t startTime = CurrentTimeInUs();
860 bool isBasedGpu = false;
861 #ifdef ENABLE_ASTC_ENCODE_BASED_GPU
862 if (testPara.isBasedOnGpu) {
863 if (!TryAstcEncBasedOnCl(testPara.param, pixelMap, astcBuf, clBinPath)) {
864 GTEST_LOG_(ERROR) << "astc encoding based on GPU failed";
865 FreeMem(pixelMap, astcBuf);
866 return TestEncRet::ERR_ENC_FAILED;
867 }
868 isBasedGpu = true;
869 }
870 #endif
871 if (!isBasedGpu && !AstcCodec::AstcSoftwareEncodeCore(testPara.param, pixelMap, astcBuf)) {
872 GTEST_LOG_(ERROR) << "astc encoding based on CPU failed";
873 FreeMem(pixelMap, astcBuf);
874 return TestEncRet::ERR_ENC_FAILED;
875 }
876 FreeMem(pixelMap, astcBuf);
877 testPara.totalTime += CurrentTimeInUs() - startTime;
878 }
879 return TestEncRet::ERR_OK;
880 }
881
TestCaseMultiFrameEnc(AstcEncTestPara & testPara)882 TestEncRet TestCaseMultiFrameEnc(AstcEncTestPara &testPara)
883 {
884 if (!FillEncodeOptions(testPara.param, testPara.width, testPara.height,
885 testPara.block, testPara.privateProfile)) {
886 GTEST_LOG_(ERROR) << "FillEncodeOptions failed";
887 return TestEncRet::ERR_LOW_LEVEL_FAILED;
888 }
889 TestEncRet ret = EncodeMutiFrames(testPara);
890 if (ret == TestEncRet::ERR_OK) {
891 GTEST_LOG_(INFO) << "isGPU:" << testPara.isBasedOnGpu << " SelfPixel:" << testPara.isSelfCreatePixMap <<
892 " profile:" << testPara.privateProfile << " " << testPara.param.width_ << "x" <<
893 testPara.param.height_ << " frames " <<
894 testPara.frames << " gpu astc encoding average time: " <<
895 static_cast<float>(testPara.totalTime) / static_cast<float>(testPara.frames) << "us";
896 }
897 return ret;
898 }
899
CreateAstcEncTestPara(int32_t width,int32_t height,uint8_t block,size_t frames,bool isBasedOnGpu)900 static AstcEncTestPara CreateAstcEncTestPara(int32_t width, int32_t height,
901 uint8_t block, size_t frames, bool isBasedOnGpu)
902 {
903 AstcEncTestPara testPara;
904 testPara.width = width;
905 testPara.height = height;
906 testPara.isBasedOnGpu = isBasedOnGpu;
907 testPara.block = block;
908 testPara.frames = frames;
909 testPara.isSelfCreatePixMap = true;
910 testPara.privateProfile = HIGH_SPEED_PROFILE;
911 testPara.sutEncEnable = false;
912 return testPara;
913 }
914
915 /**
916 * @tc.name: AstcEncoderTime_001
917 * @tc.desc: Calculate the average time
918 * : BasedOnCPU / 64x64 / quality 20 / self-created images / 5000frames
919 * @tc.type: Performance
920 */
921 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_001, TestSize.Level3)
922 {
923 // test condition: width 64, height 64, block 4x4 , frames 5000, isBasedOnGpu: false
924 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 5000, false);
925 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
926 }
927
928 /**
929 * @tc.name: AstcEncoderTime_002
930 * @tc.desc: Calculate the average time
931 * : BasedOnCPU / 64x64 / quality 100 / self-created images / 5000frames
932 * @tc.type: Performance
933 */
934 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_002, TestSize.Level3)
935 {
936 // test condition: width 64, height 64, block 4x4 , frames 5000, isBasedOnGpu: false
937 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 5000, false);
938 testPara.privateProfile = HIGH_QUALITY_PROFILE;
939 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
940 }
941
942 /**
943 * @tc.name: AstcEncoderTime_003
944 * @tc.desc: Calculate the average time
945 * : BasedOnCPU / 64x64 / quality 20 / Extern images / 5000frames
946 * @tc.type: Performance
947 */
948 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_003, TestSize.Level3)
949 {
950 // test condition: width 64, height 64, block 4x4 , frames 5000, isBasedOnGpu: false
951 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 5000, false);
952 testPara.isSelfCreatePixMap = false;
953 ASSERT_LE(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_FILE_NOT_FIND);
954 }
955
956 /**
957 * @tc.name: AstcEncoderTime_004
958 * @tc.desc: Calculate the average time
959 * : BasedOnCPU / 64x64 / quality 100 / Extern images / 5000frames
960 * @tc.type: Performance
961 */
962 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_004, TestSize.Level3)
963 {
964 // test condition: width 64, height 64, block 4x4 , frames 5000, isBasedOnGpu: false
965 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 5000, false);
966 testPara.isSelfCreatePixMap = false;
967 testPara.privateProfile = HIGH_QUALITY_PROFILE;
968 ASSERT_LE(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_FILE_NOT_FIND);
969 }
970
971 /**
972 * @tc.name: AstcEncoderTime_005
973 * @tc.desc: Calculate the average time
974 * : BasedOnGPU / 64x64 / self-created images / 2frames
975 * @tc.type: Performance
976 */
977 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_005, TestSize.Level3)
978 {
979 // test condition: width 64, height 64, block 4x4 , frames 2, isBasedOnGpu: true
980 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 2, true);
981 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
982 }
983
984 /**
985 * @tc.name: AstcEncoderTime_006
986 * @tc.desc: Calculate the average time
987 * : BasedOnGPU / 64x64 / Extern images / 2frames
988 * @tc.type: Performance
989 */
990 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_006, TestSize.Level3)
991 {
992 // test condition: width 64, height 64, block 4x4 , frames 2, isBasedOnGpu: true
993 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 2, true);
994 testPara.isSelfCreatePixMap = false;
995 ASSERT_LE(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_FILE_NOT_FIND);
996 }
997
998 /**
999 * @tc.name: AstcEncoderTime_007
1000 * @tc.desc: Calculate the average time
1001 * : BasedOnGPU / different resolution / self-created images
1002 * @tc.type: Performance
1003 */
1004 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_007, TestSize.Level3)
1005 {
1006 // test condition: width 64, height 64, block 4x4 , frames 2, isBasedOnGpu: true
1007 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 2, true);
1008 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1009
1010 testPara = CreateAstcEncTestPara(128, 128, 4, 2, true); // 64x64 block 4x4 , frames 2
1011 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1012
1013 testPara = CreateAstcEncTestPara(256, 256, 4, 2, true); // 256x256 block 4x4 , frames 2
1014 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1015
1016 testPara = CreateAstcEncTestPara(512, 512, 4, 1, true); // 512x512 block 4x4 , frames 1
1017 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1018
1019 testPara = CreateAstcEncTestPara(1024, 1024, 4, 1, true); // 1024x1024 block 4x4 , frames 1
1020 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1021
1022 testPara = CreateAstcEncTestPara(1920, 1080, 4, 1, true); // 1920x1080 block 4x4 , frames 1
1023 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1024
1025 testPara = CreateAstcEncTestPara(2560, 1440, 4, 1, true); // 2560x1440 block 4x4 , frames 1
1026 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1027
1028 testPara = CreateAstcEncTestPara(3840, 2160, 4, 1, true); // 3840x2160 block 4x4 , frames 1
1029 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1030
1031 testPara = CreateAstcEncTestPara(8192, 8192, 4, 1, true); // 8192x8192 block 4x4 , frames 1
1032 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1033 }
1034
1035 /**
1036 * @tc.name: AstcEncoderTime_008
1037 * @tc.desc: Calculate the average time
1038 * : BasedOnCPU / different resolution / self-created images
1039 * @tc.type: Performance
1040 */
1041 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_008, TestSize.Level3)
1042 {
1043 // test condition: width 64, height 64, block 4x4 , frames 5000, isBasedOnGpu: false
1044 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 5000, false);
1045 testPara.isSelfCreatePixMap = true;
1046 testPara.privateProfile = HIGH_SPEED_PROFILE;
1047 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1048
1049 testPara = CreateAstcEncTestPara(128, 128, 4, 5000, false); // 64x64 block 4x4 , frames 5000
1050 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1051
1052 testPara = CreateAstcEncTestPara(256, 256, 4, 5000, false); // 256x256 block 4x4 , frames 5000
1053 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1054
1055 testPara = CreateAstcEncTestPara(512, 512, 4, 1, false); // 512x512 block 4x4 , frames 1
1056 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1057
1058 testPara = CreateAstcEncTestPara(1024, 1024, 4, 1, false); // 1024x1024 block 4x4 , frames 1
1059 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1060
1061 testPara = CreateAstcEncTestPara(1920, 1080, 4, 1, false); // 1920x1080 block 4x4 , frames 1
1062 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1063
1064 testPara = CreateAstcEncTestPara(2560, 1440, 4, 1, false); // 2560x1440 block 4x4 , frames 1
1065 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1066
1067 testPara = CreateAstcEncTestPara(3840, 2160, 4, 1, false); // 3840x2160 block 4x4 , frames 1
1068 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1069
1070 testPara = CreateAstcEncTestPara(8192, 8192, 4, 1, false); // 8192x8192 block 4x4 , frames 1
1071 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1072 }
1073
1074 /**
1075 * @tc.name: AstcEncoderTime_009
1076 * @tc.desc: BoundCheck for new function
1077 * @tc.type: Performance
1078 */
1079 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_009, TestSize.Level3)
1080 {
1081 TextureEncodeOptions param;
1082 ASSERT_EQ(AstcCodec::AstcSoftwareEncodeCore(param, nullptr, nullptr), false);
1083
1084 uint8_t pixmapIn = 0;
1085 ASSERT_EQ(AstcCodec::AstcSoftwareEncodeCore(param, &pixmapIn, nullptr), false);
1086 }
1087
1088 #ifdef ASTC_CUSTOMIZED_ENABLE
1089 /**
1090 * @tc.name: AstcEncoderTime_010
1091 * @tc.desc: Calculate the average time
1092 * : BasedOnCPU / different resolution / self-created images, extern-created images
1093 * @tc.type: Performance
1094 */
1095 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_010, TestSize.Level3)
1096 {
1097 // test condition: width 64, height 64, block 4x4 , frames 5000, isBasedOnGpu: false
1098 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 5000, false); // 64x64 block 4x4 , frames 5000
1099 testPara.privateProfile = CUSTOMIZED_PROFILE;
1100 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1101
1102 testPara = CreateAstcEncTestPara(128, 128, 4, 5000, false); // 128x128 block 4x4 , frames 5000
1103 testPara.privateProfile = CUSTOMIZED_PROFILE;
1104 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1105
1106 testPara = CreateAstcEncTestPara(256, 256, 4, 5000, false); // 256x256 block 4x4 , frames 5000
1107 testPara.privateProfile = CUSTOMIZED_PROFILE;
1108 ASSERT_EQ(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_OK);
1109
1110 // test condition: width 64, height 64, block 4x4 , frames 5000, isBasedOnGpu: false
1111 testPara = CreateAstcEncTestPara(64, 64, 4, 5000, false); // 64x64 block 4x4 , frames 5000
1112 testPara.isSelfCreatePixMap = false;
1113 testPara.privateProfile = CUSTOMIZED_PROFILE;
1114 ASSERT_LE(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_FILE_NOT_FIND);
1115
1116 testPara = CreateAstcEncTestPara(128, 128, 4, 5000, false); // 128x128 block 4x4 , frames 5000
1117 testPara.isSelfCreatePixMap = false;
1118 testPara.privateProfile = CUSTOMIZED_PROFILE;
1119 ASSERT_LE(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_FILE_NOT_FIND);
1120
1121 testPara = CreateAstcEncTestPara(256, 256, 4, 5000, false); // 256x256 block 4x4 , frames 5000
1122 testPara.isSelfCreatePixMap = false;
1123 testPara.privateProfile = CUSTOMIZED_PROFILE;
1124 ASSERT_LE(TestCaseMultiFrameEnc(testPara), TestEncRet::ERR_FILE_NOT_FIND);
1125 }
1126 #endif
1127
1128 #ifdef ENABLE_ASTC_ENCODE_BASED_GPU
1129 /**
1130 * @tc.name: AstcEncoderTime_011
1131 * @tc.desc: BoundCheck for TryAstcEncBasedOnCl function
1132 * @tc.type: branch coverage
1133 */
EncodeMutiFramesCL(AstcEncTestPara & testPara,const string shaderPath)1134 TestEncRet EncodeMutiFramesCL(AstcEncTestPara &testPara, const string shaderPath)
1135 {
1136 testPara.totalTime = 0;
1137 size_t bytesPerFile = testPara.width * testPara.height * BYTES_PER_PIXEL;
1138 for (size_t idx = 0; idx < testPara.frames; idx++) {
1139 uint8_t *pixelMap = static_cast<uint8_t *>(malloc(bytesPerFile * sizeof(uint8_t)));
1140 if (pixelMap == nullptr) {
1141 return TestEncRet::ERR_LOW_LEVEL_FAILED;
1142 }
1143 uint8_t *astcBuf = static_cast<uint8_t *>(malloc(testPara.param.astcBytes * sizeof(uint8_t)));
1144 if (astcBuf == nullptr) {
1145 free(pixelMap);
1146 return TestEncRet::ERR_LOW_LEVEL_FAILED;
1147 }
1148 SelfCreatePixMap(pixelMap, bytesPerFile, idx);
1149 int64_t startTime = CurrentTimeInUs();
1150 if (!AstcCodec::TryAstcEncBasedOnCl(testPara.param, pixelMap, astcBuf, shaderPath)) {
1151 GTEST_LOG_(ERROR) << "astc encoding based on GPU failed";
1152 FreeMem(pixelMap, astcBuf);
1153 return TestEncRet::ERR_ENC_FAILED;
1154 }
1155 #ifdef SUT_ENCODE_ENABLE
1156 testPara.param.sutProfile = testPara.sutEncEnable ? SutProfile::EXTREME_SPEED : SutProfile::SKIP_SUT;
1157 testPara.param.hardwareFlag = true;
1158 if (!AstcCodec::TryTextureSuperCompress(testPara.param, astcBuf)) {
1159 GTEST_LOG_(ERROR) << "TryTextureSuperCompress failed";
1160 FreeMem(pixelMap, astcBuf);
1161 return TestEncRet::ERR_ENC_FAILED;
1162 }
1163 #endif
1164 FreeMem(pixelMap, astcBuf);
1165 testPara.totalTime += CurrentTimeInUs() - startTime;
1166 }
1167 return TestEncRet::ERR_OK;
1168 }
1169
TestCaseMultiFrameEncCL(AstcEncTestPara & testPara,const string shaderPath)1170 TestEncRet TestCaseMultiFrameEncCL(AstcEncTestPara &testPara, const string shaderPath)
1171 {
1172 if (!FillEncodeOptions(testPara.param, testPara.width, testPara.height,
1173 testPara.block, testPara.privateProfile)) {
1174 GTEST_LOG_(ERROR) << "FillEncodeOptions failed";
1175 return TestEncRet::ERR_LOW_LEVEL_FAILED;
1176 }
1177 TestEncRet ret = EncodeMutiFramesCL(testPara, shaderPath);
1178 if (ret == TestEncRet::ERR_OK) {
1179 GTEST_LOG_(INFO) << "isGPU:" << testPara.isBasedOnGpu << " SelfPixel:" << testPara.isSelfCreatePixMap <<
1180 " profile:" << testPara.privateProfile << " " << testPara.param.width_ << "x" <<
1181 testPara.param.height_ << " frames " <<
1182 testPara.frames << " gpu astc encoding average time: " <<
1183 static_cast<float>(testPara.totalTime) / static_cast<float>(testPara.frames) << "us";
1184 }
1185 return ret;
1186 }
1187
1188 HWTEST_F(PluginTextureEncodeTest, AstcEncoderTime_011, TestSize.Level3)
1189 {
1190 // test condition: width 64, height 64, block 4x4 , frames 1, isBasedOnGpu: false
1191 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 1, false); // 64x64 block 4x4 , frames 1
1192 const std::string clBinInvalidPath = "/data/local/tmp/AstcEncShader_ALN-AL00.bin";
1193 ASSERT_EQ(AstcCodec::TryAstcEncBasedOnCl(testPara.param, nullptr, nullptr, clBinInvalidPath), false);
1194 ASSERT_EQ(TestCaseMultiFrameEncCL(testPara, clBinInvalidPath), TestEncRet::ERR_OK);
1195 testPara.sutEncEnable = true;
1196 ASSERT_EQ(TestCaseMultiFrameEncCL(testPara, clBinInvalidPath), TestEncRet::ERR_OK);
1197 const std::string clBinFalsePath = "/data/false/AstcEncShader_ALN-AL00.bin";
1198 ASSERT_EQ(TestCaseMultiFrameEncCL(testPara, clBinFalsePath), TestEncRet::ERR_OK);
1199 }
1200 #endif
1201
1202 #ifdef SUT_ENCODE_ENABLE
1203 /**
1204 * @tc.name: SutEncoderBoundCheck_012
1205 * @tc.desc: BoundCheck for SutEncoderBoundCheck_012 function
1206 * @tc.type: branch coverage
1207 */
1208 HWTEST_F(PluginTextureEncodeTest, SutEncoderBoundCheck_012, TestSize.Level3)
1209 {
1210 // test condition: width 64, height 64, block 4x4 , frames 1, isBasedOnGpu: false
1211 AstcEncTestPara testPara = CreateAstcEncTestPara(64, 64, 4, 1, false); // 64x64 block 4x4 , frames 1
1212 ASSERT_EQ(AstcCodec::TryTextureSuperCompress(testPara.param, nullptr), true);
1213 uint8_t astcBuf;
1214 testPara.param.astcBytes = 0;
1215 testPara.param.sutProfile = SutProfile::EXTREME_SPEED;
1216 testPara.param.hardwareFlag = true;
1217 testPara.param.blockX_ = ASTC_BLOCK_WIDTH;
1218 testPara.param.blockY_ = ASTC_BLOCK_HEIGHT;
1219 ASSERT_EQ(AstcCodec::TryTextureSuperCompress(testPara.param, &astcBuf), false);
1220 }
1221 #endif
1222
1223 /**
1224 * @tc.name: AstcExtendInfoTest
1225 * @tc.desc: BoundCheck for AstcExtendInfoTest function
1226 * @tc.type: branch coverage
1227 */
1228 HWTEST_F(PluginTextureEncodeTest, AstcExtendInfoTest, TestSize.Level3)
1229 {
1230 GTEST_LOG_(INFO) << "PluginTextureEncodeTest: AstcExtendInfoTest start";
1231 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
1232 ASSERT_NE(pixelMap, nullptr);
1233 Media::PixelMap *pixelMapPtr = pixelMap.get();
1234 ASSERT_NE(pixelMapPtr, nullptr);
1235
1236 uint8_t *output = static_cast<uint8_t *>(malloc(OUTPUT_SIZE_MAX));
1237 ASSERT_NE(output, nullptr);
1238 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output, OUTPUT_SIZE_MAX);
1239 ASSERT_NE(stream, nullptr);
1240
1241 struct PlEncodeOptions option = { "image/astc/4*4", 100, 1 }; // quality set to 100
1242 AstcCodec astcEncoder;
1243 uint32_t setRet = astcEncoder.SetAstcEncode(stream, option, pixelMapPtr);
1244 ASSERT_EQ(setRet, SUCCESS);
1245 AstcExtendInfo extendInfo = {0};
1246 bool ret = astcEncoder.InitAstcExtendInfo(extendInfo);
1247 ASSERT_EQ(ret, true);
1248 ASSERT_EQ(extendInfo.extendBufferSumBytes, EXTEND_BUFFER_SUM_BYTES);
1249 uint8_t* extendBuffer = static_cast<uint8_t *>(malloc(extendInfo.extendBufferSumBytes + EXTEND_INFO_DEFINITION));
1250 astcEncoder.WriteAstcExtendInfo(extendBuffer, 0, extendInfo);
1251 uint8_t csName = *(extendBuffer + COLOR_SPACE_OFFSET);
1252 ASSERT_EQ(csName, COLOR_SPACE_NAME);
1253 astcEncoder.ReleaseExtendInfoMemory(extendInfo);
1254 if (output != nullptr) {
1255 free(output);
1256 output = nullptr;
1257 }
1258 if (stream != nullptr) {
1259 delete stream;
1260 stream = nullptr;
1261 }
1262 if (extendBuffer != nullptr) {
1263 free(extendBuffer);
1264 extendBuffer = nullptr;
1265 }
1266 }
1267
1268 /**
1269 * @tc.name: AstcExtendInfoTest
1270 * @tc.desc: Verify that AstcSoftwareEncodeCore returns false when encoding parameters are invalid.
1271 * @tc.type: FUNC
1272 */
1273 HWTEST_F(PluginTextureEncodeTest, AstcExtendInfoTest001, TestSize.Level3)
1274 {
1275 AstcCodec codec;
1276 TextureEncodeOptions param;
1277 param.blockX_ = -1;
1278 param.blockY_ = -1;
1279 std::vector<uint8_t> pixelMap(1);
1280 std::vector<uint8_t> astcBuf(1);
1281 bool ret = codec.AstcSoftwareEncodeCore(param, pixelMap.data(), astcBuf.data());
1282 EXPECT_FALSE(ret);
1283 }
1284
1285 /**
1286 * @tc.name: IsAstcEncTest001
1287 * @tc.desc: Verify that IsAstcEnc returns false when the input PixelMap or parameters are invalid.
1288 * @tc.type: FUNC
1289 */
1290 HWTEST_F(PluginTextureEncodeTest, IsAstcEncTest001, TestSize.Level3)
1291 {
1292 AstcCodec codec;
1293 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
1294 codec.astcPixelMap_ = pixelMap.get();
1295 ImageInfo info;
1296 uint8_t* pixelMapIn = nullptr;
1297 TextureEncodeOptions param;
1298 AstcExtendInfo extendInfo;
1299 bool ret = codec.IsAstcEnc(info, pixelMapIn, param, extendInfo);
1300 EXPECT_FALSE(ret);
1301 }
1302
1303 /**
1304 * @tc.name: InitBeforeAstcEncodeTest001
1305 * @tc.desc: Verify that InitBeforeAstcEncode returns false when the input PixelMap or output stream is invalid.
1306 * @tc.type: FUNC
1307 */
1308 HWTEST_F(PluginTextureEncodeTest, InitBeforeAstcEncodeTest001, TestSize.Level3)
1309 {
1310 AstcCodec codec;
1311 std::unique_ptr<PixelMap> pixelMap = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
1312 std::vector<uint8_t> output(1);
1313 BufferPackerStream *stream = new (std::nothrow) BufferPackerStream(output.data(), OUTPUT_SIZE_MAX);
1314 ImageInfo imageInfo;
1315 TextureEncodeOptions param;
1316 uint8_t colorData = 0;
1317 uint8_t *pixmapIn = nullptr;
1318 uint32_t stride = 0;
1319 codec.astcPixelMap_ = nullptr;
1320 codec.astcOutput_ = stream;
1321 bool ret = codec.InitBeforeAstcEncode(imageInfo, param, colorData, &pixmapIn, stride);
1322 EXPECT_FALSE(ret);
1323 codec.astcPixelMap_ = pixelMap.get();
1324 codec.astcOutput_ = nullptr;
1325 ret = codec.InitBeforeAstcEncode(imageInfo, param, colorData, &pixmapIn, stride);
1326 EXPECT_FALSE(ret);
1327 codec.astcPixelMap_ = nullptr;
1328 codec.astcOutput_ = nullptr;
1329 ret = codec.InitBeforeAstcEncode(imageInfo, param, colorData, &pixmapIn, stride);
1330 EXPECT_FALSE(ret);
1331 }
1332
1333 /**
1334 * @tc.name: TryEncSUTTest001
1335 * @tc.desc: Verify that TryEncSUT returns false when encoding parameters or buffer are invalid.
1336 * @tc.type: FUNC
1337 */
1338 HWTEST_F(PluginTextureEncodeTest, TryEncSUTTest001, TestSize.Level3)
1339 {
1340 AstcCodec codec;
1341 TextureEncodeOptions param;
1342 uint8_t *astcBuffer = nullptr;
1343 AstcExtendInfo extendInfo;
1344 bool ret = codec.TryEncSUT(param, astcBuffer, extendInfo);
1345 EXPECT_TRUE(ret);
1346 }
1347
1348 /**
1349 * @tc.name: FillMetaDataTest001
1350 * @tc.desc: Verify that FillMetaData returns false when the input PixelMap or parameters are invalid.
1351 * @tc.type: FUNC
1352 */
1353 HWTEST_F(PluginTextureEncodeTest, FillMetaDataTest001, TestSize.Level3)
1354 {
1355 AstcCodec codec;
1356 AstcExtendInfo info = {0};
1357 EXPECT_FALSE(codec.FillMetaData(info, nullptr));
1358 std::unique_ptr<PixelMap> mapNoFd = ConstructPixmap(RGBA_TEST0001_WIDTH, RGBA_TEST0001_HEIGHT);
1359 mapNoFd->imageInfo_.pixelFormat = PixelFormat::RGBA_1010102;
1360 EXPECT_FALSE(codec.FillMetaData(info, mapNoFd.get()));
1361 EXPECT_FALSE(codec.FillMetaData(info, mapNoFd.get()));
1362 mapNoFd->imageInfo_.pixelFormat = PixelFormat::ASTC_4x4;
1363 EXPECT_FALSE(codec.FillMetaData(info, mapNoFd.get()));
1364 }
1365 } // namespace Multimedia
1366 } // namespace OHOS