• 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     EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
163     EGLSurface pbufferSurface_ = eglCreatePbufferSurface(eglDisplay_, config_, attribs);
164 
165     eglMakeCurrent(eglDisplay_, pbufferSurface_, pbufferSurface_, eglContext_);
166 
167     BLOGW("Create EGL context successfully, version %{public}d.%{public}d", major, minor);
168 }
169 
Deinit()170 void NativeImageTest::Deinit()
171 {
172     if (eglDisplay_ == EGL_NO_DISPLAY) {
173         return;
174     }
175     eglDestroyContext(eglDisplay_, eglContext_);
176     eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
177     eglTerminate(eglDisplay_);
178     eglReleaseThread();
179 
180     eglDisplay_ = EGL_NO_DISPLAY;
181     eglContext_ = EGL_NO_CONTEXT;
182 }
183 
184 /*
185  * @tc.name: OHNativeImageCreate001
186  * @tc.desc: test for call OH_NativeImage_Create and check ret.
187  * @tc.type: FUNC
188  */
189 HWTEST_F(NativeImageTest, OHNativeImageCreate001, Function | MediumTest | Level1)
190 {
191     image = OH_NativeImage_Create(textureId, GL_TEXTURE_2D);
192     ASSERT_NE(image, nullptr);
193 }
194 
195 /*
196  * @tc.name: OHNativeImageAcquireNativeWindow001
197  * @tc.desc: test for call OH_NativeImage_AcquireNativeWindow by abnormal input and check ret.
198  * @tc.type: FUNC
199  */
200 HWTEST_F(NativeImageTest, OHNativeImageAcquireNativeWindow001, Function | MediumTest | Level2)
201 {
202     nativeWindow = OH_NativeImage_AcquireNativeWindow(nullptr);
203     ASSERT_EQ(nativeWindow, nullptr);
204 }
205 
206 /*
207  * @tc.name: OHNativeImageAcquireNativeWindow001
208  * @tc.desc: test for call OH_NativeImage_AcquireNativeWindow and check ret.
209  * @tc.type: FUNC
210  */
211 HWTEST_F(NativeImageTest, OHNativeImageAcquireNativeWindow002, Function | MediumTest | Level1)
212 {
213     nativeWindow = OH_NativeImage_AcquireNativeWindow(image);
214     ASSERT_NE(nativeWindow, nullptr);
215 }
216 
217 /*
218  * @tc.name: OHNativeImageAttachContext001
219  * @tc.desc: test for call OH_NativeImage_AttachContext by abnormal input and check ret.
220  * @tc.type: FUNC
221  */
222 HWTEST_F(NativeImageTest, OHNativeImageAttachContext001, Function | MediumTest | Level2)
223 {
224     int32_t ret = OH_NativeImage_AttachContext(nullptr, textureId);
225     ASSERT_NE(ret, SURFACE_ERROR_OK);
226 }
227 
228 /*
229  * @tc.name: OHNativeImageDetachContext001
230  * @tc.desc: test for call OHNativeImageDetachContext by abnormal input and check ret.
231  * @tc.type: FUNC
232  */
233 HWTEST_F(NativeImageTest, OHNativeImageDetachContext001, Function | MediumTest | Level2)
234 {
235     int32_t ret = OH_NativeImage_DetachContext(nullptr);
236     ASSERT_NE(ret, SURFACE_ERROR_OK);
237 }
238 
239 /*
240  * @tc.name: OHNativeImageDetachContext002
241  * @tc.desc: test for call OHNativeImageDetachContext and check ret.
242  * @tc.type: FUNC
243  */
244 HWTEST_F(NativeImageTest, OHNativeImageDetachContext002, Function | MediumTest | Level1)
245 {
246     int32_t ret = OH_NativeImage_DetachContext(image);
247     ASSERT_EQ(ret, SURFACE_ERROR_INIT);
248 }
249 
250 /*
251  * @tc.name: OHNativeImageDetachContext003
252  * @tc.desc: test for call OHNativeImageDetachContext and check ret.
253  * @tc.type: FUNC
254  */
255 HWTEST_F(NativeImageTest, OHNativeImageDetachContext003, Function | MediumTest | Level1)
256 {
257     InitEglContext();
258     int32_t ret = OH_NativeImage_DetachContext(image);
259     ASSERT_EQ(ret, SURFACE_ERROR_ERROR);
260 }
261 
262 /*
263  * @tc.name: OHNativeImageDetachContext003
264  * @tc.desc: test for call OH_NativeImage_AttachContext and check ret.
265  * @tc.type: FUNC
266  */
267 HWTEST_F(NativeImageTest, OHNativeImageAttachContext002, Function | MediumTest | Level1)
268 {
269     int32_t ret = OH_NativeImage_AttachContext(image, textureId);
270     ASSERT_EQ(ret, SURFACE_ERROR_OK);
271 }
272 
273 /*
274  * @tc.name: OHNativeImageUpdateSurfaceImage001
275  * @tc.desc: test for  call OH_NativeImage_UpdateSurfaceImage by abnormal input and check ret.
276  * @tc.type: FUNC
277  */
278 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage001, Function | MediumTest | Level2)
279 {
280     int32_t ret = OH_NativeImage_UpdateSurfaceImage(nullptr);
281     ASSERT_NE(ret, SURFACE_ERROR_OK);
282 }
283 
284 /*
285  * @tc.name: OHNativeImageUpdateSurfaceImage002
286  * @tc.desc: test for call OH_NativeImage_UpdateSurfaceImage and check ret.
287  * @tc.type: FUNC
288  */
289 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage002, Function | MediumTest | Level1)
290 {
291     int32_t ret = OH_NativeImage_UpdateSurfaceImage(image);
292     ASSERT_NE(ret, SURFACE_ERROR_OK);
293 }
294 
295 /*
296  * @tc.name: OHNativeImageUpdateSurfaceImage003
297  * @tc.desc: test for call OH_NativeImage_UpdateSurfaceImage.
298  * @tc.type: FUNC
299  */
300 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage003, Function | MediumTest | Level1)
301 {
302     int code = SET_USAGE;
303     int32_t usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA;
304     int32_t ret = NativeWindowHandleOpt(nativeWindow, code, usage);
305     if (ret != GSERROR_OK) {
306         std::cout << "NativeWindowHandleOpt SET_USAGE faile" << std::endl;
307     }
308     code = SET_BUFFER_GEOMETRY;
309     int32_t width = 0x100;
310     int32_t height = 0x100;
311     ret = NativeWindowHandleOpt(nativeWindow, code, width, height);
312     if (ret != GSERROR_OK) {
313         std::cout << "NativeWindowHandleOpt SET_BUFFER_GEOMETRY failed" << std::endl;
314     }
315     code = SET_STRIDE;
316     int32_t stride = 0x8;
317     ret = NativeWindowHandleOpt(nativeWindow, code, stride);
318     if (ret != GSERROR_OK) {
319         std::cout << "NativeWindowHandleOpt SET_STRIDE failed" << std::endl;
320     }
321     code = SET_FORMAT;
322     int32_t format = GRAPHIC_PIXEL_FMT_RGBA_8888;
323     ret = NativeWindowHandleOpt(nativeWindow, code, format);
324     if (ret != GSERROR_OK) {
325         std::cout << "NativeWindowHandleOpt SET_FORMAT failed" << std::endl;
326     }
327 
328     NativeWindowBuffer* nativeWindowBuffer = nullptr;
329     int fenceFd = -1;
330     ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
331     ASSERT_EQ(ret, GSERROR_OK);
332 
333     struct Region *region = new Region();
334     struct Region::Rect *rect = new Region::Rect();
335     rect->x = 0x100;
336     rect->y = 0x100;
337     rect->w = 0x100;
338     rect->h = 0x100;
339     region->rects = rect;
340     ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, fenceFd, *region);
341     ASSERT_EQ(ret, GSERROR_OK);
342     delete region;
343 
344     ret = OH_NativeImage_UpdateSurfaceImage(image);
345     ASSERT_EQ(ret, SURFACE_ERROR_OK);
346 }
347 
348 /*
349  * @tc.name: OHNativeImageGetTimestamp001
350  * @tc.desc: test for call OH_NativeImage_GetTimestamp by abnormal input and check ret.
351  * @tc.type: FUNC
352  */
353 HWTEST_F(NativeImageTest, OHNativeImageGetTimestamp001, Function | MediumTest | Level2)
354 {
355     int64_t timeStamp = OH_NativeImage_GetTimestamp(nullptr);
356     ASSERT_EQ(timeStamp, SURFACE_ERROR_ERROR);
357 }
358 
359 /*
360  * @tc.name: OHNativeImageGetTimestamp002
361  * @tc.desc: test for call OH_NativeImage_GetTimestamp and check ret.
362  * @tc.type: FUNC
363  */
364 HWTEST_F(NativeImageTest, OHNativeImageGetTimestamp002, Function | MediumTest | Level1)
365 {
366     int64_t timeStamp = OH_NativeImage_GetTimestamp(image);
367     ASSERT_NE(timeStamp, SURFACE_ERROR_ERROR);
368 }
369 
370 /*
371  * @tc.name: OHNativeImageGetTransformMatrix001
372  * @tc.desc: test for call OH_NativeImage_GetTransformMatrix by abnormal input and check ret.
373  * @tc.type: FUNC
374  */
375 HWTEST_F(NativeImageTest, OHNativeImageGetTransformMatrix001, Function | MediumTest | Level2)
376 {
377     float matrix[16];
378     int32_t ret = OH_NativeImage_GetTransformMatrix(nullptr, matrix);
379     ASSERT_NE(ret, SURFACE_ERROR_OK);
380 }
381 
382 /*
383  * @tc.name: OHNativeImageGetTransformMatrix002
384  * @tc.desc: test for call OH_NativeImage_GetTransformMatrix and check ret.
385  * @tc.type: FUNC
386  */
387 HWTEST_F(NativeImageTest, OHNativeImageGetTransformMatrix002, Function | MediumTest | Level1)
388 {
389     float matrix[16];
390     int32_t ret = OH_NativeImage_GetTransformMatrix(image, matrix);
391     ASSERT_EQ(ret, SURFACE_ERROR_OK);
392 }
393 
394 /*
395  * @tc.name: OHNativeImageGetTransformMatrix003
396  * @tc.desc: test for call OH_NativeImage_GetTransformMatrix with another texture and check ret.
397  * @tc.type: FUNC
398  */
399 HWTEST_F(NativeImageTest, OHNativeImageAttachContext003, Function | MediumTest | Level1)
400 {
401     int32_t ret = OH_NativeImage_AttachContext(image, textureId2);
402     ASSERT_EQ(ret, SURFACE_ERROR_OK);
403 }
404 
405 /*
406  * @tc.name: OHNativeImageUpdateSurfaceImage004
407  * @tc.desc: test for OH_NativeImage_UpdateSurfaceImage after the OPENGL ES texture changed and check ret.
408  * @tc.type: FUNC
409  */
410 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage004, Function | MediumTest | Level1)
411 {
412     NativeWindowBuffer* nativeWindowBuffer = nullptr;
413     int fenceFd = -1;
414     int32_t ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
415     ASSERT_EQ(ret, GSERROR_OK);
416 
417     struct Region *region = new Region();
418     struct Region::Rect *rect = new Region::Rect();
419     rect->x = 0x100;
420     rect->y = 0x100;
421     rect->w = 0x100;
422     rect->h = 0x100;
423     region->rects = rect;
424     ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, fenceFd, *region);
425     ASSERT_EQ(ret, GSERROR_OK);
426     delete region;
427 
428     ret = OH_NativeImage_UpdateSurfaceImage(image);
429     ASSERT_EQ(ret, SURFACE_ERROR_OK);
430 }
431 
432 /*
433  * @tc.name: OHNativeImageDetachContext004
434  * @tc.desc: test for call OH_NativeImage_DetachContext and check ret.
435  * @tc.type: FUNC
436  */
437 HWTEST_F(NativeImageTest, OHNativeImageDetachContext004, Function | MediumTest | Level1)
438 {
439     int32_t ret = OH_NativeImage_DetachContext(image);
440     ASSERT_EQ(ret, SURFACE_ERROR_OK);
441 }
442 
443 /*
444  * @tc.name: OHNativeImageAttachContext004
445  * @tc.desc: test for call OH_NativeImage_AttachContext after OH_NativeImage_DetachContext and check ret.
446  * @tc.type: FUNC
447  */
448 HWTEST_F(NativeImageTest, OHNativeImageAttachContext004, Function | MediumTest | Level1)
449 {
450     int32_t ret = OH_NativeImage_AttachContext(image, textureId2);
451     ASSERT_EQ(ret, SURFACE_ERROR_OK);
452 }
453 
454 /*
455  * @tc.name: OHNativeImageUpdateSurfaceImage005
456  * @tc.desc: test for OHNativeImageUpdateSurfaceImage again and check ret.
457  * @tc.type: FUNC
458  */
459 HWTEST_F(NativeImageTest, OHNativeImageUpdateSurfaceImage005, Function | MediumTest | Level1)
460 {
461     NativeWindowBuffer* nativeWindowBuffer = nullptr;
462     int fenceFd = -1;
463     int32_t ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fenceFd);
464     ASSERT_EQ(ret, GSERROR_OK);
465 
466     struct Region *region = new Region();
467     struct Region::Rect *rect = new Region::Rect();
468     rect->x = 0x100;
469     rect->y = 0x100;
470     rect->w = 0x100;
471     rect->h = 0x100;
472     region->rects = rect;
473     ret = OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow, nativeWindowBuffer, fenceFd, *region);
474     ASSERT_EQ(ret, GSERROR_OK);
475     delete region;
476 
477     ret = OH_NativeImage_UpdateSurfaceImage(image);
478     ASSERT_EQ(ret, SURFACE_ERROR_OK);
479 }
480 
481 /*
482  * @tc.name: OHNativeImageDestroy001
483  * @tc.desc: test for call OH_NativeImage_Destroy by abnormal input and check ret.
484  * @tc.type: FUNC
485  */
486 HWTEST_F(NativeImageTest, OHNativeImageDestroy001, Function | MediumTest | Level2)
487 {
488     OH_NativeImage_Destroy(nullptr);
489     ASSERT_NE(image, nullptr);
490 }
491 
492 /*
493  * @tc.name: OHNativeImageDestroy002
494  * @tc.desc: test for call OH_NativeImage_Destroy and check ret.
495  * @tc.type: FUNC
496  */
497 HWTEST_F(NativeImageTest, OHNativeImageDestroy002, Function | MediumTest | Level1)
498 {
499     OH_NativeImage_Destroy(&image);
500     ASSERT_EQ(image, nullptr);
501 }
502 }