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()
     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, EGL_NONE};
     77   engineContext->eglContext = eglCreateContext(engineContext->eglDisplay, eglConfig, NULL, eglContextAttribList);
     78 
     79   // surface
     80   EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
     81   engineContext->eglSurface = eglCreatePbufferSurface(engineContext->eglDisplay, eglConfig, eglSurfaceAttribList);
     82 
     83   eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext);
     84 
     85   ALOGI("In %s context = %p", __FUNCTION__, (void *)(engineContext->eglContext));
     86 
     87   return (void*)(engineContext);
     88 }
     89 
     90 //-----------------------------------------------------------------------------
     91 // Shutdown.
     92 void engine_shutdown(void* context)
     93 //-----------------------------------------------------------------------------
     94 {
     95   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;
    103 }
    104 
    105 //-----------------------------------------------------------------------------
    106 void engine_deleteInputBuffer(unsigned int id)
    107 //-----------------------------------------------------------------------------
    108 {
    109   if (id != 0) {
    110     GL(glDeleteTextures(1, &id));
    111   }
    112 }
    113 
    114 //-----------------------------------------------------------------------------
    115 void engine_deleteProgram(unsigned int id)
    116 //-----------------------------------------------------------------------------
    117 {
    118   if (id != 0) {
    119     GL(glDeleteProgram(id));
    120   }
    121 }
    122 
    123 //-----------------------------------------------------------------------------
    124 unsigned 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 //-----------------------------------------------------------------------------
    142 unsigned 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 //-----------------------------------------------------------------------------
    161 void dumpShaderLog(int shader)
    162 //-----------------------------------------------------------------------------
    163 {
    164   int success = 0;
    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 //-----------------------------------------------------------------------------
    174 GLuint 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 //-----------------------------------------------------------------------------
    206 void WaitOnNativeFence(int fd)
    207 //-----------------------------------------------------------------------------
    208 {
    209   if (fd != -1) {
    210     EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
    211 
    212     EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
    213 
    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.
    218       EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
    219       EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
    220     }
    221   }
    222 }
    223 
    224 //-----------------------------------------------------------------------------
    225 int CreateNativeFence()
    226 //-----------------------------------------------------------------------------
    227 {
    228   int fd = -1;
    229 
    230   EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
    231   GL(glFlush());
    232   if (sync == EGL_NO_SYNC_KHR) {
    233     ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
    234   } else {
    235     fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
    236     if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
    237       ALOGE("%s - Failed to dup sync", __FUNCTION__);
    238     }
    239     EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
    240   }
    241 
    242   return fd;
    243 }
    244 
    245 //-----------------------------------------------------------------------------
    246 void 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 //-----------------------------------------------------------------------------
    254 void engine_setProgram(int id)
    255 //-----------------------------------------------------------------------------
    256 {
    257   GL(glUseProgram(id));
    258 }
    259 
    260 //-----------------------------------------------------------------------------
    261 void 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 //-----------------------------------------------------------------------------
    269 void 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 //-----------------------------------------------------------------------------
    277 void engine_setExternalInputBuffer(int binding, unsigned int id)
    278 //-----------------------------------------------------------------------------
    279 {
    280   GL(glActiveTexture(GL_TEXTURE0 + binding));
    281   GL(glBindTexture(0x8D65, id));
    282 }
    283 
    284 //-----------------------------------------------------------------------------
    285 int 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 //-----------------------------------------------------------------------------
    300 void 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 //-----------------------------------------------------------------------------
    337 void 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 }
    402