1 /*
2 * Copyright (c) 2021 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 "egl_core.h"
17
18 #include <EGL/egl.h>
19 #include <GLES3/gl3.h>
20 #include "plugin_common.h"
21 #include "plugin_render.h"
22
23 namespace {
getConfig(int version,EGLDisplay eglDisplay)24 EGLConfig getConfig(int version, EGLDisplay eglDisplay)
25 {
26 int attribList[] = {
27 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
28 EGL_RED_SIZE, 8,
29 EGL_GREEN_SIZE, 8,
30 EGL_BLUE_SIZE, 8,
31 EGL_ALPHA_SIZE, 8,
32 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
33 EGL_NONE
34 };
35 EGLConfig configs = NULL;
36 int configsNum;
37 if (!eglChooseConfig(eglDisplay, attribList, &configs, 1, &configsNum)) {
38 LOGE("eglChooseConfig ERROR");
39 return NULL;
40 }
41 return configs;
42 }
43 }
44
45
46 char vertexShader[] =
47 "#version 300 es\n"
48 "layout(location = 0) in vec4 a_position;\n"
49 "layout(location = 1) in vec4 a_color;\n"
50 "out vec4 v_color;\n"
51 "void main()\n"
52 "{\n"
53 " gl_Position = a_position;\n"
54 " v_color = a_color;\n"
55 "}\n";
56
57 char fragmentShader[] =
58 "#version 300 es\n"
59 "precision mediump float;\n"
60 "in vec4 v_color;\n"
61 "out vec4 fragColor;\n"
62 "void main()\n"
63 "{\n"
64 " fragColor = v_color;\n"
65 "}\n";
66
GLContextInit(void * window,int w,int h)67 void EGLCore::GLContextInit(void* window, int w, int h)
68 {
69 LOGD("EGLCore::GLContextInit window = %{public}p, w = %{public}d, h = %{public}d.", window, w, h);
70 width_ = w;
71 height_ = h;
72 mEglWindow = reinterpret_cast<EGLNativeWindowType>(window);
73
74 // 1. create sharedcontext
75 mEGLDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
76 if (mEGLDisplay == EGL_NO_DISPLAY) {
77 LOGE("EGLCore::unable to get EGL display.");
78 return;
79 }
80
81 EGLint eglMajVers, eglMinVers;
82 if (!eglInitialize(mEGLDisplay, &eglMajVers, &eglMinVers)) {
83 mEGLDisplay = EGL_NO_DISPLAY;
84 LOGE("EGLCore::unable to initialize display");
85 return;
86 }
87
88 int version = 3;
89 mEGLConfig = getConfig(version, mEGLDisplay);
90 if (mEGLConfig == nullptr) {
91 LOGE("EGLCore::GLContextInit config ERROR");
92 return;
93 }
94
95 // 2. Create EGL Surface from Native Window
96 EGLint winAttribs[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE};
97 if (mEglWindow) {
98 mEGLSurface = eglCreateWindowSurface(mEGLDisplay, mEGLConfig, mEglWindow, winAttribs);
99 if (mEGLSurface == nullptr) {
100 LOGE("EGLCore::eglCreateContext eglSurface is null");
101 return;
102 }
103 }
104
105 // 3. Create EGLContext from
106 int attrib3_list[] = {
107 EGL_CONTEXT_CLIENT_VERSION, 2,
108 EGL_NONE
109 };
110 mEGLContext = eglCreateContext(mEGLDisplay, mEGLConfig, mSharedEGLContext, attrib3_list);
111 if (!eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
112 LOGE("EGLCore::eglMakeCurrent error = %{public}d", eglGetError());
113 }
114 mProgramHandle = CreateProgram(vertexShader, fragmentShader);
115 if (!mProgramHandle) {
116 LOGE("EGLCore::Could not create CreateProgram");
117 return;
118 }
119 DrawTriangle();
120 }
121
DrawTriangle()122 void EGLCore::DrawTriangle()
123 {
124 GLfloat color[] = {
125 0.5f, 0.6f, 0.3f, 1.0f
126 };
127
128 const GLfloat triangleVertices[] = {
129 0.0f, 1.0f,
130 -1.0f, -1.0f,
131 1.0f, -1.0f
132 };
133 glViewport(0, 0, width_, height_);
134 glClearColor(0.0, 0.0, 0.0, 1.0);
135 glClear(GL_COLOR_BUFFER_BIT);
136 glUseProgram(mProgramHandle);
137 GLint positionHandle = glGetAttribLocation(mProgramHandle, "a_position");
138 int vertexsize = 2;
139 glVertexAttribPointer(positionHandle, vertexsize, GL_FLOAT, GL_FALSE, 0, triangleVertices);
140 glEnableVertexAttribArray(positionHandle);
141 glVertexAttrib4fv(1, color);
142 int count = 3;
143 glDrawArrays(GL_TRIANGLES, 0, count);
144 glDisableVertexAttribArray(positionHandle);
145
146 glFlush();
147 glFinish();
148 eglSwapBuffers(mEGLDisplay, mEGLSurface);
149 }
150
ChangeShape()151 void EGLCore::ChangeShape()
152 {
153 if (!eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
154 LOGE("EGLCore::eglMakeCurrent error = %{public}d", eglGetError());
155 }
156
157 GLfloat color[] = {
158 0.7f, 0.2f, 0.2f, 1.0f
159 };
160
161 const GLfloat triangleVertices[] = {
162 -1.0f, 1.0f,
163 -1.0f, -1.0f,
164 1.0f, 0.0f
165 };
166
167 glViewport(0, 0, width_, height_);
168 glClearColor(0.0, 0.0, 0.0, 1.0);
169 glClear(GL_COLOR_BUFFER_BIT);
170 glUseProgram(mProgramHandle);
171 GLint positionHandle = glGetAttribLocation(mProgramHandle, "a_position");
172 int vertexsize = 2;
173 glVertexAttribPointer(positionHandle, vertexsize, GL_FLOAT, GL_FALSE, 0, triangleVertices);
174 glEnableVertexAttribArray(positionHandle);
175 glVertexAttrib4fv(1, color);
176 int count = 3;
177 glDrawArrays(GL_TRIANGLES, 0, count);
178 glDisableVertexAttribArray(positionHandle);
179
180 Update();
181 }
182
ChangeColor()183 void EGLCore::ChangeColor()
184 {
185 if (!eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) {
186 LOGE("EGLCore::eglMakeCurrent error = %{public}d", eglGetError());
187 }
188
189 GLfloat color[] = {
190 0.9f, 0.5f, 0.7f, 1.0f
191 };
192
193 const GLfloat triangleVertices[] = {
194 0.0f, 1.0f,
195 -1.0f, -1.0f,
196 1.0f, -1.0f
197 };
198
199 glViewport(0, 0, width_, height_);
200 glClearColor(0.0, 0.0, 0.0, 1.0);
201 glClear(GL_COLOR_BUFFER_BIT);
202 glUseProgram(mProgramHandle);
203 GLint positionHandle = glGetAttribLocation(mProgramHandle, "a_position");
204 int vertexsize = 2;
205 glVertexAttribPointer(positionHandle, vertexsize, GL_FLOAT, GL_FALSE, 0, triangleVertices);
206 glEnableVertexAttribArray(positionHandle);
207 glVertexAttrib4fv(1, color);
208 int count = 3;
209 glDrawArrays(GL_TRIANGLES, 0, count);
210 glDisableVertexAttribArray(positionHandle);
211
212 Update();
213 }
214
Update()215 void EGLCore::Update()
216 {
217 eglSwapBuffers(mEGLDisplay, mEGLSurface);
218 }
219
LoadShader(GLenum type,const char * shaderSrc)220 GLuint EGLCore::LoadShader(GLenum type, const char *shaderSrc)
221 {
222 GLuint shader;
223 GLint compiled;
224
225 shader = glCreateShader(type);
226 if (shader == 0) {
227 LOGE("LoadShader shader error");
228 return 0;
229 }
230
231 glShaderSource(shader, 1, &shaderSrc, nullptr);
232 glCompileShader(shader);
233
234 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
235
236 if (!compiled) {
237 GLint infoLen = 0;
238 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
239
240 if (infoLen > 1) {
241 char *infoLog = (char*)malloc(sizeof(char) * infoLen);
242 glGetShaderInfoLog(shader, infoLen, nullptr, infoLog);
243 LOGE("Error compiling shader:\n%s\n", infoLog);
244 free(infoLog);
245 }
246 glDeleteShader(shader);
247 return 0;
248 }
249 return shader;
250 }
251
CreateProgram(const char * vertexShader,const char * fragShader)252 GLuint EGLCore::CreateProgram(const char *vertexShader, const char *fragShader)
253 {
254 GLuint vertex;
255 GLuint fragment;
256 GLuint program;
257 GLint linked;
258
259 vertex = LoadShader(GL_VERTEX_SHADER, vertexShader);
260 if (vertex == 0) {
261 LOGE("CreateProgram vertex error");
262 return 0;
263 }
264
265 fragment = LoadShader(GL_FRAGMENT_SHADER, fragShader);
266 if (fragment == 0) {
267 LOGE("CreateProgram fragment error");
268 glDeleteShader(vertex);
269 return 0;
270 }
271
272 program = glCreateProgram();
273 if (program == 0) {
274 LOGE("CreateProgram program error");
275 glDeleteShader(vertex);
276 glDeleteShader(fragment);
277 return 0;
278 }
279
280 glAttachShader(program, vertex);
281 glAttachShader(program, fragment);
282 glLinkProgram(program);
283 glGetProgramiv(program, GL_LINK_STATUS, &linked);
284
285 if (!linked) {
286 LOGE("CreateProgram linked error");
287 GLint infoLen = 0;
288 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLen);
289 if (infoLen > 1) {
290 char *infoLog = (char *)malloc(sizeof(char) * infoLen);
291 glGetProgramInfoLog(program, infoLen, nullptr, infoLog);
292 LOGE("Error linking program:\n%s\n", infoLog);
293 free(infoLog);
294 }
295 glDeleteShader(vertex);
296 glDeleteShader(fragment);
297 glDeleteProgram(program);
298 return 0;
299 }
300 glDeleteShader(vertex);
301 glDeleteShader(fragment);
302
303 return program;
304 }
305
checkGlError(const char * op)306 bool EGLCore::checkGlError(const char* op)
307 {
308 LOGE("EGL ERROR CODE = %{public}x", eglGetError());
309 for (GLint error = glGetError(); error; error = glGetError()) {
310 LOGE("ERROR: %{public}s, ERROR CODE = %{public}x", op, error);
311 return true;
312 }
313 return false;
314 }