• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }