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 #include <utils/Log.h>
     20 
     21 #include "EGLImageWrapper.h"
     22 #include "Tonemapper.h"
     23 #include "engine.h"
     24 #include "forward_tonemap.inl"
     25 #include "fullscreen_vertex_shader.inl"
     26 #include "rgba_inverse_tonemap.inl"
     27 
     28 //-----------------------------------------------------------------------------
     29 Tonemapper::Tonemapper()
     30 //-----------------------------------------------------------------------------
     31 {
     32   tonemapTexture = 0;
     33   lutXformTexture = 0;
     34   programID = 0;
     35   eglImageWrapper = new EGLImageWrapper();
     36 }
     37 
     38 //-----------------------------------------------------------------------------
     39 Tonemapper::~Tonemapper()
     40 //-----------------------------------------------------------------------------
     41 {
     42   engine_bind(engineContext);
     43   engine_deleteInputBuffer(tonemapTexture);
     44   engine_deleteInputBuffer(lutXformTexture);
     45   engine_deleteProgram(programID);
     46 
     47   // clear EGLImage mappings
     48   if (eglImageWrapper != 0) {
     49     delete eglImageWrapper;
     50     eglImageWrapper = 0;
     51   }
     52 
     53   engine_shutdown(engineContext);
     54 }
     55 
     56 //-----------------------------------------------------------------------------
     57 Tonemapper *Tonemapper::build(int type, void *colorMap, int colorMapSize, void *lutXform,
     58                               int lutXformSize)
     59 //-----------------------------------------------------------------------------
     60 {
     61   if (colorMapSize <= 0) {
     62       ALOGE("Invalid Color Map size = %d", colorMapSize);
     63       return NULL;
     64   }
     65 
     66   // build new tonemapper
     67   Tonemapper *tonemapper = new Tonemapper();
     68 
     69   tonemapper->engineContext = engine_initialize();
     70 
     71   engine_bind(tonemapper->engineContext);
     72 
     73   // load the 3d lut
     74   tonemapper->tonemapTexture = engine_load3DTexture(colorMap, colorMapSize, 0);
     75   // load the non-uniform xform
     76   tonemapper->lutXformTexture = engine_load1DTexture(lutXform, lutXformSize, 0);
     77   bool bUseXform = (tonemapper->lutXformTexture != 0) && (lutXformSize != 0);
     78 
     79   // create the program
     80   const char *fragmentShaders[3];
     81   int fragmentShaderCount = 0;
     82   const char *version = "#version 300 es\n";
     83   const char *define = "#define USE_NONUNIFORM_SAMPLING\n";
     84 
     85   fragmentShaders[fragmentShaderCount++] = version;
     86 
     87   // non-uniform sampling
     88   if (bUseXform) {
     89     fragmentShaders[fragmentShaderCount++] = define;
     90   }
     91 
     92   if (type == TONEMAP_INVERSE) {  // inverse tonemapping
     93     fragmentShaders[fragmentShaderCount++] = rgba_inverse_tonemap_shader;
     94   } else {  // forward tonemapping
     95     fragmentShaders[fragmentShaderCount++] = forward_tonemap_shader;
     96   }
     97 
     98   tonemapper->programID =
     99       engine_loadProgram(1, &fullscreen_vertex_shader, fragmentShaderCount, fragmentShaders);
    100 
    101   return tonemapper;
    102 }
    103 
    104 //-----------------------------------------------------------------------------
    105 int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd)
    106 //-----------------------------------------------------------------------------
    107 {
    108   // make current
    109   engine_bind(engineContext);
    110 
    111   // create eglimages if required
    112   EGLImageBuffer *dst_buffer = eglImageWrapper->wrap(dst);
    113   EGLImageBuffer *src_buffer = eglImageWrapper->wrap(src);
    114 
    115   // bind the program
    116   engine_setProgram(programID);
    117 
    118   // set destination
    119   engine_setDestination(dst_buffer->getFramebuffer(), 0, 0, dst_buffer->getWidth(),
    120                         dst_buffer->getHeight());
    121   // set source
    122   engine_setExternalInputBuffer(0, src_buffer->getTexture());
    123   // set 3d lut
    124   engine_set3DInputBuffer(1, tonemapTexture);
    125   // set non-uniform xform
    126   engine_set2DInputBuffer(2, lutXformTexture);
    127 
    128   // perform
    129   int fenceFD = engine_blit(srcFenceFd);
    130 
    131   return fenceFD;
    132 }
    133