blob: e5c8e68aade8256955763717e379ef3249e7c69f [file] [log] [blame]
Arun Kumar K.R2b75da32016-11-11 14:37:20 -08001/*
2 * Copyright (c) 2016, The Linux Foundation. All rights reserved.
3 * 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
27static EGLDisplay eglDisplay;
28static EGLContext eglContext;
29static EGLSurface eglSurface;
30
31static bool isEngineInitialized = false;
32
33//-----------------------------------------------------------------------------
34// Make Current
35void engine_bind()
36//-----------------------------------------------------------------------------
37{
38 EGL(eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext));
39}
40
41//-----------------------------------------------------------------------------
42// initialize GL
43//
44bool engine_initialize()
45//-----------------------------------------------------------------------------
46{
47 if (isEngineInitialized)
48 return true;
49
50 EGLBoolean result = false;
51
52 // display
53 eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
54 EGL(eglBindAPI(EGL_OPENGL_ES_API));
55
56 // initialize
57 EGL(eglInitialize(eglDisplay, 0, 0));
58
59 // config
60 EGLConfig eglConfig;
61 EGLint eglConfigAttribList[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
62 EGL_RED_SIZE, 8,
63 EGL_GREEN_SIZE, 8,
64 EGL_BLUE_SIZE, 8,
65 EGL_ALPHA_SIZE, 8,
66 EGL_NONE};
67 int numConfig = 0;
68 EGL(eglChooseConfig(eglDisplay, eglConfigAttribList, &eglConfig, 1, &numConfig));
69
70 // context
71 EGLint eglContextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
72 eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, eglContextAttribList);
73
74 // surface
75 EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
76 eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, eglSurfaceAttribList);
77
78 result = (EGL_TRUE == eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext));
79
80 isEngineInitialized = result;
81
82 ALOGI("In %s result = %d context = %p", __FUNCTION__, result, (void *)eglContext);
83
84 return result;
85}
86
87//-----------------------------------------------------------------------------
88// Shutdown.
89void engine_shutdown()
90//-----------------------------------------------------------------------------
91{
92 EGL(eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
93 EGL(eglDestroySurface(eglDisplay, eglSurface));
94 EGL(eglDestroyContext(eglDisplay, eglContext));
95 EGL(eglTerminate(eglDisplay));
96 eglDisplay = EGL_NO_DISPLAY;
97 eglContext = EGL_NO_CONTEXT;
98 eglSurface = EGL_NO_SURFACE;
99 isEngineInitialized = false;
100}
101
102//-----------------------------------------------------------------------------
103void engine_deleteInputBuffer(unsigned int id)
104//-----------------------------------------------------------------------------
105{
106 if (id != 0) {
107 GL(glDeleteTextures(1, &id));
108 }
109}
110
111//-----------------------------------------------------------------------------
112void engine_deleteProgram(unsigned int id)
113//-----------------------------------------------------------------------------
114{
115 if (id != 0) {
116 GL(glDeleteProgram(id));
117 }
118}
119
120//-----------------------------------------------------------------------------
121unsigned int engine_load3DTexture(void *colorMapData, int sz, int format)
122//-----------------------------------------------------------------------------
123{
124 GLuint texture = 0;
125 GL(glGenTextures(1, &texture));
126 GL(glBindTexture(GL_TEXTURE_3D, texture));
127 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
128 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
129 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE));
130 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
131 GL(glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
132
133 GL(glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB10_A2, sz, sz, sz, 0, GL_RGBA,
134 GL_UNSIGNED_INT_2_10_10_10_REV, colorMapData));
135
136 return texture;
137}
138//-----------------------------------------------------------------------------
139unsigned int engine_load1DTexture(void *data, int sz, int format)
140//-----------------------------------------------------------------------------
141{
142 GLuint texture = 0;
143 if ((data != 0) && (sz != 0)) {
144 GL(glGenTextures(1, &texture));
145 GL(glBindTexture(GL_TEXTURE_2D, texture));
146 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
147 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
148 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
149 GL(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
150
151 GL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB10_A2, sz, 1, 0, GL_RGBA,
152 GL_UNSIGNED_INT_2_10_10_10_REV, data));
153 }
154 return texture;
155}
156
157//-----------------------------------------------------------------------------
158void dumpShaderLog(int shader)
159//-----------------------------------------------------------------------------
160{
161 int success;
162 GLchar infoLog[512];
163 GL(glGetShaderiv(shader, GL_COMPILE_STATUS, &success));
164 if (!success) {
165 glGetShaderInfoLog(shader, 512, NULL, infoLog);
166 ALOGI("Shader Failed to compile: %s\n", infoLog);
167 }
168}
169
170//-----------------------------------------------------------------------------
171GLuint engine_loadProgram(int vertexEntries, const char **vertex, int fragmentEntries,
172 const char **fragment)
173//-----------------------------------------------------------------------------
174{
175 GLuint progId = glCreateProgram();
176
177 int vertId = glCreateShader(GL_VERTEX_SHADER);
178 int fragId = glCreateShader(GL_FRAGMENT_SHADER);
179
180 GL(glShaderSource(vertId, vertexEntries, vertex, 0));
181 GL(glCompileShader(vertId));
182 dumpShaderLog(vertId);
183
184 GL(glShaderSource(fragId, fragmentEntries, fragment, 0));
185 GL(glCompileShader(fragId));
186 dumpShaderLog(fragId);
187
188 GL(glAttachShader(progId, vertId));
189 GL(glAttachShader(progId, fragId));
190
191 GL(glLinkProgram(progId));
192
193 GL(glDetachShader(progId, vertId));
194 GL(glDetachShader(progId, fragId));
195
196 GL(glDeleteShader(vertId));
197 GL(glDeleteShader(fragId));
198
199 return progId;
200}
201
202//-----------------------------------------------------------------------------
203void WaitOnNativeFence(int fd)
204//-----------------------------------------------------------------------------
205{
206 if (fd != -1) {
207 EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
208
209 EGLSyncKHR sync = eglCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
210
211 if (sync == EGL_NO_SYNC_KHR) {
212 ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__);
213 } else {
214 // the gpu will wait for this sync - not this cpu thread.
215 EGL(eglWaitSyncKHR(eglDisplay, sync, 0));
216 EGL(eglDestroySyncKHR(eglDisplay, sync));
217 }
218 }
219}
220
221//-----------------------------------------------------------------------------
222int CreateNativeFence()
223//-----------------------------------------------------------------------------
224{
225 int fd = -1;
226
227 EGLSyncKHR sync = eglCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
228 GL(glFlush());
229 if (sync == EGL_NO_SYNC_KHR) {
230 ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
231 } else {
232 fd = eglDupNativeFenceFDANDROID(eglDisplay, sync);
233 if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
234 ALOGE("%s - Failed to dup sync", __FUNCTION__);
235 }
236 EGL(eglDestroySyncKHR(eglDisplay, sync));
237 }
238
239 return fd;
240}
241
242//-----------------------------------------------------------------------------
243void engine_setDestination(int id, int x, int y, int w, int h)
244//-----------------------------------------------------------------------------
245{
246 GL(glBindFramebuffer(GL_FRAMEBUFFER, id));
247 GL(glViewport(x, y, w, h));
248}
249
250//-----------------------------------------------------------------------------
251void engine_setProgram(int id)
252//-----------------------------------------------------------------------------
253{
254 GL(glUseProgram(id));
255}
256
257//-----------------------------------------------------------------------------
258void engine_set2DInputBuffer(int binding, unsigned int id)
259//-----------------------------------------------------------------------------
260{
261 GL(glActiveTexture(GL_TEXTURE0 + binding));
262 GL(glBindTexture(GL_TEXTURE_2D, id));
263}
264
265//-----------------------------------------------------------------------------
266void engine_set3DInputBuffer(int binding, unsigned int id)
267//-----------------------------------------------------------------------------
268{
269 GL(glActiveTexture(GL_TEXTURE0 + binding));
270 GL(glBindTexture(GL_TEXTURE_3D, id));
271}
272
273//-----------------------------------------------------------------------------
274void engine_setExternalInputBuffer(int binding, unsigned int id)
275//-----------------------------------------------------------------------------
276{
277 GL(glActiveTexture(GL_TEXTURE0 + binding));
278 GL(glBindTexture(0x8D65, id));
279}
280
281//-----------------------------------------------------------------------------
282int engine_blit(int srcFenceFd)
283//-----------------------------------------------------------------------------
284{
285 int fd = -1;
286 WaitOnNativeFence(srcFenceFd);
287 float fullscreen_vertices[]{0.0f, 2.0f, 0.0f, 0.0f, 2.0f, 0.0f};
288 GL(glEnableVertexAttribArray(0));
289 GL(glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, fullscreen_vertices));
290 GL(glDrawArrays(GL_TRIANGLES, 0, 3));
291 fd = CreateNativeFence();
292 GL(glFlush());
293 return fd;
294}
295
296//-----------------------------------------------------------------------------
297void checkGlError(const char *file, int line)
298//-----------------------------------------------------------------------------
299{
300 for (GLint error = glGetError(); error; error = glGetError()) {
301 char *pError;
302 switch (error) {
303 case GL_NO_ERROR:
304 pError = (char *)"GL_NO_ERROR";
305 break;
306 case GL_INVALID_ENUM:
307 pError = (char *)"GL_INVALID_ENUM";
308 break;
309 case GL_INVALID_VALUE:
310 pError = (char *)"GL_INVALID_VALUE";
311 break;
312 case GL_INVALID_OPERATION:
313 pError = (char *)"GL_INVALID_OPERATION";
314 break;
315 case GL_OUT_OF_MEMORY:
316 pError = (char *)"GL_OUT_OF_MEMORY";
317 break;
318 case GL_INVALID_FRAMEBUFFER_OPERATION:
319 pError = (char *)"GL_INVALID_FRAMEBUFFER_OPERATION";
320 break;
321
322 default:
323 ALOGE("glError (0x%x) %s:%d\n", error, file, line);
324 return;
325 }
326
327 ALOGE("glError (%s) %s:%d\n", pError, file, line);
328 return;
329 }
330 return;
331}
332
333//-----------------------------------------------------------------------------
334void checkEglError(const char *file, int line)
335//-----------------------------------------------------------------------------
336{
337 for (int i = 0; i < 5; i++) {
338 const EGLint error = eglGetError();
339 if (error == EGL_SUCCESS) {
340 break;
341 }
342
343 char *pError;
344 switch (error) {
345 case EGL_SUCCESS:
346 pError = (char *)"EGL_SUCCESS";
347 break;
348 case EGL_NOT_INITIALIZED:
349 pError = (char *)"EGL_NOT_INITIALIZED";
350 break;
351 case EGL_BAD_ACCESS:
352 pError = (char *)"EGL_BAD_ACCESS";
353 break;
354 case EGL_BAD_ALLOC:
355 pError = (char *)"EGL_BAD_ALLOC";
356 break;
357 case EGL_BAD_ATTRIBUTE:
358 pError = (char *)"EGL_BAD_ATTRIBUTE";
359 break;
360 case EGL_BAD_CONTEXT:
361 pError = (char *)"EGL_BAD_CONTEXT";
362 break;
363 case EGL_BAD_CONFIG:
364 pError = (char *)"EGL_BAD_CONFIG";
365 break;
366 case EGL_BAD_CURRENT_SURFACE:
367 pError = (char *)"EGL_BAD_CURRENT_SURFACE";
368 break;
369 case EGL_BAD_DISPLAY:
370 pError = (char *)"EGL_BAD_DISPLAY";
371 break;
372 case EGL_BAD_SURFACE:
373 pError = (char *)"EGL_BAD_SURFACE";
374 break;
375 case EGL_BAD_MATCH:
376 pError = (char *)"EGL_BAD_MATCH";
377 break;
378 case EGL_BAD_PARAMETER:
379 pError = (char *)"EGL_BAD_PARAMETER";
380 break;
381 case EGL_BAD_NATIVE_PIXMAP:
382 pError = (char *)"EGL_BAD_NATIVE_PIXMAP";
383 break;
384 case EGL_BAD_NATIVE_WINDOW:
385 pError = (char *)"EGL_BAD_NATIVE_WINDOW";
386 break;
387 case EGL_CONTEXT_LOST:
388 pError = (char *)"EGL_CONTEXT_LOST";
389 break;
390 default:
391 ALOGE("eglError (0x%x) %s:%d\n", error, file, line);
392 return;
393 }
394 ALOGE("eglError (%s) %s:%d\n", pError, file, line);
395 return;
396 }
397 return;
398}