• 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 "gl_egl_state.h"
16 #include <cstdint>
17 
18 #include "display_common.h"
19 #include "display_bytrace.h"
20 namespace OHOS {
21 namespace HDI {
22 namespace DISPLAY {
CheckEglExtension(const char * extensions,const char * extension)23 static bool CheckEglExtension(const char *extensions, const char *extension)
24 {
25     size_t extlen = strlen(extension);
26     const char *end = extensions + strlen(extensions);
27     constexpr char CHARACTER_WHITESPACE = ' ';
28     constexpr const char *CHARACTER_STRING_WHITESPACE = " ";
29     while (extensions < end) {
30         size_t n = 0;
31 
32         /* Skip whitespaces, if any */
33         if (*extensions == CHARACTER_WHITESPACE) {
34             extensions++;
35             continue;
36         }
37 
38         n = strcspn(extensions, CHARACTER_STRING_WHITESPACE);
39         /* Compare strings */
40         if (n == extlen && strncmp(extension, extensions, n) == 0) {
41             return true; /* Found */
42         }
43         extensions += n;
44     }
45     /* Not found */
46     return false;
47 }
48 
GetPlatformEglDisplay(EGLenum platform,void * native_display,const EGLint * attrib_list)49 static EGLDisplay GetPlatformEglDisplay(EGLenum platform, void *native_display, const EGLint *attrib_list)
50 {
51     using GetPlatformDisplayExt = PFNEGLGETPLATFORMDISPLAYEXTPROC;
52     constexpr const char *EGL_EXT_PLATFORM_WAYLAND = "EGL_EXT_platform_wayland";
53     constexpr const char *EGL_KHR_PLATFORM_WAYLAND = "EGL_KHR_platform_wayland";
54     constexpr const char *EGL_GET_PLATFORM_DISPLAY_EXT = "eglGetPlatformDisplayEXT";
55     static GetPlatformDisplayExt eglGetPlatformDisplayExt = NULL;
56 
57     if (!eglGetPlatformDisplayExt) {
58         const char *extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
59         if (extensions && (CheckEglExtension(extensions, EGL_EXT_PLATFORM_WAYLAND) ||
60             CheckEglExtension(extensions, EGL_KHR_PLATFORM_WAYLAND))) {
61             eglGetPlatformDisplayExt = (GetPlatformDisplayExt)eglGetProcAddress(EGL_GET_PLATFORM_DISPLAY_EXT);
62         }
63     }
64 
65     if (eglGetPlatformDisplayExt) {
66         return eglGetPlatformDisplayExt(platform, native_display, attrib_list);
67     }
68 
69     return eglGetDisplay((EGLNativeDisplayType)native_display);
70 }
71 
Init(const EGLint surfaceType)72 bool GlEglState::Init(const EGLint surfaceType)
73 {
74     uint32_t ret;
75     DISPLAY_LOGD();
76     eglDisplay_ = GetPlatformEglDisplay(EGL_PLATFORM_OHOS_KHR, EGL_DEFAULT_DISPLAY, nullptr);
77     DISPLAY_CHK_RETURN((eglDisplay_ == EGL_NO_DISPLAY), false,
78         DISPLAY_LOGE("can not get eglDisplay glerror : %{puiblic}d", eglGetError()));
79 
80     EGLint major = 0, minor = 0;
81     ret = eglInitialize(eglDisplay_, &major, &minor);
82     DISPLAY_CHK_RETURN((ret == EGL_FALSE), false,
83         DISPLAY_LOGE("egl initialize failed glerror : %{public}d", eglGetError()));
84 
85     ret = eglBindAPI(EGL_OPENGL_ES_API);
86     DISPLAY_CHK_RETURN((ret == EGL_FALSE), false,
87         DISPLAY_LOGE("egl bind OpenGL ES API failed glerror : %{public}d", eglGetError()));
88 
89     EGLint outNum;
90     EGLint configAttr[] = {EGL_SURFACE_TYPE, surfaceType, EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8,
91                            EGL_ALPHA_SIZE, 8, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE};
92     ret = eglChooseConfig(eglDisplay_, configAttr, &eglConfig_, 1, &outNum);
93     DISPLAY_CHK_RETURN(((ret == EGL_FALSE) || (outNum < 1)), false,
94         DISPLAY_LOGE("Failed to choose egl config glerror %{public}d", eglGetError()));
95 
96     constexpr EGLint EGL_CONTEXT_CLIENT_VERSION_NUM = 2;
97     static const EGLint contextAttr[] = {
98         EGL_CONTEXT_CLIENT_VERSION, EGL_CONTEXT_CLIENT_VERSION_NUM,
99         EGL_NONE
100     };
101     eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, EGL_NO_CONTEXT, contextAttr);
102     DISPLAY_CHK_RETURN((ret == EGL_FALSE), false,
103         DISPLAY_LOGE("Failed to create egl context glerror : %{public}d", eglGetError()));
104     return true;
105 }
106 
Init(uint32_t width,uint32_t height)107 bool GlEglState::Init(uint32_t width, uint32_t height)
108 {
109     if (!Init(EGL_PBUFFER_BIT)) {
110         DISPLAY_LOGE("Init failed");
111     }
112     EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
113     eglSurface_ = eglCreatePbufferSurface(eglDisplay_, eglConfig_, attribs);
114     if (eglSurface_ == EGL_NO_SURFACE) {
115         DISPLAY_LOGE("Failed to create eglsurface %{public}x", eglGetError());
116     }
117     return true;
118 }
119 
Init(NativeWindowType window)120 bool GlEglState::Init(NativeWindowType window)
121 {
122     if (window == nullptr) {
123         return false;
124     }
125     if (!Init(EGL_WINDOW_BIT)) {
126         DISPLAY_LOGE("Init failed");
127         return false;
128     }
129     nativeWindow_ = window;
130     CreateEglSurface(nativeWindow_);
131     return true;
132 }
133 
MakeCurrent()134 void GlEglState::MakeCurrent()
135 {
136     DISPLAY_LOGD();
137     if (!eglMakeCurrent(eglDisplay_, eglSurface_, eglSurface_, eglContext_)) {
138         DISPLAY_LOGE("can not make cuurent glerror %{public}d", eglGetError());
139     }
140 }
141 
SwapBuffer()142 void GlEglState::SwapBuffer()
143 {
144     DisplayBytrace trace = DisplayBytrace("SwapBuffer");
145     DISPLAY_LOGD();
146     if (!eglSwapBuffers(eglDisplay_, eglSurface_)) {
147         DISPLAY_LOGE("Failed to SwapBuffers on surface %{public}p glerror %{public}d", eglSurface_, eglGetError());
148     }
149 }
150 
CreateEglSurface(EGLNativeWindowType nativeWindow)151 void GlEglState::CreateEglSurface(EGLNativeWindowType nativeWindow)
152 {
153     uint32_t ret = eglMakeCurrent(eglDisplay_, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
154     if (!ret) {
155         DISPLAY_LOGW("Failed to make current glerror %{public}x", eglGetError());
156     }
157     eglSurface_ = eglCreateWindowSurface(eglDisplay_, eglConfig_, nativeWindow, nullptr);
158     if (eglSurface_ == EGL_NO_SURFACE) {
159         DISPLAY_LOGE("Failed to create eglsurface %{public}x", eglGetError());
160     }
161 }
162 }
163 }
164 }