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