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