1 /*
2 * Copyright (c) 2021-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
16 #include "util/egl_manager.h"
17
18 #include <cstddef>
19 #include "EGL/egl.h"
20 #include "EGL/eglplatform.h"
21 #include "__config"
22 #include "util/log.h"
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28 namespace OHOS {
29 namespace Rosen {
30 namespace {
31 const int OPENGL_ES2_VERSION = 2;
32 const int OPENGL_ES3_VERSION = 3;
33 }
34 using namespace std;
35
GetConfig(int version,EGLDisplay eglDisplay)36 EGLConfig EglManager::GetConfig(int version, EGLDisplay eglDisplay)
37 {
38 EGLint renderableType = EGL_OPENGL_ES2_BIT;
39 if (version == OPENGL_ES3_VERSION) {
40 renderableType = EGL_OPENGL_ES3_BIT;
41 }
42 int attribList[] = {
43 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
44 EGL_RENDERABLE_TYPE, renderableType,
45 EGL_RED_SIZE, 8,
46 EGL_GREEN_SIZE, 8,
47 EGL_BLUE_SIZE, 8,
48 EGL_ALPHA_SIZE, 8,
49 EGL_DEPTH_SIZE, 24,
50 EGL_NONE
51 };
52 EGLConfig configs = NULL;
53 int numConfigs;
54 if (!eglChooseConfig(eglDisplay, attribList, &configs, 1, &numConfigs)) {
55 LOGE("eglChooseConfig ERROR");
56 return NULL;
57 }
58 return configs;
59 }
60
MakeCurrentIfNeeded(EGLSurface newEGLSurface)61 void EglManager::MakeCurrentIfNeeded(EGLSurface newEGLSurface)
62 {
63 if (currentSurface_ != newEGLSurface) {
64 currentSurface_ = newEGLSurface;
65 eglMakeCurrent(eglDisplay_, currentSurface_, currentSurface_, eglContext_);
66 }
67 }
68
CreateSurface(NativeWindow * window)69 EGLSurface EglManager::CreateSurface(NativeWindow* window)
70 {
71 EGLSurface eglSurface = nullptr;
72 if (window) {
73 LOGD("EglManager CreateSurface from eglWindow");
74 eglSurface = eglCreateWindowSurface(eglDisplay_, eglConfig_, window, NULL);
75 } else {
76 LOGD("EglManager CreateSurface from PBuffer width = %{public}d, height = %{public}d",
77 eglWidth_, eglHeight_);
78 int surfaceAttributes[] = {
79 EGL_WIDTH, eglWidth_,
80 EGL_HEIGHT, eglHeight_,
81 EGL_NONE
82 };
83 eglSurface = eglCreatePbufferSurface(eglDisplay_, eglConfig_, surfaceAttributes);
84 }
85 if (eglSurface == NULL) {
86 LOGE("EglManager CreateSurface eglSurface = null error %{public}d", eglGetError());
87 }
88 return eglSurface;
89 }
90
CreateContext(int version)91 void EglManager::CreateContext(int version)
92 {
93 if (eglWindow_) {
94 LOGD("EglManager Init eglSurface from eglWindow");
95 currentSurface_ = eglCreateWindowSurface(eglDisplay_, eglConfig_, eglWindow_, NULL);
96 if (currentSurface_ == NULL) {
97 LOGE("EglManager Init eglSurface = null");
98 return;
99 }
100 } else {
101 LOGD("EglManager Init eglSurface from PBuffer width = %{public}d, height = %{public}d",
102 eglWidth_, eglHeight_);
103 int surfaceAttributes[] = {
104 EGL_WIDTH, eglWidth_,
105 EGL_HEIGHT, eglHeight_,
106 EGL_NONE
107 };
108 currentSurface_ = eglCreatePbufferSurface(eglDisplay_, eglConfig_, surfaceAttributes);
109 if (currentSurface_ == NULL) {
110 LOGE("EglManager Init eglCreateContext eglSurface = null");
111 return;
112 }
113 }
114
115 int attrib3List[] = {
116 EGL_CONTEXT_CLIENT_VERSION, version,
117 EGL_NONE
118 };
119 eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, nullptr, attrib3List);
120 int error = eglGetError();
121 if (error == EGL_SUCCESS) {
122 LOGD("EglManager Init Create mEGLContext ok");
123 } else {
124 LOGE("EglManager Init eglCreateContext error %{public}x", error);
125 return;
126 }
127 eglMakeCurrent(eglDisplay_, currentSurface_, currentSurface_, eglContext_);
128 }
129
Init()130 void EglManager::Init()
131 {
132 if (initialized_) {
133 return;
134 }
135 initialized_ = true;
136 LOGD("EglManager Init.");
137 if (eglContext_ != nullptr) {
138 LOGE("EglManager Init mEGLContext is already init.");
139 return;
140 }
141
142 eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
143 if (eglDisplay_ == EGL_NO_DISPLAY) {
144 LOGE("EglManager Init unable to get EGL display.");
145 return;
146 }
147
148 EGLint eglMajVers, eglMinVers;
149 if (!eglInitialize(eglDisplay_, &eglMajVers, &eglMinVers)) {
150 eglDisplay_ = EGL_NO_DISPLAY;
151 LOGE("EglManager Init unable to initialize display");
152 return;
153 }
154
155 int version = OPENGL_ES3_VERSION;
156 eglConfig_ = EglManager::GetConfig(version, eglDisplay_);
157 if (eglConfig_ == NULL) {
158 LOGE("EglManager Init config ERROR, try again");
159 version = OPENGL_ES2_VERSION;
160 eglConfig_ = EglManager::GetConfig(version, eglDisplay_);
161 if (eglConfig_ == NULL) {
162 LOGE("EglManager Init config ERROR again");
163 return;
164 }
165 }
166 CreateContext(version);
167 }
168 } // namespace Rosen
169 } // namespace OHOS
170 #ifdef __cplusplus
171 }
172 #endif
173