blob: 90fe50229c979eef35ce577ec2404cfbca727f77 [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//
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080073void* engine_initialize()
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
97 EGLint eglContextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080098 engineContext->eglContext = eglCreateContext(engineContext->eglDisplay, eglConfig, NULL, eglContextAttribList);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080099
100 // surface
101 EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800102 engineContext->eglSurface = eglCreatePbufferSurface(engineContext->eglDisplay, eglConfig, eglSurfaceAttribList);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800103
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800104 eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800105
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800106 ALOGI("In %s context = %p", __FUNCTION__, (void *)(engineContext->eglContext));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800107
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800108 return (void*)(engineContext);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800109}
110
111//-----------------------------------------------------------------------------
112// Shutdown.
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800113void engine_shutdown(void* context)
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800114//-----------------------------------------------------------------------------
115{
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800116 EngineContext* engineContext = (EngineContext*)context;
117 EGL(eglMakeCurrent(engineContext->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
118 EGL(eglDestroySurface(engineContext->eglDisplay, engineContext->eglSurface));
119 EGL(eglDestroyContext(engineContext->eglDisplay, engineContext->eglContext));
120 EGL(eglTerminate(engineContext->eglDisplay));
121 engineContext->eglDisplay = EGL_NO_DISPLAY;
122 engineContext->eglContext = EGL_NO_CONTEXT;
123 engineContext->eglSurface = EGL_NO_SURFACE;
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800124}
125
126//-----------------------------------------------------------------------------
127void engine_deleteInputBuffer(unsigned int id)
128//-----------------------------------------------------------------------------
129{
130 if (id != 0) {
131 GL(glDeleteTextures(1, &id));
132 }
133}
134
135//-----------------------------------------------------------------------------
136void engine_deleteProgram(unsigned int id)
137//-----------------------------------------------------------------------------
138{
139 if (id != 0) {
140 GL(glDeleteProgram(id));
141 }
142}
143
144//-----------------------------------------------------------------------------
Arun Kumar K.R1d1e57d2017-02-16 19:12:20 -0800145void engine_setData2f(int location, float* data)
146//-----------------------------------------------------------------------------
147{
148 GL(glUniform2f(location, data[0], data[1]));
149}
150
151//-----------------------------------------------------------------------------
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800152unsigned int engine_load3DTexture(void *colorMapData, int sz, int format)
153//-----------------------------------------------------------------------------
154{
155 GLuint texture = 0;
156 GL(glGenTextures(1, &texture));
157 GL(glBindTexture(GL_TEXTURE_3D, texture));
158 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
159 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
160 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
161 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
162 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
163
164 GL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB10_A2, sz, sz, sz, 0, GL_RGBA,
165 GL_UNSIGNED_INT_2_10_10_10_REV, colorMapData));
166
167 return texture;
168}
169//-----------------------------------------------------------------------------
170unsigned int engine_load1DTexture(void *data, int sz, int format)
171//-----------------------------------------------------------------------------
172{
173 GLuint texture = 0;
174 if ((data != 0) && (sz != 0)) {
175 GL(glGenTextures(1, &texture));
176 GL(glBindTexture(GL_TEXTURE_2D, texture));
177 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
178 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
179 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
180 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
181
182 GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, sz, 1, 0, GL_RGBA,
183 GL_UNSIGNED_INT_2_10_10_10_REV, data));
184 }
185 return texture;
186}
187
188//-----------------------------------------------------------------------------
189void dumpShaderLog(int shader)
190//-----------------------------------------------------------------------------
191{
Pramodh Kumar Mukundab89f2452017-01-27 14:58:59 +0530192 int success = 0;
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800193 GLchar infoLog[512];
194 GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));
195 if (!success) {
196 glGetShaderInfoLog(shader, 512, NULL, infoLog);
197 ALOGI("Shader Failed to compile: %s\n", infoLog);
198 }
199}
200
201//-----------------------------------------------------------------------------
202GLuint engine_loadProgram(int vertexEntries, const char **vertex, int fragmentEntries,
203 const char **fragment)
204//-----------------------------------------------------------------------------
205{
206 GLuint progId = glCreateProgram();
207
208 int vertId = glCreateShader(GL_VERTEX_SHADER);
209 int fragId = glCreateShader(GL_FRAGMENT_SHADER);
210
211 GL(glShaderSource(vertId, vertexEntries, vertex, 0));
212 GL(glCompileShader(vertId));
213 dumpShaderLog(vertId);
214
215 GL(glShaderSource(fragId, fragmentEntries, fragment, 0));
216 GL(glCompileShader(fragId));
217 dumpShaderLog(fragId);
218
219 GL(glAttachShader(progId, vertId));
220 GL(glAttachShader(progId, fragId));
221
222 GL(glLinkProgram(progId));
223
224 GL(glDetachShader(progId, vertId));
225 GL(glDetachShader(progId, fragId));
226
227 GL(glDeleteShader(vertId));
228 GL(glDeleteShader(fragId));
229
230 return progId;
231}
232
233//-----------------------------------------------------------------------------
234void WaitOnNativeFence(int fd)
235//-----------------------------------------------------------------------------
236{
237 if (fd != -1) {
238 EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
239
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800240 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800241
242 if (sync == EGL_NO_SYNC_KHR) {
243 ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__);
244 } else {
245 // the gpu will wait for this sync - not this cpu thread.
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800246 EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
247 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800248 }
249 }
250}
251
252//-----------------------------------------------------------------------------
253int CreateNativeFence()
254//-----------------------------------------------------------------------------
255{
256 int fd = -1;
257
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800258 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800259 GL(glFlush());
260 if (sync == EGL_NO_SYNC_KHR) {
261 ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
262 } else {
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800263 fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800264 if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
265 ALOGE("%s - Failed to dup sync", __FUNCTION__);
266 }
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800267 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800268 }
269
270 return fd;
271}
272
273//-----------------------------------------------------------------------------
274void engine_setDestination(int id, int x, int y, int w, int h)
275//-----------------------------------------------------------------------------
276{
277 GL(glBindFramebuffer(GL_FRAMEBUFFER, id));
278 GL(glViewport(x, y, w, h));
279}
280
281//-----------------------------------------------------------------------------
282void engine_setProgram(int id)
283//-----------------------------------------------------------------------------
284{
285 GL(glUseProgram(id));
286}
287
288//-----------------------------------------------------------------------------
289void engine_set2DInputBuffer(int binding, unsigned int id)
290//-----------------------------------------------------------------------------
291{
292 GL(glActiveTexture(GL_TEXTURE0 + binding));
293 GL(glBindTexture(GL_TEXTURE_2D, id));
294}
295
296//-----------------------------------------------------------------------------
297void engine_set3DInputBuffer(int binding, unsigned int id)
298//-----------------------------------------------------------------------------
299{
300 GL(glActiveTexture(GL_TEXTURE0 + binding));
301 GL(glBindTexture(GL_TEXTURE_3D, id));
302}
303
304//-----------------------------------------------------------------------------
305void engine_setExternalInputBuffer(int binding, unsigned int id)
306//-----------------------------------------------------------------------------
307{
308 GL(glActiveTexture(GL_TEXTURE0 + binding));
309 GL(glBindTexture(0x8D65, id));
310}
311
312//-----------------------------------------------------------------------------
313int engine_blit(int srcFenceFd)
314//-----------------------------------------------------------------------------
315{
316 int fd = -1;
317 WaitOnNativeFence(srcFenceFd);
318 float fullscreen_vertices[]{0.0f, 2.0f, 0.0f, 0.0f, 2.0f, 0.0f};
319 GL(glEnableVertexAttribArray(0));
320 GL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, fullscreen_vertices));
321 GL(glDrawArrays(GL_TRIANGLES, 0, 3));
322 fd = CreateNativeFence();
323 GL(glFlush());
324 return fd;
325}
326
327//-----------------------------------------------------------------------------
328void checkGlError(const char *file, int line)
329//-----------------------------------------------------------------------------
330{
331 for (GLint error = glGetError(); error; error = glGetError()) {
332 char *pError;
333 switch (error) {
334 case GL_NO_ERROR:
335 pError = (char *)"GL_NO_ERROR";
336 break;
337 case GL_INVALID_ENUM:
338 pError = (char *)"GL_INVALID_ENUM";
339 break;
340 case GL_INVALID_VALUE:
341 pError = (char *)"GL_INVALID_VALUE";
342 break;
343 case GL_INVALID_OPERATION:
344 pError = (char *)"GL_INVALID_OPERATION";
345 break;
346 case GL_OUT_OF_MEMORY:
347 pError = (char *)"GL_OUT_OF_MEMORY";
348 break;
349 case GL_INVALID_FRAMEBUFFER_OPERATION:
350 pError = (char *)"GL_INVALID_FRAMEBUFFER_OPERATION";
351 break;
352
353 default:
354 ALOGE("glError (0x%x) %s:%d\n", error, file, line);
355 return;
356 }
357
358 ALOGE("glError (%s) %s:%d\n", pError, file, line);
359 return;
360 }
361 return;
362}
363
364//-----------------------------------------------------------------------------
365void checkEglError(const char *file, int line)
366//-----------------------------------------------------------------------------
367{
368 for (int i = 0; i < 5; i++) {
369 const EGLint error = eglGetError();
370 if (error == EGL_SUCCESS) {
371 break;
372 }
373
374 char *pError;
375 switch (error) {
376 case EGL_SUCCESS:
377 pError = (char *)"EGL_SUCCESS";
378 break;
379 case EGL_NOT_INITIALIZED:
380 pError = (char *)"EGL_NOT_INITIALIZED";
381 break;
382 case EGL_BAD_ACCESS:
383 pError = (char *)"EGL_BAD_ACCESS";
384 break;
385 case EGL_BAD_ALLOC:
386 pError = (char *)"EGL_BAD_ALLOC";
387 break;
388 case EGL_BAD_ATTRIBUTE:
389 pError = (char *)"EGL_BAD_ATTRIBUTE";
390 break;
391 case EGL_BAD_CONTEXT:
392 pError = (char *)"EGL_BAD_CONTEXT";
393 break;
394 case EGL_BAD_CONFIG:
395 pError = (char *)"EGL_BAD_CONFIG";
396 break;
397 case EGL_BAD_CURRENT_SURFACE:
398 pError = (char *)"EGL_BAD_CURRENT_SURFACE";
399 break;
400 case EGL_BAD_DISPLAY:
401 pError = (char *)"EGL_BAD_DISPLAY";
402 break;
403 case EGL_BAD_SURFACE:
404 pError = (char *)"EGL_BAD_SURFACE";
405 break;
406 case EGL_BAD_MATCH:
407 pError = (char *)"EGL_BAD_MATCH";
408 break;
409 case EGL_BAD_PARAMETER:
410 pError = (char *)"EGL_BAD_PARAMETER";
411 break;
412 case EGL_BAD_NATIVE_PIXMAP:
413 pError = (char *)"EGL_BAD_NATIVE_PIXMAP";
414 break;
415 case EGL_BAD_NATIVE_WINDOW:
416 pError = (char *)"EGL_BAD_NATIVE_WINDOW";
417 break;
418 case EGL_CONTEXT_LOST:
419 pError = (char *)"EGL_CONTEXT_LOST";
420 break;
421 default:
422 ALOGE("eglError (0x%x) %s:%d\n", error, file, line);
423 return;
424 }
425 ALOGE("eglError (%s) %s:%d\n", pError, file, line);
426 return;
427 }
428 return;
429}