blob: 35e1932c5af407a94700a1be18aadea83987c2d3 [file] [log] [blame]
Arun Kumar K.R2b75da32016-11-11 14:37:20 -08001/*
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -08002 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
Arun Kumar K.R2b75da32016-11-11 14:37:20 -08003 * Not a Contribution.
4 *
5 * Copyright 2015 The Android Open Source Project
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20#include "glengine.h"
Naseer Ahmed04a804a2018-03-06 20:41:14 -050021#include <log/log.h>
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080022#include "engine.h"
23
24void checkGlError(const char *, int);
25void checkEglError(const char *, int);
26
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080027class EngineContext {
28 public:
29 EGLDisplay eglDisplay;
30 EGLContext eglContext;
31 EGLSurface eglSurface;
32 EngineContext()
33 {
34 eglDisplay = EGL_NO_DISPLAY;
35 eglContext = EGL_NO_CONTEXT;
36 eglSurface = EGL_NO_SURFACE;
37 }
38};
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080039
40//-----------------------------------------------------------------------------
41// Make Current
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080042void engine_bind(void* context)
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080043//-----------------------------------------------------------------------------
44{
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080045 EngineContext* engineContext = (EngineContext*)(context);
46 EGL(eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080047}
48
49//-----------------------------------------------------------------------------
50// initialize GL
51//
Sushil Chauhan70bc2c02017-05-02 17:09:47 -070052void* engine_initialize(bool isSecure)
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080053//-----------------------------------------------------------------------------
54{
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080055 EngineContext* engineContext = new EngineContext();
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080056
57 // display
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080058 engineContext->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080059 EGL(eglBindAPI(EGL_OPENGL_ES_API));
60
61 // initialize
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080062 EGL(eglInitialize(engineContext->eglDisplay, 0, 0));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080063
64 // config
65 EGLConfig eglConfig;
66 EGLint eglConfigAttribList[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
67 EGL_RED_SIZE, 8,
68 EGL_GREEN_SIZE, 8,
69 EGL_BLUE_SIZE, 8,
70 EGL_ALPHA_SIZE, 8,
71 EGL_NONE};
72 int numConfig = 0;
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080073 EGL(eglChooseConfig(engineContext->eglDisplay, eglConfigAttribList, &eglConfig, 1, &numConfig));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080074
75 // context
Sushil Chauhan70bc2c02017-05-02 17:09:47 -070076 EGLint eglContextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3,
77 isSecure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
78 isSecure ? EGL_TRUE : EGL_NONE,
79 EGL_NONE};
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080080 engineContext->eglContext = eglCreateContext(engineContext->eglDisplay, eglConfig, NULL, eglContextAttribList);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080081
82 // surface
Sushil Chauhan70bc2c02017-05-02 17:09:47 -070083 EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1,
84 EGL_HEIGHT, 1,
85 isSecure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
86 isSecure ? EGL_TRUE : EGL_NONE,
87 EGL_NONE};
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080088 engineContext->eglSurface = eglCreatePbufferSurface(engineContext->eglDisplay, eglConfig, eglSurfaceAttribList);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080089
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080090 eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080091
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080092 ALOGI("In %s context = %p", __FUNCTION__, (void *)(engineContext->eglContext));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080093
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080094 return (void*)(engineContext);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080095}
96
97//-----------------------------------------------------------------------------
98// Shutdown.
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080099void engine_shutdown(void* context)
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800100//-----------------------------------------------------------------------------
101{
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800102 EngineContext* engineContext = (EngineContext*)context;
103 EGL(eglMakeCurrent(engineContext->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
104 EGL(eglDestroySurface(engineContext->eglDisplay, engineContext->eglSurface));
105 EGL(eglDestroyContext(engineContext->eglDisplay, engineContext->eglContext));
106 EGL(eglTerminate(engineContext->eglDisplay));
107 engineContext->eglDisplay = EGL_NO_DISPLAY;
108 engineContext->eglContext = EGL_NO_CONTEXT;
109 engineContext->eglSurface = EGL_NO_SURFACE;
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800110}
111
112//-----------------------------------------------------------------------------
113void engine_deleteInputBuffer(unsigned int id)
114//-----------------------------------------------------------------------------
115{
116 if (id != 0) {
117 GL(glDeleteTextures(1, &id));
118 }
119}
120
121//-----------------------------------------------------------------------------
122void engine_deleteProgram(unsigned int id)
123//-----------------------------------------------------------------------------
124{
125 if (id != 0) {
126 GL(glDeleteProgram(id));
127 }
128}
129
130//-----------------------------------------------------------------------------
Arun Kumar K.R1d1e57d2017-02-16 19:12:20 -0800131void engine_setData2f(int location, float* data)
132//-----------------------------------------------------------------------------
133{
134 GL(glUniform2f(location, data[0], data[1]));
135}
136
137//-----------------------------------------------------------------------------
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800138unsigned int engine_load3DTexture(void *colorMapData, int sz, int format)
139//-----------------------------------------------------------------------------
140{
141 GLuint texture = 0;
142 GL(glGenTextures(1, &texture));
143 GL(glBindTexture(GL_TEXTURE_3D, texture));
144 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
145 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
146 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
147 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
148 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
149
150 GL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB10_A2, sz, sz, sz, 0, GL_RGBA,
151 GL_UNSIGNED_INT_2_10_10_10_REV, colorMapData));
152
153 return texture;
154}
155//-----------------------------------------------------------------------------
156unsigned int engine_load1DTexture(void *data, int sz, int format)
157//-----------------------------------------------------------------------------
158{
159 GLuint texture = 0;
160 if ((data != 0) && (sz != 0)) {
161 GL(glGenTextures(1, &texture));
162 GL(glBindTexture(GL_TEXTURE_2D, texture));
163 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
164 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
165 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
166 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
167
168 GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, sz, 1, 0, GL_RGBA,
169 GL_UNSIGNED_INT_2_10_10_10_REV, data));
170 }
171 return texture;
172}
173
174//-----------------------------------------------------------------------------
175void dumpShaderLog(int shader)
176//-----------------------------------------------------------------------------
177{
Pramodh Kumar Mukundab89f2452017-01-27 14:58:59 +0530178 int success = 0;
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800179 GLchar infoLog[512];
180 GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));
181 if (!success) {
182 glGetShaderInfoLog(shader, 512, NULL, infoLog);
183 ALOGI("Shader Failed to compile: %s\n", infoLog);
184 }
185}
186
187//-----------------------------------------------------------------------------
188GLuint engine_loadProgram(int vertexEntries, const char **vertex, int fragmentEntries,
189 const char **fragment)
190//-----------------------------------------------------------------------------
191{
192 GLuint progId = glCreateProgram();
193
194 int vertId = glCreateShader(GL_VERTEX_SHADER);
195 int fragId = glCreateShader(GL_FRAGMENT_SHADER);
196
197 GL(glShaderSource(vertId, vertexEntries, vertex, 0));
198 GL(glCompileShader(vertId));
199 dumpShaderLog(vertId);
200
201 GL(glShaderSource(fragId, fragmentEntries, fragment, 0));
202 GL(glCompileShader(fragId));
203 dumpShaderLog(fragId);
204
205 GL(glAttachShader(progId, vertId));
206 GL(glAttachShader(progId, fragId));
207
208 GL(glLinkProgram(progId));
209
210 GL(glDetachShader(progId, vertId));
211 GL(glDetachShader(progId, fragId));
212
213 GL(glDeleteShader(vertId));
214 GL(glDeleteShader(fragId));
215
216 return progId;
217}
218
219//-----------------------------------------------------------------------------
220void WaitOnNativeFence(int fd)
221//-----------------------------------------------------------------------------
222{
223 if (fd != -1) {
224 EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
225
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800226 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800227
228 if (sync == EGL_NO_SYNC_KHR) {
229 ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__);
230 } else {
231 // the gpu will wait for this sync - not this cpu thread.
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800232 EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
233 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800234 }
235 }
236}
237
238//-----------------------------------------------------------------------------
239int CreateNativeFence()
240//-----------------------------------------------------------------------------
241{
242 int fd = -1;
243
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800244 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800245 GL(glFlush());
246 if (sync == EGL_NO_SYNC_KHR) {
247 ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
248 } else {
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800249 fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800250 if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
251 ALOGE("%s - Failed to dup sync", __FUNCTION__);
252 }
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800253 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800254 }
255
256 return fd;
257}
258
259//-----------------------------------------------------------------------------
260void engine_setDestination(int id, int x, int y, int w, int h)
261//-----------------------------------------------------------------------------
262{
263 GL(glBindFramebuffer(GL_FRAMEBUFFER, id));
264 GL(glViewport(x, y, w, h));
265}
266
267//-----------------------------------------------------------------------------
268void engine_setProgram(int id)
269//-----------------------------------------------------------------------------
270{
271 GL(glUseProgram(id));
272}
273
274//-----------------------------------------------------------------------------
275void engine_set2DInputBuffer(int binding, unsigned int id)
276//-----------------------------------------------------------------------------
277{
278 GL(glActiveTexture(GL_TEXTURE0 + binding));
279 GL(glBindTexture(GL_TEXTURE_2D, id));
280}
281
282//-----------------------------------------------------------------------------
283void engine_set3DInputBuffer(int binding, unsigned int id)
284//-----------------------------------------------------------------------------
285{
286 GL(glActiveTexture(GL_TEXTURE0 + binding));
287 GL(glBindTexture(GL_TEXTURE_3D, id));
288}
289
290//-----------------------------------------------------------------------------
291void engine_setExternalInputBuffer(int binding, unsigned int id)
292//-----------------------------------------------------------------------------
293{
294 GL(glActiveTexture(GL_TEXTURE0 + binding));
295 GL(glBindTexture(0x8D65, id));
296}
297
298//-----------------------------------------------------------------------------
299int engine_blit(int srcFenceFd)
300//-----------------------------------------------------------------------------
301{
302 int fd = -1;
303 WaitOnNativeFence(srcFenceFd);
304 float fullscreen_vertices[]{0.0f, 2.0f, 0.0f, 0.0f, 2.0f, 0.0f};
305 GL(glEnableVertexAttribArray(0));
306 GL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, fullscreen_vertices));
307 GL(glDrawArrays(GL_TRIANGLES, 0, 3));
308 fd = CreateNativeFence();
309 GL(glFlush());
310 return fd;
311}
312
313//-----------------------------------------------------------------------------
314void checkGlError(const char *file, int line)
315//-----------------------------------------------------------------------------
316{
317 for (GLint error = glGetError(); error; error = glGetError()) {
318 char *pError;
319 switch (error) {
320 case GL_NO_ERROR:
321 pError = (char *)"GL_NO_ERROR";
322 break;
323 case GL_INVALID_ENUM:
324 pError = (char *)"GL_INVALID_ENUM";
325 break;
326 case GL_INVALID_VALUE:
327 pError = (char *)"GL_INVALID_VALUE";
328 break;
329 case GL_INVALID_OPERATION:
330 pError = (char *)"GL_INVALID_OPERATION";
331 break;
332 case GL_OUT_OF_MEMORY:
333 pError = (char *)"GL_OUT_OF_MEMORY";
334 break;
335 case GL_INVALID_FRAMEBUFFER_OPERATION:
336 pError = (char *)"GL_INVALID_FRAMEBUFFER_OPERATION";
337 break;
338
339 default:
340 ALOGE("glError (0x%x) %s:%d\n", error, file, line);
341 return;
342 }
343
344 ALOGE("glError (%s) %s:%d\n", pError, file, line);
345 return;
346 }
347 return;
348}
349
350//-----------------------------------------------------------------------------
351void checkEglError(const char *file, int line)
352//-----------------------------------------------------------------------------
353{
354 for (int i = 0; i < 5; i++) {
355 const EGLint error = eglGetError();
356 if (error == EGL_SUCCESS) {
357 break;
358 }
359
360 char *pError;
361 switch (error) {
362 case EGL_SUCCESS:
363 pError = (char *)"EGL_SUCCESS";
364 break;
365 case EGL_NOT_INITIALIZED:
366 pError = (char *)"EGL_NOT_INITIALIZED";
367 break;
368 case EGL_BAD_ACCESS:
369 pError = (char *)"EGL_BAD_ACCESS";
370 break;
371 case EGL_BAD_ALLOC:
372 pError = (char *)"EGL_BAD_ALLOC";
373 break;
374 case EGL_BAD_ATTRIBUTE:
375 pError = (char *)"EGL_BAD_ATTRIBUTE";
376 break;
377 case EGL_BAD_CONTEXT:
378 pError = (char *)"EGL_BAD_CONTEXT";
379 break;
380 case EGL_BAD_CONFIG:
381 pError = (char *)"EGL_BAD_CONFIG";
382 break;
383 case EGL_BAD_CURRENT_SURFACE:
384 pError = (char *)"EGL_BAD_CURRENT_SURFACE";
385 break;
386 case EGL_BAD_DISPLAY:
387 pError = (char *)"EGL_BAD_DISPLAY";
388 break;
389 case EGL_BAD_SURFACE:
390 pError = (char *)"EGL_BAD_SURFACE";
391 break;
392 case EGL_BAD_MATCH:
393 pError = (char *)"EGL_BAD_MATCH";
394 break;
395 case EGL_BAD_PARAMETER:
396 pError = (char *)"EGL_BAD_PARAMETER";
397 break;
398 case EGL_BAD_NATIVE_PIXMAP:
399 pError = (char *)"EGL_BAD_NATIVE_PIXMAP";
400 break;
401 case EGL_BAD_NATIVE_WINDOW:
402 pError = (char *)"EGL_BAD_NATIVE_WINDOW";
403 break;
404 case EGL_CONTEXT_LOST:
405 pError = (char *)"EGL_CONTEXT_LOST";
406 break;
407 default:
408 ALOGE("eglError (0x%x) %s:%d\n", error, file, line);
409 return;
410 }
411 ALOGE("eglError (%s) %s:%d\n", pError, file, line);
412 return;
413 }
414 return;
415}