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
Init()91 void EglManager::Init()
92 {
93 if (initialized_) {
94 return;
95 }
96 initialized_ = true;
97 LOGD("EglManag Init.");
98 if (eglContext_ != nullptr) {
99 LOGE("EglManager Init mEGLContext is already init.");
100 return;
101 }
102
103 eglDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY);
104 if (eglDisplay_ == EGL_NO_DISPLAY) {
105 LOGE("EglManager Init unable to get EGL display.");
106 return;
107 }
108
109 EGLint eglMajVers, eglMinVers;
110 if (!eglInitialize(eglDisplay_, &eglMajVers, &eglMinVers)) {
111 eglDisplay_ = EGL_NO_DISPLAY;
112 LOGE("EglManager Init unable to initialize display");
113 return;
114 }
115
116 int version = OPENGL_ES3_VERSION;
117 eglConfig_ = EglManager::GetConfig(version, eglDisplay_);
118 if (eglConfig_ == NULL) {
119 LOGE("EglManager Init config ERROR, try again");
120 version = OPENGL_ES2_VERSION;
121 eglConfig_ = EglManager::GetConfig(version, eglDisplay_);
122 if (eglConfig_ == NULL) {
123 LOGE("EglManager Init config ERROR again");
124 return;
125 }
126 }
127
128 if (eglWindow_) {
129 LOGD("EglManager Init eglSurface from eglWindow");
130 currentSurface_ = eglCreateWindowSurface(eglDisplay_, eglConfig_, eglWindow_, NULL);
131 if (currentSurface_ == NULL) {
132 LOGE("EglManager Init eglSurface = null");
133 return;
134 }
135 } else {
136 LOGD("EglManager Init eglSurface from PBuffer width = %{public}d, height = %{public}d",
137 eglWidth_, eglHeight_);
138 int surfaceAttributes[] = {
139 EGL_WIDTH, eglWidth_,
140 EGL_HEIGHT, eglHeight_,
141 EGL_NONE
142 };
143 currentSurface_ = eglCreatePbufferSurface(eglDisplay_, eglConfig_, surfaceAttributes);
144 if (currentSurface_ == NULL) {
145 LOGE("EglManager Init eglCreateContext eglSurface = null");
146 return;
147 }
148 }
149
150 int attrib3List[] = {
151 EGL_CONTEXT_CLIENT_VERSION, version,
152 EGL_NONE
153 };
154 eglContext_ = eglCreateContext(eglDisplay_, eglConfig_, nullptr, attrib3List);
155 int error = eglGetError();
156 if (error == EGL_SUCCESS) {
157 LOGD("EglManager Init Create mEGLContext ok");
158 } else {
159 LOGE("EglManager Init eglCreateContext error %{public}x", error);
160 }
161 eglMakeCurrent(eglDisplay_, currentSurface_, currentSurface_, eglContext_);
162 }
163 } // namespace Rosen
164 } // namespace OHOS
165 #ifdef __cplusplus
166 }
167 #endif
168