blob: 981863d4620864566c198d7aba8244c269458191 [file] [log] [blame]
Arun Kumar K.R2b75da32016-11-11 14:37:20 -08001/*
Sushil Chauhan1cc416f2017-01-11 18:09:02 -08002 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
Arun Kumar K.R2b75da32016-11-11 14:37:20 -08003 * 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//-----------------------------------------------------------------------------
29Tonemapper::Tonemapper()
30//-----------------------------------------------------------------------------
31{
32 tonemapTexture = 0;
33 lutXformTexture = 0;
34 programID = 0;
Sushil Chauhan1cc416f2017-01-11 18:09:02 -080035 eglImageWrapper = new EGLImageWrapper();
Arun Kumar K.R1d1e57d2017-02-16 19:12:20 -080036
37 lutXformScaleOffset[0] = 1.0f;
38 lutXformScaleOffset[1] = 0.0f;
39
40 tonemapScaleOffset[0] = 1.0f;
41 tonemapScaleOffset[1] = 0.0f;
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080042}
43
44//-----------------------------------------------------------------------------
45Tonemapper::~Tonemapper()
46//-----------------------------------------------------------------------------
47{
Arun Kumar K.R99ff47d2017-02-20 20:07:48 +053048 void* caller_context = engine_backup();
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080049 engine_bind(engineContext);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080050 engine_deleteInputBuffer(tonemapTexture);
51 engine_deleteInputBuffer(lutXformTexture);
52 engine_deleteProgram(programID);
Sushil Chauhan1cc416f2017-01-11 18:09:02 -080053
54 // clear EGLImage mappings
55 if (eglImageWrapper != 0) {
Sushil Chauhan1cc416f2017-01-11 18:09:02 -080056 delete eglImageWrapper;
57 eglImageWrapper = 0;
58 }
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080059
60 engine_shutdown(engineContext);
Arun Kumar K.R99ff47d2017-02-20 20:07:48 +053061 // restore the caller context
62 engine_bind(caller_context);
63 engine_free_backup(caller_context);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080064}
65
66//-----------------------------------------------------------------------------
67Tonemapper *Tonemapper::build(int type, void *colorMap, int colorMapSize, void *lutXform,
Sushil Chauhan70bc2c02017-05-02 17:09:47 -070068 int lutXformSize, bool isSecure)
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080069//-----------------------------------------------------------------------------
70{
71 if (colorMapSize <= 0) {
72 ALOGE("Invalid Color Map size = %d", colorMapSize);
73 return NULL;
74 }
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080075
76 // build new tonemapper
77 Tonemapper *tonemapper = new Tonemapper();
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080078
Sushil Chauhan70bc2c02017-05-02 17:09:47 -070079 tonemapper->engineContext = engine_initialize(isSecure);
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080080
Arun Kumar K.R99ff47d2017-02-20 20:07:48 +053081 void* caller_context = engine_backup();
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -080082 engine_bind(tonemapper->engineContext);
83
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080084 // load the 3d lut
85 tonemapper->tonemapTexture = engine_load3DTexture(colorMap, colorMapSize, 0);
Arun Kumar K.R1d1e57d2017-02-16 19:12:20 -080086 tonemapper->tonemapScaleOffset[0] = ((float)(colorMapSize-1))/((float)(colorMapSize));
87 tonemapper->tonemapScaleOffset[1] = 1.0f/(2.0f*colorMapSize);
88
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080089 // load the non-uniform xform
90 tonemapper->lutXformTexture = engine_load1DTexture(lutXform, lutXformSize, 0);
91 bool bUseXform = (tonemapper->lutXformTexture != 0) && (lutXformSize != 0);
Arun Kumar K.R1d1e57d2017-02-16 19:12:20 -080092 if( bUseXform )
93 {
94 tonemapper->lutXformScaleOffset[0] = ((float)(lutXformSize-1))/((float)(lutXformSize));
95 tonemapper->lutXformScaleOffset[1] = 1.0f/(2.0f*lutXformSize);
96 }
Arun Kumar K.R2b75da32016-11-11 14:37:20 -080097
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
Arun Kumar K.R99ff47d2017-02-20 20:07:48 +0530120 // restore the caller context
121 engine_bind(caller_context);
122 engine_free_backup(caller_context);
123
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800124 return tonemapper;
125}
126
127//-----------------------------------------------------------------------------
128int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd)
129//-----------------------------------------------------------------------------
130{
Arun Kumar K.R99ff47d2017-02-20 20:07:48 +0530131 void* caller_context = engine_backup();
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800132 // make current
Arun Kumar K.R1b04a4e2017-01-23 17:16:55 -0800133 engine_bind(engineContext);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800134
135 // create eglimages if required
Sushil Chauhan1cc416f2017-01-11 18:09:02 -0800136 EGLImageBuffer *dst_buffer = eglImageWrapper->wrap(dst);
137 EGLImageBuffer *src_buffer = eglImageWrapper->wrap(src);
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800138
139 // bind the program
140 engine_setProgram(programID);
141
Arun Kumar K.R1d1e57d2017-02-16 19:12:20 -0800142 engine_setData2f(3, tonemapScaleOffset);
143 bool bUseXform = (lutXformTexture != 0);
144 if( bUseXform )
145 {
146 engine_setData2f(4, lutXformScaleOffset);
147 }
148
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800149 // 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
Arun Kumar K.R99ff47d2017-02-20 20:07:48 +0530162 // restore the caller context
163 engine_bind(caller_context);
164 engine_free_backup(caller_context);
165
166
Arun Kumar K.R2b75da32016-11-11 14:37:20 -0800167 return fenceFD;
168}