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 lutXformScaleOffset[0] = 1.0f; 38 lutXformScaleOffset[1] = 0.0f; 39 40 tonemapScaleOffset[0] = 1.0f; 41 tonemapScaleOffset[1] = 0.0f; 42 } 43 44 //----------------------------------------------------------------------------- 45 Tonemapper::~Tonemapper() 46 //----------------------------------------------------------------------------- 47 { 48 void* caller_context = engine_backup(); 49 engine_bind(engineContext); 50 engine_deleteInputBuffer(tonemapTexture); 51 engine_deleteInputBuffer(lutXformTexture); 52 engine_deleteProgram(programID); 53 54 // clear EGLImage mappings 55 if (eglImageWrapper != 0) { 56 delete eglImageWrapper; 57 eglImageWrapper = 0; 58 } 59 60 engine_shutdown(engineContext); 61 // restore the caller context 62 engine_bind(caller_context); 63 engine_free_backup(caller_context); 64 } 65 66 //----------------------------------------------------------------------------- 67 Tonemapper *Tonemapper::build(int type, void *colorMap, int colorMapSize, void *lutXform, 68 int lutXformSize, bool isSecure) 69 //----------------------------------------------------------------------------- 70 { 71 if (colorMapSize <= 0) { 72 ALOGE("Invalid Color Map size = %d", colorMapSize); 73 return NULL; 74 } 75 76 // build new tonemapper 77 Tonemapper *tonemapper = new Tonemapper(); 78 79 tonemapper->engineContext = engine_initialize(isSecure); 80 81 void* caller_context = engine_backup(); 82 engine_bind(tonemapper->engineContext); 83 84 // load the 3d lut 85 tonemapper->tonemapTexture = engine_load3DTexture(colorMap, colorMapSize, 0); 86 tonemapper->tonemapScaleOffset[0] = ((float)(colorMapSize-1))/((float)(colorMapSize)); 87 tonemapper->tonemapScaleOffset[1] = 1.0f/(2.0f*colorMapSize); 88 89 // load the non-uniform xform 90 tonemapper->lutXformTexture = engine_load1DTexture(lutXform, lutXformSize, 0); 91 bool bUseXform = (tonemapper->lutXformTexture != 0) && (lutXformSize != 0); 92 if( bUseXform ) 93 { 94 tonemapper->lutXformScaleOffset[0] = ((float)(lutXformSize-1))/((float)(lutXformSize)); 95 tonemapper->lutXformScaleOffset[1] = 1.0f/(2.0f*lutXformSize); 96 } 97 98 // create the program 99 const char *fragmentShaders[3]; 100 int fragmentShaderCount = 0; 101 const char *version = "#version 300 es\n"; 102 const char *define = "#define USE_NONUNIFORM_SAMPLING\n"; 103 104 fragmentShaders[fragmentShaderCount++] = version; 105 106 // non-uniform sampling 107 if (bUseXform) { 108 fragmentShaders[fragmentShaderCount++] = define; 109 } 110 111 if (type == TONEMAP_INVERSE) { // inverse tonemapping 112 fragmentShaders[fragmentShaderCount++] = rgba_inverse_tonemap_shader; 113 } else { // forward tonemapping 114 fragmentShaders[fragmentShaderCount++] = forward_tonemap_shader; 115 } 116 117 tonemapper->programID = 118 engine_loadProgram(1, &fullscreen_vertex_shader, fragmentShaderCount, fragmentShaders); 119 120 // restore the caller context 121 engine_bind(caller_context); 122 engine_free_backup(caller_context); 123 124 return tonemapper; 125 } 126 127 //----------------------------------------------------------------------------- 128 int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd) 129 //----------------------------------------------------------------------------- 130 { 131 void* caller_context = engine_backup(); 132 // make current 133 engine_bind(engineContext); 134 135 // create eglimages if required 136 EGLImageBuffer *dst_buffer = eglImageWrapper->wrap(dst); 137 EGLImageBuffer *src_buffer = eglImageWrapper->wrap(src); 138 139 // bind the program 140 engine_setProgram(programID); 141 142 engine_setData2f(3, tonemapScaleOffset); 143 bool bUseXform = (lutXformTexture != 0); 144 if( bUseXform ) 145 { 146 engine_setData2f(4, lutXformScaleOffset); 147 } 148 149 // set destination 150 engine_setDestination(dst_buffer->getFramebuffer(), 0, 0, dst_buffer->getWidth(), 151 dst_buffer->getHeight()); 152 // set source 153 engine_setExternalInputBuffer(0, src_buffer->getTexture()); 154 // set 3d lut 155 engine_set3DInputBuffer(1, tonemapTexture); 156 // set non-uniform xform 157 engine_set2DInputBuffer(2, lutXformTexture); 158 159 // perform 160 int fenceFD = engine_blit(srcFenceFd); 161 162 // restore the caller context 163 engine_bind(caller_context); 164 engine_free_backup(caller_context); 165 166 167 return fenceFD; 168 } 169