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