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 //-----------------------------------------------------------------------------
Tonemapper()29 Tonemapper::Tonemapper()
30 //-----------------------------------------------------------------------------
31 {
32   tonemapTexture = 0;
33   lutXformTexture = 0;
34   programID = 0;
35   eglImageWrapper = new EGLImageWrapper();
36 }
37 
38 //-----------------------------------------------------------------------------
~Tonemapper()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 //-----------------------------------------------------------------------------
build(int type,void * colorMap,int colorMapSize,void * lutXform,int lutXformSize)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 //-----------------------------------------------------------------------------
blit(const void * dst,const void * src,int srcFenceFd)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