1 /*
2 * Copyright (c) 2022 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 <gtest/gtest.h>
16 #include <iservice_registry.h>
17 #include <native_image.h>
18 #include <EGL/egl.h>
19 #include <EGL/eglext.h>
20 #include "graphic_common_c.h"
21 #include "surface_type.h"
22 #include "window.h"
23 #include "GLES/gl.h"
24 #include "buffer_log.h"
25
26 using namespace testing;
27 using namespace testing::ext;
28 using namespace std;
29
30 namespace OHOS::Rosen {
31 using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC;
32 constexpr const char* EGL_EXT_PLATFORM_WAYLAND = "EGL_EXT_platform_wayland";
33 constexpr const char* EGL_KHR_PLATFORM_WAYLAND = "EGL_KHR_platform_wayland";
34 constexpr int32_t EGL_CONTEXT_CLIENT_VERSION_NUM = 2;
35 constexpr char CHARACTER_WHITESPACE = ' ';
36 constexpr const char* CHARACTER_STRING_WHITESPACE = " ";
37 constexpr const char* EGL_GET_PLATFORM_DISPLAY_EXT = "eglGetPlatformDisplayEXT";
38
39 struct TEST_IMAGE {
40 int a;
41 bool b;
42 };
43
CheckEglExtension(const char * extensions,const char * extension)44 static bool CheckEglExtension(const char* extensions, const char* extension)
45 {
46 size_t extlen = strlen(extension);
47 const char* end = extensions + strlen(extensions);
48
49 while (extensions < end) {
50 size_t n = 0;
51 /* Skip whitespaces, if any */
52 if (*extensions == CHARACTER_WHITESPACE) {
53 extensions++;
54 continue;
55 }
56 n = strcspn(extensions, CHARACTER_STRING_WHITESPACE);
57 /* Compare strings */
58 if (n == extlen && strncmp(extension, extensions, n) == 0) {
59 return true; /* Found */
60 }
61 extensions += n;
62 }
63 /* Not found */
64 return false;
65 }
66
GetPlatformEglDisplay(EGLenum platform,void * native_display,const EGLint * attrib_list)67 static EGLDisplay GetPlatformEglDisplay(EGLenum platform, void* native_display, const EGLint* attrib_list)
68 {
69 static GetPlatformDisplayExt eglGetPlatformDisplayExt = NULL;
70
71 if (!eglGetPlatformDisplayExt) {
72 const char* extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
73 if (extensions &&
74 (CheckEglExtension(extensions, EGL_EXT_PLATFORM_WAYLAND) ||
75 CheckEglExtension(extensions, EGL_KHR_PLATFORM_WAYLAND))) {
76 eglGetPlatformDisplayExt = (GetPlatformDisplayExt)eglGetProcAddress(EGL_GET_PLATFORM_DISPLAY_EXT);
77 }
78 }
79
80 if (eglGetPlatformDisplayExt) {
81 return eglGetPlatformDisplayExt(platform, native_display, attrib_list);
82 }
83
84 return eglGetDisplay((EGLNativeDisplayType)native_display);
85 }
86
87 class NativeImageTest : public testing::Test {
88 public:
89 static void SetUpTestCase();
90 static void TearDownTestCase();
91
92 static void InitEglContext();
93 static void Deinit();
94
95 static inline OH_NativeImage* image = nullptr;
96 static inline OHNativeWindow* nativeWindow = nullptr;
97 static inline GLuint textureId = 0;
98 static inline GLuint textureId2 = 0;
99 static inline EGLDisplay eglDisplay_ = EGL_NO_DISPLAY;
100 static inline EGLContext eglContext_ = EGL_NO_CONTEXT;
101 static inline EGLConfig config_;;
102 };
103
SetUpTestCase()104 void NativeImageTest::SetUpTestCase()
105 {
106 image = nullptr;
107 nativeWindow = nullptr;
108 glGenTextures(1, &textureId);
109 glGenTextures(1, &textureId2);
110 }
111
TearDownTestCase()112 void NativeImageTest::TearDownTestCase()
113 {
114 image = nullptr;
115 nativeWindow = nullptr;
116 Deinit();
117 }
118
InitEglContext()119 void NativeImageTest::InitEglContext()
120 {
121 if (eglContext_ != EGL_NO_DISPLAY) {
122 return;
123 }
124
125 BLOGI("Creating EGLContext!!!");
126 eglDisplay_ = GetPlatformEglDisplay(EGL_PLATFORM_OHOS_KHR, EGL_DEFAULT_DISPLAY, NULL);
127 if (eglDisplay_ == EGL_NO_DISPLAY) {
128 BLOGW("Failed to create EGLDisplay gl errno : %{public}x", eglGetError());
129 return;
130 }
131
132 EGLint major, minor;
133 if (eglInitialize(eglDisplay_, &major, &minor) == EGL_FALSE) {
134 BLOGE("Failed to initialize EGLDisplay");
135 return;
136 }
137
138 if (eglBindAPI(EGL_OPENGL_ES_API) == EGL_FALSE) {
139 BLOGE("Failed to bind OpenGL ES API");
140 return;
141 }
142
143 unsigned int ret;
144 EGLint count;
145 EGLint config_attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
146 EGL_ALPHA_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT, EGL_NONE };
147
148 ret = eglChooseConfig(eglDisplay_, config_attribs, &config_, 1, &count);
149 if (!(ret && static_cast<unsigned int>(count) >= 1)) {
150 BLOGE("Failed to eglChooseConfig");
151 return;
152 }
153
154 static const EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, EGL_CONTEXT_CLIENT_VERSION_NUM, EGL_NONE };
155
156 eglContext_ = eglCreateContext(eglDisplay_, config_, EGL_NO_CONTEXT, context_attribs);
157 if (eglContext_ == EGL_NO_CONTEXT) {
158 BLOGE("Failed to create egl context %{public}x", eglGetError());
159 return;
160 }
161
162 eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, eglContext_);
163
164 BLOGW("Create EGL context successfully, version %{public}d.%{public}d", major, minor);
165 }
166
Deinit()167 void NativeImageTest::Deinit()
168 {
169 if (eglDisplay_ == EGL_NO_DISPLAY) {
170 return;
171 }
172 eglDestroyContext(eglDisplay_, eglContext_);
173 eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
174 eglTerminate(eglDisplay_);
175 eglReleaseThread();
176
177 eglDisplay_ = EGL_NO_DISPLAY;
178 eglContext_ = EGL_NO_CONTEXT;
179 }
180
181 /*
182 * @tc.name: OHNativeImageCreate001
183 * @tc.desc: test for call OH_NativeImage_Create and check ret.
184 * @tc.type: FUNC
185 */
186 HWTEST_F(NativeImageTest, OHNativeImageCreate001, Function | MediumTest | Level1)
187 {
188 image = OH_NativeImage_Create(textureId, GL_TEXTURE_2D);
189 ASSERT_NE(image, nullptr);
190 }
191
192 /*
193 * @tc.name: OHNativeImageAcquireNativeWindow001
194 * @tc.desc: test for call OH_NativeImage_AcquireNativeWindow by abnormal input and check ret.
195 * @tc.type: FUNC
196 */
197 HWTEST_F(NativeImageTest, OHNativeImageAcquireNativeWindow001, Function | MediumTest | Level2)
198 {
199 nativeWindow = OH_NativeImage_AcquireNativeWindow(nullptr);
200 ASSERT_EQ(nativeWindow, nullptr);
201 }
202
203 /*
204 * @tc.name: OHNativeImageAcquireNativeWindow001
205 * @tc.desc: test for call OH_NativeImage_AcquireNativeWindow and check ret.
206 * @tc.type: FUNC
207 */
208 HWTEST_F(NativeImageTest, OHNativeImageAcquireNativeWindow002, Function | MediumTest | Level1)
209 {
210 nativeWindow = OH_NativeImage_AcquireNativeWindow(image);
211 ASSERT_NE(nativeWindow, nullptr);
212 }
213
214 /*
215 * @tc.name: OHNativeImageAttachContext001
216 * @tc.desc: test for call OH_NativeImage_AttachContext by abnormal input and check ret.
217 * @tc.type: FUNC
218 */
219 HWTEST_F(NativeImageTest, OHNativeImageAttachContext001, Function | MediumTest | Level2)
220 {
221 int32_t ret = OH_NativeImage_AttachContext(nullptr, textureId);
222 ASSERT_NE(ret, SURFACE_ERROR_OK);
223 }
224
225 /*
226 * @tc.name: OHNativeImageDetachContext001
227 * @tc.desc: test for call OHNativeImageDetachContext by abnormal input and check ret.
228 * @tc.type: FUNC
229 */
230 HWTEST_F(NativeImageTest, OHNativeImageDetachContext001, Function | MediumTest | Level2)
231 {
232 int32_t ret = OH_NativeImage_DetachContext(nullptr);
233 ASSERT_NE(ret, SURFACE_ERROR_OK);
234 }
235
236 /*
237 * @tc.name: OHNativeImageDetachContext002
238 * @tc.desc: test for call OHNativeImageDetachContext and check ret.
239 * @tc.type: FUNC
240 */
241 HWTEST_F(NativeImageTest, OHNativeImageDetachContext002, Function | MediumTest | Level1)
242 {
243 int32_t ret = OH_NativeImage_DetachContext(image);
244 ASSERT_EQ(ret, SURFACE_ERROR_INIT);
245 }
246
247 /*
248 * @tc.name: OHNativeImageDetachContext003
249 * @tc.desc: test for call OHNativeImageDetachContext and check ret.
250 * @tc.type: FUNC
251 */
252 HWTEST_F(NativeImageTest, OHNativeImageDetachContext003, Function | MediumTest | Level1)
253 {
254 InitEglContext();
255 int32_t ret = OH_NativeImage_DetachContext(image);
256 ASSERT_EQ(ret, SURFACE_ERROR_ERROR);
257 }
258
259 /*
260 * @tc.name: OHNativeImageDetachContext003
261 * @tc.desc: test for call OH_NativeImage_AttachContext and check ret.
262 * @tc.type: FUNC
263 */
264 HWTEST_F(NativeImageTest, OHNativeImageAttachContext002, Function | MediumTest | Level1)
265 {
266 int32_t ret = OH_NativeImage_AttachContext(image, textureId);
267 ASSERT_EQ(ret, SURFACE_ERROR_OK);
268 }
269
270 /*
271 * @tc.name: OHNativeImageUpdateSurfaceImage001
272 * @tc.desc: test for call OH_NativeImage_UpdateSurfaceImage by abnormal input and check ret.
273 * @tc.type: FUNC
274 */
275 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage001, Function | MediumTest | Level2)
276 {
277 int32_t ret = OH_NativeImage_UpdateSurfaceImage(nullptr);
278 ASSERT_NE(ret, SURFACE_ERROR_OK);
279 }
280
281 /*
282 * @tc.name: OHNativeImageUpdateSurfaceImage002
283 * @tc.desc: test for call OH_NativeImage_UpdateSurfaceImage and check ret.
284 * @tc.type: FUNC
285 */
286 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage002, Function | MediumTest | Level1)
287 {
288 int32_t ret = OH_NativeImage_UpdateSurfaceImage(image);
289 ASSERT_NE(ret, SURFACE_ERROR_OK);
290 }
291
292 /*
293 * @tc.name: OHNativeImageUpdateSurfaceImage003
294 * @tc.desc: test for call OH_NativeImage_UpdateSurfaceImage.
295 * @tc.type: FUNC
296 */
297 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage003, Function | MediumTest | Level1)
298 {
299 int code = SET_USAGE;
300 int32_t usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA;
301 int32_t ret = NativeWindowHandleOpt(nativeWindow, code, usage);
302 if (ret != GSERROR_OK) {
303 std::cout << "NativeWindowHandleOpt SET_USAGE faile" << std::endl;
304 }
305 code = SET_BUFFER_GEOMETRY;
306 int32_t width = 0x100;
307 int32_t height = 0x100;
308 ret = NativeWindowHandleOpt(nativeWindow, code, width, height);
309 if (ret != GSERROR_OK) {
310 std::cout << "NativeWindowHandleOpt SET_BUFFER_GEOMETRY failed" << std::endl;
311 }
312 code = SET_STRIDE;
313 int32_t stride = 0x8;
314 ret = NativeWindowHandleOpt(nativeWindow, code, stride);
315 if (ret != GSERROR_OK) {
316 std::cout << "NativeWindowHandleOpt SET_STRIDE failed" << std::endl;
317 }
318 code = SET_FORMAT;
319 int32_t format = PIXEL_FMT_RGBA_8888;
320 ret = NativeWindowHandleOpt(nativeWindow, code, format);
321 if (ret != GSERROR_OK) {
322 std::cout << "NativeWindowHandleOpt SET_FORMAT failed" << std::endl;
323 }
324
325 NativeWindowBuffer* nativeWindowBuffer = nullptr;
326 int fenceFd = -1;
327 ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
328 ASSERT_EQ(ret, GSERROR_OK);
329
330 struct Region *region = new Region();
331 struct Region::Rect *rect = new Region::Rect();
332 rect->x = 0x100;
333 rect->y = 0x100;
334 rect->w = 0x100;
335 rect->h = 0x100;
336 region->rects = rect;
337 ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, fenceFd, *region);
338 ASSERT_EQ(ret, GSERROR_OK);
339 delete region;
340
341 ret = OH_NativeImage_UpdateSurfaceImage(image);
342 ASSERT_EQ(ret, SURFACE_ERROR_OK);
343 }
344
345 /*
346 * @tc.name: OHNativeImageGetTimestamp001
347 * @tc.desc: test for call OH_NativeImage_GetTimestamp by abnormal input and check ret.
348 * @tc.type: FUNC
349 */
350 HWTEST_F(NativeImageTest, OHNativeImageGetTimestamp001, Function | MediumTest | Level2)
351 {
352 int64_t timeStamp = OH_NativeImage_GetTimestamp(nullptr);
353 ASSERT_EQ(timeStamp, SURFACE_ERROR_ERROR);
354 }
355
356 /*
357 * @tc.name: OHNativeImageGetTimestamp002
358 * @tc.desc: test for call OH_NativeImage_GetTimestamp and check ret.
359 * @tc.type: FUNC
360 */
361 HWTEST_F(NativeImageTest, OHNativeImageGetTimestamp002, Function | MediumTest | Level1)
362 {
363 int64_t timeStamp = OH_NativeImage_GetTimestamp(image);
364 ASSERT_NE(timeStamp, SURFACE_ERROR_ERROR);
365 }
366
367 /*
368 * @tc.name: OHNativeImageGetTransformMatrix001
369 * @tc.desc: test for call OH_NativeImage_GetTransformMatrix by abnormal input and check ret.
370 * @tc.type: FUNC
371 */
372 HWTEST_F(NativeImageTest, OHNativeImageGetTransformMatrix001, Function | MediumTest | Level2)
373 {
374 float matrix[16];
375 int32_t ret = OH_NativeImage_GetTransformMatrix(nullptr, matrix);
376 ASSERT_NE(ret, SURFACE_ERROR_OK);
377 }
378
379 /*
380 * @tc.name: OHNativeImageGetTransformMatrix002
381 * @tc.desc: test for call OH_NativeImage_GetTransformMatrix and check ret.
382 * @tc.type: FUNC
383 */
384 HWTEST_F(NativeImageTest, OHNativeImageGetTransformMatrix002, Function | MediumTest | Level1)
385 {
386 float matrix[16];
387 int32_t ret = OH_NativeImage_GetTransformMatrix(image, matrix);
388 ASSERT_EQ(ret, SURFACE_ERROR_OK);
389 }
390
391 /*
392 * @tc.name: OHNativeImageGetTransformMatrix003
393 * @tc.desc: test for call OH_NativeImage_GetTransformMatrix with another texture and check ret.
394 * @tc.type: FUNC
395 */
396 HWTEST_F(NativeImageTest, OHNativeImageAttachContext003, Function | MediumTest | Level1)
397 {
398 int32_t ret = OH_NativeImage_AttachContext(image, textureId2);
399 ASSERT_EQ(ret, SURFACE_ERROR_OK);
400 }
401
402 /*
403 * @tc.name: OHNativeImageUpdateSurfaceImage004
404 * @tc.desc: test for OH_NativeImage_UpdateSurfaceImage after the OPENGL ES texture changed and check ret.
405 * @tc.type: FUNC
406 */
407 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage004, Function | MediumTest | Level1)
408 {
409 NativeWindowBuffer* nativeWindowBuffer = nullptr;
410 int fenceFd = -1;
411 int32_t ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
412 ASSERT_EQ(ret, GSERROR_OK);
413
414 struct Region *region = new Region();
415 struct Region::Rect *rect = new Region::Rect();
416 rect->x = 0x100;
417 rect->y = 0x100;
418 rect->w = 0x100;
419 rect->h = 0x100;
420 region->rects = rect;
421 ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, fenceFd, *region);
422 ASSERT_EQ(ret, GSERROR_OK);
423 delete region;
424
425 ret = OH_NativeImage_UpdateSurfaceImage(image);
426 ASSERT_EQ(ret, SURFACE_ERROR_OK);
427 }
428
429 /*
430 * @tc.name: OHNativeImageDetachContext004
431 * @tc.desc: test for call OH_NativeImage_DetachContext and check ret.
432 * @tc.type: FUNC
433 */
434 HWTEST_F(NativeImageTest, OHNativeImageDetachContext004, Function | MediumTest | Level1)
435 {
436 int32_t ret = OH_NativeImage_DetachContext(image);
437 ASSERT_EQ(ret, SURFACE_ERROR_OK);
438 }
439
440 /*
441 * @tc.name: OHNativeImageAttachContext004
442 * @tc.desc: test for call OH_NativeImage_AttachContext after OH_NativeImage_DetachContext and check ret.
443 * @tc.type: FUNC
444 */
445 HWTEST_F(NativeImageTest, OHNativeImageAttachContext004, Function | MediumTest | Level1)
446 {
447 int32_t ret = OH_NativeImage_AttachContext(image, textureId2);
448 ASSERT_EQ(ret, SURFACE_ERROR_OK);
449 }
450
451 /*
452 * @tc.name: OHNativeImageUpdateSurfaceImage005
453 * @tc.desc: test for OHNativeImageUpdateSurfaceImage again and check ret.
454 * @tc.type: FUNC
455 */
456 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage005, Function | MediumTest | Level1)
457 {
458 NativeWindowBuffer* nativeWindowBuffer = nullptr;
459 int fenceFd = -1;
460 int32_t ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
461 ASSERT_EQ(ret, GSERROR_OK);
462
463 struct Region *region = new Region();
464 struct Region::Rect *rect = new Region::Rect();
465 rect->x = 0x100;
466 rect->y = 0x100;
467 rect->w = 0x100;
468 rect->h = 0x100;
469 region->rects = rect;
470 ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, fenceFd, *region);
471 ASSERT_EQ(ret, GSERROR_OK);
472 delete region;
473
474 ret = OH_NativeImage_UpdateSurfaceImage(image);
475 ASSERT_EQ(ret, SURFACE_ERROR_OK);
476 }
477
478 /*
479 * @tc.name: OHNativeImageDestroy001
480 * @tc.desc: test for call OH_NativeImage_Destroy by abnormal input and check ret.
481 * @tc.type: FUNC
482 */
483 HWTEST_F(NativeImageTest, OHNativeImageDestroy001, Function | MediumTest | Level2)
484 {
485 OH_NativeImage_Destroy(nullptr);
486 ASSERT_NE(image, nullptr);
487 }
488
489 /*
490 * @tc.name: OHNativeImageDestroy002
491 * @tc.desc: test for call OH_NativeImage_Destroy and check ret.
492 * @tc.type: FUNC
493 */
494 HWTEST_F(NativeImageTest, OHNativeImageDestroy002, Function | MediumTest | Level1)
495 {
496 OH_NativeImage_Destroy(&image);
497 ASSERT_EQ(image, nullptr);
498 }
499 }