blob: 6cfe15f5079c9515c4d399a217e8ccf79ba2a66f [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"
21#include <utils/Log.h>
22#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//-----------------------------------------------------------------------------
Arun Kumar K.R99ff47d2017-02-20 20:07:48 +053050// store the current context(caller)
51void* engine_backup()
52{
53 EngineContext* callerContext = new EngineContext();
54 // store the previous display/context
55 callerContext->eglDisplay = eglGetCurrentDisplay();
56 callerContext->eglContext = eglGetCurrentContext();
57 callerContext->eglSurface = eglGetCurrentSurface(EGL_DRAW);
58
59 return (void*)callerContext;
60}
61//-----------------------------------------------------------------------------
62// frees the backed up caller context
63void engine_free_backup(void* context)
64{
65 EngineContext* callerContext = (EngineContext*)(context);
66
67 delete callerContext;
68}
69
70//-----------------------------------------------------------------------------
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080071// initialize GL
72//
Sushil Chauhan70bc2c02017-05-02 17:09:47 -070073void* engine_initialize(bool isSecure)
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080074//-----------------------------------------------------------------------------
75{
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080076 EngineContext* engineContext = new EngineContext();
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080077
78 // display
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080079 engineContext->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080080 EGL(eglBindAPI(EGL_OPENGL_ES_API));
81
82 // initialize
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080083 EGL(eglInitialize(engineContext->eglDisplay, 0, 0));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080084
85 // config
86 EGLConfig eglConfig;
87 EGLint eglConfigAttribList[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
88 EGL_RED_SIZE, 8,
89 EGL_GREEN_SIZE, 8,
90 EGL_BLUE_SIZE, 8,
91 EGL_ALPHA_SIZE, 8,
92 EGL_NONE};
93 int numConfig = 0;
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080094 EGL(eglChooseConfig(engineContext->eglDisplay, eglConfigAttribList, &eglConfig, 1, &numConfig));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080095
96 // context
Sushil Chauhan70bc2c02017-05-02 17:09:47 -070097 EGLint eglContextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3,
98 isSecure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
99 isSecure ? EGL_TRUE : EGL_NONE,
100 EGL_NONE};
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800101 engineContext->eglContext = eglCreateContext(engineContext->eglDisplay, eglConfig, NULL, eglContextAttribList);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800102
103 // surface
Sushil Chauhan70bc2c02017-05-02 17:09:47 -0700104 EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1,
105 EGL_HEIGHT, 1,
106 isSecure ? EGL_PROTECTED_CONTENT_EXT : EGL_NONE,
107 isSecure ? EGL_TRUE : EGL_NONE,
108 EGL_NONE};
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800109 engineContext->eglSurface = eglCreatePbufferSurface(engineContext->eglDisplay, eglConfig, eglSurfaceAttribList);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800110
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800111 eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800112
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800113 ALOGI("In %s context = %p", __FUNCTION__, (void *)(engineContext->eglContext));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800114
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800115 return (void*)(engineContext);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800116}
117
118//-----------------------------------------------------------------------------
119// Shutdown.
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800120void engine_shutdown(void* context)
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800121//-----------------------------------------------------------------------------
122{
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800123 EngineContext* engineContext = (EngineContext*)context;
124 EGL(eglMakeCurrent(engineContext->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
125 EGL(eglDestroySurface(engineContext->eglDisplay, engineContext->eglSurface));
126 EGL(eglDestroyContext(engineContext->eglDisplay, engineContext->eglContext));
127 EGL(eglTerminate(engineContext->eglDisplay));
128 engineContext->eglDisplay = EGL_NO_DISPLAY;
129 engineContext->eglContext = EGL_NO_CONTEXT;
130 engineContext->eglSurface = EGL_NO_SURFACE;
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800131}
132
133//-----------------------------------------------------------------------------
134void engine_deleteInputBuffer(unsigned int id)
135//-----------------------------------------------------------------------------
136{
137 if (id != 0) {
138 GL(glDeleteTextures(1, &id));
139 }
140}
141
142//-----------------------------------------------------------------------------
143void engine_deleteProgram(unsigned int id)
144//-----------------------------------------------------------------------------
145{
146 if (id != 0) {
147 GL(glDeleteProgram(id));
148 }
149}
150
151//-----------------------------------------------------------------------------
Arun Kumar K.R1d1e57d2017-02-16 19:12:20 -0800152void engine_setData2f(int location, float* data)
153//-----------------------------------------------------------------------------
154{
155 GL(glUniform2f(location, data[0], data[1]));
156}
157
158//-----------------------------------------------------------------------------
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800159unsigned int engine_load3DTexture(void *colorMapData, int sz, int format)
160//-----------------------------------------------------------------------------
161{
162 GLuint texture = 0;
163 GL(glGenTextures(1, &texture));
164 GL(glBindTexture(GL_TEXTURE_3D, texture));
165 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
166 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
167 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
168 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
169 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
170
171 GL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB10_A2, sz, sz, sz, 0, GL_RGBA,
172 GL_UNSIGNED_INT_2_10_10_10_REV, colorMapData));
173
174 return texture;
175}
176//-----------------------------------------------------------------------------
177unsigned int engine_load1DTexture(void *data, int sz, int format)
178//-----------------------------------------------------------------------------
179{
180 GLuint texture = 0;
181 if ((data != 0) && (sz != 0)) {
182 GL(glGenTextures(1, &texture));
183 GL(glBindTexture(GL_TEXTURE_2D, texture));
184 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
185 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
186 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
187 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
188
189 GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, sz, 1, 0, GL_RGBA,
190 GL_UNSIGNED_INT_2_10_10_10_REV, data));
191 }
192 return texture;
193}
194
195//-----------------------------------------------------------------------------
196void dumpShaderLog(int shader)
197//-----------------------------------------------------------------------------
198{
Pramodh Kumar Mukundab89f2452017-01-27 14:58:59 +0530199 int success = 0;
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800200 GLchar infoLog[512];
201 GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));
202 if (!success) {
203 glGetShaderInfoLog(shader, 512, NULL, infoLog);
204 ALOGI("Shader Failed to compile: %s\n", infoLog);
205 }
206}
207
208//-----------------------------------------------------------------------------
209GLuint engine_loadProgram(int vertexEntries, const char **vertex, int fragmentEntries,
210 const char **fragment)
211//-----------------------------------------------------------------------------
212{
213 GLuint progId = glCreateProgram();
214
215 int vertId = glCreateShader(GL_VERTEX_SHADER);
216 int fragId = glCreateShader(GL_FRAGMENT_SHADER);
217
218 GL(glShaderSource(vertId, vertexEntries, vertex, 0));
219 GL(glCompileShader(vertId));
220 dumpShaderLog(vertId);
221
222 GL(glShaderSource(fragId, fragmentEntries, fragment, 0));
223 GL(glCompileShader(fragId));
224 dumpShaderLog(fragId);
225
226 GL(glAttachShader(progId, vertId));
227 GL(glAttachShader(progId, fragId));
228
229 GL(glLinkProgram(progId));
230
231 GL(glDetachShader(progId, vertId));
232 GL(glDetachShader(progId, fragId));
233
234 GL(glDeleteShader(vertId));
235 GL(glDeleteShader(fragId));
236
237 return progId;
238}
239
240//-----------------------------------------------------------------------------
241void WaitOnNativeFence(int fd)
242//-----------------------------------------------------------------------------
243{
244 if (fd != -1) {
245 EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
246
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800247 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800248
249 if (sync == EGL_NO_SYNC_KHR) {
250 ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__);
251 } else {
252 // the gpu will wait for this sync - not this cpu thread.
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800253 EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
254 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800255 }
256 }
257}
258
259//-----------------------------------------------------------------------------
260int CreateNativeFence()
261//-----------------------------------------------------------------------------
262{
263 int fd = -1;
264
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800265 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800266 GL(glFlush());
267 if (sync == EGL_NO_SYNC_KHR) {
268 ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
269 } else {
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800270 fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800271 if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
272 ALOGE("%s - Failed to dup sync", __FUNCTION__);
273 }
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800274 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800275 }
276
277 return fd;
278}
279
280//-----------------------------------------------------------------------------
281void engine_setDestination(int id, int x, int y, int w, int h)
282//-----------------------------------------------------------------------------
283{
284 GL(glBindFramebuffer(GL_FRAMEBUFFER, id));
285 GL(glViewport(x, y, w, h));
286}
287
288//-----------------------------------------------------------------------------
289void engine_setProgram(int id)
290//-----------------------------------------------------------------------------
291{
292 GL(glUseProgram(id));
293}
294
295//-----------------------------------------------------------------------------
296void engine_set2DInputBuffer(int binding, unsigned int id)
297//-----------------------------------------------------------------------------
298{
299 GL(glActiveTexture(GL_TEXTURE0 + binding));
300 GL(glBindTexture(GL_TEXTURE_2D, id));
301}
302
303//-----------------------------------------------------------------------------
304void engine_set3DInputBuffer(int binding, unsigned int id)
305//-----------------------------------------------------------------------------
306{
307 GL(glActiveTexture(GL_TEXTURE0 + binding));
308 GL(glBindTexture(GL_TEXTURE_3D, id));
309}
310
311//-----------------------------------------------------------------------------
312void engine_setExternalInputBuffer(int binding, unsigned int id)
313//-----------------------------------------------------------------------------
314{
315 GL(glActiveTexture(GL_TEXTURE0 + binding));
316 GL(glBindTexture(0x8D65, id));
317}
318
319//-----------------------------------------------------------------------------
320int engine_blit(int srcFenceFd)
321//-----------------------------------------------------------------------------
322{
323 int fd = -1;
324 WaitOnNativeFence(srcFenceFd);
325 float fullscreen_vertices[]{0.0f, 2.0f, 0.0f, 0.0f, 2.0f, 0.0f};
326 GL(glEnableVertexAttribArray(0));
327 GL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, fullscreen_vertices));
328 GL(glDrawArrays(GL_TRIANGLES, 0, 3));
329 fd = CreateNativeFence();
330 GL(glFlush());
331 return fd;
332}
333
334//-----------------------------------------------------------------------------
335void checkGlError(const char *file, int line)
336//-----------------------------------------------------------------------------
337{
338 for (GLint error = glGetError(); error; error = glGetError()) {
339 char *pError;
340 switch (error) {
341 case GL_NO_ERROR:
342 pError = (char *)"GL_NO_ERROR";
343 break;
344 case GL_INVALID_ENUM:
345 pError = (char *)"GL_INVALID_ENUM";
346 break;
347 case GL_INVALID_VALUE:
348 pError = (char *)"GL_INVALID_VALUE";
349 break;
350 case GL_INVALID_OPERATION:
351 pError = (char *)"GL_INVALID_OPERATION";
352 break;
353 case GL_OUT_OF_MEMORY:
354 pError = (char *)"GL_OUT_OF_MEMORY";
355 break;
356 case GL_INVALID_FRAMEBUFFER_OPERATION:
357 pError = (char *)"GL_INVALID_FRAMEBUFFER_OPERATION";
358 break;
359
360 default:
361 ALOGE("glError (0x%x) %s:%d\n", error, file, line);
362 return;
363 }
364
365 ALOGE("glError (%s) %s:%d\n", pError, file, line);
366 return;
367 }
368 return;
369}
370
371//-----------------------------------------------------------------------------
372void checkEglError(const char *file, int line)
373//-----------------------------------------------------------------------------
374{
375 for (int i = 0; i < 5; i++) {
376 const EGLint error = eglGetError();
377 if (error == EGL_SUCCESS) {
378 break;
379 }
380
381 char *pError;
382 switch (error) {
383 case EGL_SUCCESS:
384 pError = (char *)"EGL_SUCCESS";
385 break;
386 case EGL_NOT_INITIALIZED:
387 pError = (char *)"EGL_NOT_INITIALIZED";
388 break;
389 case EGL_BAD_ACCESS:
390 pError = (char *)"EGL_BAD_ACCESS";
391 break;
392 case EGL_BAD_ALLOC:
393 pError = (char *)"EGL_BAD_ALLOC";
394 break;
395 case EGL_BAD_ATTRIBUTE:
396 pError = (char *)"EGL_BAD_ATTRIBUTE";
397 break;
398 case EGL_BAD_CONTEXT:
399 pError = (char *)"EGL_BAD_CONTEXT";
400 break;
401 case EGL_BAD_CONFIG:
402 pError = (char *)"EGL_BAD_CONFIG";
403 break;
404 case EGL_BAD_CURRENT_SURFACE:
405 pError = (char *)"EGL_BAD_CURRENT_SURFACE";
406 break;
407 case EGL_BAD_DISPLAY:
408 pError = (char *)"EGL_BAD_DISPLAY";
409 break;
410 case EGL_BAD_SURFACE:
411 pError = (char *)"EGL_BAD_SURFACE";
412 break;
413 case EGL_BAD_MATCH:
414 pError = (char *)"EGL_BAD_MATCH";
415 break;
416 case EGL_BAD_PARAMETER:
417 pError = (char *)"EGL_BAD_PARAMETER";
418 break;
419 case EGL_BAD_NATIVE_PIXMAP:
420 pError = (char *)"EGL_BAD_NATIVE_PIXMAP";
421 break;
422 case EGL_BAD_NATIVE_WINDOW:
423 pError = (char *)"EGL_BAD_NATIVE_WINDOW";
424 break;
425 case EGL_CONTEXT_LOST:
426 pError = (char *)"EGL_CONTEXT_LOST";
427 break;
428 default:
429 ALOGE("eglError (0x%x) %s:%d\n", error, file, line);
430 return;
431 }
432 ALOGE("eglError (%s) %s:%d\n", pError, file, line);
433 return;
434 }
435 return;
436}