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