blob: 9fc8f6b17ce32c0bad58a0b3f7a6942822700008 [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//-----------------------------------------------------------------------------
124unsigned int engine_load3DTexture(void *colorMapData, int sz, int format)
125//-----------------------------------------------------------------------------
126{
127 GLuint texture = 0;
128 GL(glGenTextures(1, &texture));
129 GL(glBindTexture(GL_TEXTURE_3D, texture));
130 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
131 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
132 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
133 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
134 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
135
136 GL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB10_A2, sz, sz, sz, 0, GL_RGBA,
137 GL_UNSIGNED_INT_2_10_10_10_REV, colorMapData));
138
139 return texture;
140}
141//-----------------------------------------------------------------------------
142unsigned int engine_load1DTexture(void *data, int sz, int format)
143//-----------------------------------------------------------------------------
144{
145 GLuint texture = 0;
146 if ((data != 0) && (sz != 0)) {
147 GL(glGenTextures(1, &texture));
148 GL(glBindTexture(GL_TEXTURE_2D, texture));
149 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
150 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
151 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
152 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
153
154 GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, sz, 1, 0, GL_RGBA,
155 GL_UNSIGNED_INT_2_10_10_10_REV, data));
156 }
157 return texture;
158}
159
160//-----------------------------------------------------------------------------
161void dumpShaderLog(int shader)
162//-----------------------------------------------------------------------------
163{
164 int success;
165 GLchar infoLog[512];
166 GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));
167 if (!success) {
168 glGetShaderInfoLog(shader, 512, NULL, infoLog);
169 ALOGI("Shader Failed to compile: %s\n", infoLog);
170 }
171}
172
173//-----------------------------------------------------------------------------
174GLuint engine_loadProgram(int vertexEntries, const char **vertex, int fragmentEntries,
175 const char **fragment)
176//-----------------------------------------------------------------------------
177{
178 GLuint progId = glCreateProgram();
179
180 int vertId = glCreateShader(GL_VERTEX_SHADER);
181 int fragId = glCreateShader(GL_FRAGMENT_SHADER);
182
183 GL(glShaderSource(vertId, vertexEntries, vertex, 0));
184 GL(glCompileShader(vertId));
185 dumpShaderLog(vertId);
186
187 GL(glShaderSource(fragId, fragmentEntries, fragment, 0));
188 GL(glCompileShader(fragId));
189 dumpShaderLog(fragId);
190
191 GL(glAttachShader(progId, vertId));
192 GL(glAttachShader(progId, fragId));
193
194 GL(glLinkProgram(progId));
195
196 GL(glDetachShader(progId, vertId));
197 GL(glDetachShader(progId, fragId));
198
199 GL(glDeleteShader(vertId));
200 GL(glDeleteShader(fragId));
201
202 return progId;
203}
204
205//-----------------------------------------------------------------------------
206void WaitOnNativeFence(int fd)
207//-----------------------------------------------------------------------------
208{
209 if (fd != -1) {
210 EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
211
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800212 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800213
214 if (sync == EGL_NO_SYNC_KHR) {
215 ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__);
216 } else {
217 // the gpu will wait for this sync - not this cpu thread.
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800218 EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
219 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800220 }
221 }
222}
223
224//-----------------------------------------------------------------------------
225int CreateNativeFence()
226//-----------------------------------------------------------------------------
227{
228 int fd = -1;
229
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800230 EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800231 GL(glFlush());
232 if (sync == EGL_NO_SYNC_KHR) {
233 ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
234 } else {
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800235 fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800236 if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
237 ALOGE("%s - Failed to dup sync", __FUNCTION__);
238 }
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800239 EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800240 }
241
242 return fd;
243}
244
245//-----------------------------------------------------------------------------
246void engine_setDestination(int id, int x, int y, int w, int h)
247//-----------------------------------------------------------------------------
248{
249 GL(glBindFramebuffer(GL_FRAMEBUFFER, id));
250 GL(glViewport(x, y, w, h));
251}
252
253//-----------------------------------------------------------------------------
254void engine_setProgram(int id)
255//-----------------------------------------------------------------------------
256{
257 GL(glUseProgram(id));
258}
259
260//-----------------------------------------------------------------------------
261void engine_set2DInputBuffer(int binding, unsigned int id)
262//-----------------------------------------------------------------------------
263{
264 GL(glActiveTexture(GL_TEXTURE0 + binding));
265 GL(glBindTexture(GL_TEXTURE_2D, id));
266}
267
268//-----------------------------------------------------------------------------
269void engine_set3DInputBuffer(int binding, unsigned int id)
270//-----------------------------------------------------------------------------
271{
272 GL(glActiveTexture(GL_TEXTURE0 + binding));
273 GL(glBindTexture(GL_TEXTURE_3D, id));
274}
275
276//-----------------------------------------------------------------------------
277void engine_setExternalInputBuffer(int binding, unsigned int id)
278//-----------------------------------------------------------------------------
279{
280 GL(glActiveTexture(GL_TEXTURE0 + binding));
281 GL(glBindTexture(0x8D65, id));
282}
283
284//-----------------------------------------------------------------------------
285int engine_blit(int srcFenceFd)
286//-----------------------------------------------------------------------------
287{
288 int fd = -1;
289 WaitOnNativeFence(srcFenceFd);
290 float fullscreen_vertices[]{0.0f, 2.0f, 0.0f, 0.0f, 2.0f, 0.0f};
291 GL(glEnableVertexAttribArray(0));
292 GL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, fullscreen_vertices));
293 GL(glDrawArrays(GL_TRIANGLES, 0, 3));
294 fd = CreateNativeFence();
295 GL(glFlush());
296 return fd;
297}
298
299//-----------------------------------------------------------------------------
300void checkGlError(const char *file, int line)
301//-----------------------------------------------------------------------------
302{
303 for (GLint error = glGetError(); error; error = glGetError()) {
304 char *pError;
305 switch (error) {
306 case GL_NO_ERROR:
307 pError = (char *)"GL_NO_ERROR";
308 break;
309 case GL_INVALID_ENUM:
310 pError = (char *)"GL_INVALID_ENUM";
311 break;
312 case GL_INVALID_VALUE:
313 pError = (char *)"GL_INVALID_VALUE";
314 break;
315 case GL_INVALID_OPERATION:
316 pError = (char *)"GL_INVALID_OPERATION";
317 break;
318 case GL_OUT_OF_MEMORY:
319 pError = (char *)"GL_OUT_OF_MEMORY";
320 break;
321 case GL_INVALID_FRAMEBUFFER_OPERATION:
322 pError = (char *)"GL_INVALID_FRAMEBUFFER_OPERATION";
323 break;
324
325 default:
326 ALOGE("glError (0x%x) %s:%d\n", error, file, line);
327 return;
328 }
329
330 ALOGE("glError (%s) %s:%d\n", pError, file, line);
331 return;
332 }
333 return;
334}
335
336//-----------------------------------------------------------------------------
337void checkEglError(const char *file, int line)
338//-----------------------------------------------------------------------------
339{
340 for (int i = 0; i < 5; i++) {
341 const EGLint error = eglGetError();
342 if (error == EGL_SUCCESS) {
343 break;
344 }
345
346 char *pError;
347 switch (error) {
348 case EGL_SUCCESS:
349 pError = (char *)"EGL_SUCCESS";
350 break;
351 case EGL_NOT_INITIALIZED:
352 pError = (char *)"EGL_NOT_INITIALIZED";
353 break;
354 case EGL_BAD_ACCESS:
355 pError = (char *)"EGL_BAD_ACCESS";
356 break;
357 case EGL_BAD_ALLOC:
358 pError = (char *)"EGL_BAD_ALLOC";
359 break;
360 case EGL_BAD_ATTRIBUTE:
361 pError = (char *)"EGL_BAD_ATTRIBUTE";
362 break;
363 case EGL_BAD_CONTEXT:
364 pError = (char *)"EGL_BAD_CONTEXT";
365 break;
366 case EGL_BAD_CONFIG:
367 pError = (char *)"EGL_BAD_CONFIG";
368 break;
369 case EGL_BAD_CURRENT_SURFACE:
370 pError = (char *)"EGL_BAD_CURRENT_SURFACE";
371 break;
372 case EGL_BAD_DISPLAY:
373 pError = (char *)"EGL_BAD_DISPLAY";
374 break;
375 case EGL_BAD_SURFACE:
376 pError = (char *)"EGL_BAD_SURFACE";
377 break;
378 case EGL_BAD_MATCH:
379 pError = (char *)"EGL_BAD_MATCH";
380 break;
381 case EGL_BAD_PARAMETER:
382 pError = (char *)"EGL_BAD_PARAMETER";
383 break;
384 case EGL_BAD_NATIVE_PIXMAP:
385 pError = (char *)"EGL_BAD_NATIVE_PIXMAP";
386 break;
387 case EGL_BAD_NATIVE_WINDOW:
388 pError = (char *)"EGL_BAD_NATIVE_WINDOW";
389 break;
390 case EGL_CONTEXT_LOST:
391 pError = (char *)"EGL_CONTEXT_LOST";
392 break;
393 default:
394 ALOGE("eglError (0x%x) %s:%d\n", error, file, line);
395 return;
396 }
397 ALOGE("eglError (%s) %s:%d\n", pError, file, line);
398 return;
399 }
400 return;
401}