blob: d60fee6345732e265164a42eb7370c629af12a7a [file] [log] [blame]
Mathias Agopian3f844832013-08-07 21:24:32 -07001/*
2 * Copyright 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef SF_RENDER_ENGINE_PROGRAMCACHE_H
18#define SF_RENDER_ENGINE_PROGRAMCACHE_H
19
Chia-I Wud3b13cb2018-09-13 13:31:26 -070020#include <memory>
Chia-I Wu56d7b0a2018-10-01 15:13:11 -070021#include <unordered_map>
22
Mathias Agopian3f844832013-08-07 21:24:32 -070023#include <GLES2/gl2.h>
Peiyong Lin833074a2018-08-28 11:53:54 -070024#include <renderengine/private/Description.h>
Chia-I Wub027f802017-11-29 14:00:52 -080025#include <utils/Singleton.h>
Mathias Agopian3f844832013-08-07 21:24:32 -070026#include <utils/TypeHelpers.h>
27
Mathias Agopian3f844832013-08-07 21:24:32 -070028namespace android {
29
Peiyong Lin833074a2018-08-28 11:53:54 -070030class String8;
31
32namespace renderengine {
33
Peiyong Lin70b26ce2018-09-18 19:02:39 -070034struct Description;
Peiyong Lin833074a2018-08-28 11:53:54 -070035
36namespace gl {
37
Peiyong Lin2542cb02018-04-30 17:29:53 -070038class Formatter;
Mathias Agopian3f844832013-08-07 21:24:32 -070039class Program;
Mathias Agopian3f844832013-08-07 21:24:32 -070040
41/*
42 * This class generates GLSL programs suitable to handle a given
43 * Description. It's responsible for figuring out what to
44 * generate from a Description.
45 * It also maintains a cache of these Programs.
46 */
47class ProgramCache : public Singleton<ProgramCache> {
48public:
49 /*
50 * Key is used to retrieve a Program in the cache.
51 * A Key is generated from a Description.
52 */
53 class Key {
54 friend class ProgramCache;
55 typedef uint32_t key_t;
56 key_t mKey;
Chia-I Wub027f802017-11-29 14:00:52 -080057
Mathias Agopian3f844832013-08-07 21:24:32 -070058 public:
59 enum {
Chia-I Wu7e65bc02018-01-11 14:31:38 -080060 BLEND_SHIFT = 0,
61 BLEND_MASK = 1 << BLEND_SHIFT,
62 BLEND_PREMULT = 1 << BLEND_SHIFT,
63 BLEND_NORMAL = 0 << BLEND_SHIFT,
Mathias Agopian3f844832013-08-07 21:24:32 -070064
Chia-I Wu7e65bc02018-01-11 14:31:38 -080065 OPACITY_SHIFT = 1,
66 OPACITY_MASK = 1 << OPACITY_SHIFT,
67 OPACITY_OPAQUE = 1 << OPACITY_SHIFT,
68 OPACITY_TRANSLUCENT = 0 << OPACITY_SHIFT,
Mathias Agopian3f844832013-08-07 21:24:32 -070069
Chia-I Wu7e65bc02018-01-11 14:31:38 -080070 ALPHA_SHIFT = 2,
71 ALPHA_MASK = 1 << ALPHA_SHIFT,
72 ALPHA_LT_ONE = 1 << ALPHA_SHIFT,
73 ALPHA_EQ_ONE = 0 << ALPHA_SHIFT,
Mathias Agopian3f844832013-08-07 21:24:32 -070074
Chia-I Wu7e65bc02018-01-11 14:31:38 -080075 TEXTURE_SHIFT = 3,
76 TEXTURE_MASK = 3 << TEXTURE_SHIFT,
77 TEXTURE_OFF = 0 << TEXTURE_SHIFT,
78 TEXTURE_EXT = 1 << TEXTURE_SHIFT,
79 TEXTURE_2D = 2 << TEXTURE_SHIFT,
Mathias Agopianff2ed702013-09-01 21:36:12 -070080
Peiyong Lina296b0c2018-04-30 16:55:29 -070081 INPUT_TRANSFORM_MATRIX_SHIFT = 5,
82 INPUT_TRANSFORM_MATRIX_MASK = 1 << INPUT_TRANSFORM_MATRIX_SHIFT,
83 INPUT_TRANSFORM_MATRIX_OFF = 0 << INPUT_TRANSFORM_MATRIX_SHIFT,
84 INPUT_TRANSFORM_MATRIX_ON = 1 << INPUT_TRANSFORM_MATRIX_SHIFT,
Romain Guy88d37dd2017-05-26 17:57:05 -070085
Peiyong Lina296b0c2018-04-30 16:55:29 -070086 OUTPUT_TRANSFORM_MATRIX_SHIFT = 6,
87 OUTPUT_TRANSFORM_MATRIX_MASK = 1 << OUTPUT_TRANSFORM_MATRIX_SHIFT,
88 OUTPUT_TRANSFORM_MATRIX_OFF = 0 << OUTPUT_TRANSFORM_MATRIX_SHIFT,
89 OUTPUT_TRANSFORM_MATRIX_ON = 1 << OUTPUT_TRANSFORM_MATRIX_SHIFT,
90
91 INPUT_TF_SHIFT = 7,
Chia-I Wu7e65bc02018-01-11 14:31:38 -080092 INPUT_TF_MASK = 3 << INPUT_TF_SHIFT,
93 INPUT_TF_LINEAR = 0 << INPUT_TF_SHIFT,
94 INPUT_TF_SRGB = 1 << INPUT_TF_SHIFT,
Chia-I Wu131d3762018-01-11 14:35:27 -080095 INPUT_TF_ST2084 = 2 << INPUT_TF_SHIFT,
Peiyong Lina3fb7d62018-04-11 17:41:47 -070096 INPUT_TF_HLG = 3 << INPUT_TF_SHIFT,
Chia-I Wu7e65bc02018-01-11 14:31:38 -080097
Peiyong Lina296b0c2018-04-30 16:55:29 -070098 OUTPUT_TF_SHIFT = 9,
Chia-I Wu7e65bc02018-01-11 14:31:38 -080099 OUTPUT_TF_MASK = 3 << OUTPUT_TF_SHIFT,
100 OUTPUT_TF_LINEAR = 0 << OUTPUT_TF_SHIFT,
101 OUTPUT_TF_SRGB = 1 << OUTPUT_TF_SHIFT,
Chia-I Wu131d3762018-01-11 14:35:27 -0800102 OUTPUT_TF_ST2084 = 2 << OUTPUT_TF_SHIFT,
Peiyong Lina3fb7d62018-04-11 17:41:47 -0700103 OUTPUT_TF_HLG = 3 << OUTPUT_TF_SHIFT,
Chia-I Wu131d3762018-01-11 14:35:27 -0800104
Peiyong Lina296b0c2018-04-30 16:55:29 -0700105 Y410_BT2020_SHIFT = 11,
Chia-I Wu131d3762018-01-11 14:35:27 -0800106 Y410_BT2020_MASK = 1 << Y410_BT2020_SHIFT,
107 Y410_BT2020_OFF = 0 << Y410_BT2020_SHIFT,
108 Y410_BT2020_ON = 1 << Y410_BT2020_SHIFT,
Mathias Agopian3f844832013-08-07 21:24:32 -0700109 };
110
Chia-I Wub027f802017-11-29 14:00:52 -0800111 inline Key() : mKey(0) {}
112 inline Key(const Key& rhs) : mKey(rhs.mKey) {}
Mathias Agopian3f844832013-08-07 21:24:32 -0700113
114 inline Key& set(key_t mask, key_t value) {
115 mKey = (mKey & ~mask) | value;
116 return *this;
117 }
118
Chia-I Wub027f802017-11-29 14:00:52 -0800119 inline bool isTexturing() const { return (mKey & TEXTURE_MASK) != TEXTURE_OFF; }
120 inline int getTextureTarget() const { return (mKey & TEXTURE_MASK); }
121 inline bool isPremultiplied() const { return (mKey & BLEND_MASK) == BLEND_PREMULT; }
122 inline bool isOpaque() const { return (mKey & OPACITY_MASK) == OPACITY_OPAQUE; }
123 inline bool hasAlpha() const { return (mKey & ALPHA_MASK) == ALPHA_LT_ONE; }
Peiyong Lina296b0c2018-04-30 16:55:29 -0700124 inline bool hasInputTransformMatrix() const {
125 return (mKey & INPUT_TRANSFORM_MATRIX_MASK) == INPUT_TRANSFORM_MATRIX_ON;
126 }
127 inline bool hasOutputTransformMatrix() const {
128 return (mKey & OUTPUT_TRANSFORM_MATRIX_MASK) == OUTPUT_TRANSFORM_MATRIX_ON;
129 }
130 inline bool hasTransformMatrix() const {
131 return hasInputTransformMatrix() || hasOutputTransformMatrix();
132 }
Chia-I Wu7e65bc02018-01-11 14:31:38 -0800133 inline int getInputTF() const { return (mKey & INPUT_TF_MASK); }
134 inline int getOutputTF() const { return (mKey & OUTPUT_TF_MASK); }
Peiyong Lin53f320e2018-04-23 17:31:06 -0700135
136 // When HDR and non-HDR contents are mixed, or different types of HDR contents are
137 // mixed, we will do a tone mapping process to tone map the input content to output
138 // content. Currently, the following conversions handled, they are:
139 // * SDR -> HLG
140 // * SDR -> PQ
141 // * HLG -> PQ
142 inline bool needsToneMapping() const {
143 int inputTF = getInputTF();
144 int outputTF = getOutputTF();
145
146 // Return false when converting from SDR to SDR.
147 if (inputTF == Key::INPUT_TF_SRGB && outputTF == Key::OUTPUT_TF_LINEAR) {
148 return false;
149 }
150 if (inputTF == Key::INPUT_TF_LINEAR && outputTF == Key::OUTPUT_TF_SRGB) {
151 return false;
152 }
153
154 inputTF >>= Key::INPUT_TF_SHIFT;
155 outputTF >>= Key::OUTPUT_TF_SHIFT;
156 return inputTF != outputTF;
157 }
Chia-I Wu131d3762018-01-11 14:35:27 -0800158 inline bool isY410BT2020() const { return (mKey & Y410_BT2020_MASK) == Y410_BT2020_ON; }
Mathias Agopian3f844832013-08-07 21:24:32 -0700159
Chia-I Wu56d7b0a2018-10-01 15:13:11 -0700160 // for use by std::unordered_map
161
Peiyong Lin46080ef2018-10-26 18:43:14 -0700162 bool operator==(const Key& other) const { return mKey == other.mKey; }
Chia-I Wu56d7b0a2018-10-01 15:13:11 -0700163
164 struct Hash {
Peiyong Lin46080ef2018-10-26 18:43:14 -0700165 size_t operator()(const Key& key) const { return static_cast<size_t>(key.mKey); }
Chia-I Wu56d7b0a2018-10-01 15:13:11 -0700166 };
Mathias Agopian3f844832013-08-07 21:24:32 -0700167 };
168
Chia-I Wud3b13cb2018-09-13 13:31:26 -0700169 ProgramCache() = default;
170 ~ProgramCache() = default;
Mathias Agopian3f844832013-08-07 21:24:32 -0700171
Chia-I Wu93e14df2018-06-04 10:10:17 -0700172 // Generate shaders to populate the cache
Peiyong Lin13effd12018-07-24 17:01:47 -0700173 void primeCache(bool useColorManagement);
Chia-I Wu93e14df2018-06-04 10:10:17 -0700174
Chia-I Wu56d7b0a2018-10-01 15:13:11 -0700175 size_t getSize() const { return mCache.size(); }
176
Mathias Agopian3f844832013-08-07 21:24:32 -0700177 // useProgram lookup a suitable program in the cache or generates one
178 // if none can be found.
179 void useProgram(const Description& description);
180
181private:
Mathias Agopian3f844832013-08-07 21:24:32 -0700182 // compute a cache Key from a Description
183 static Key computeKey(const Description& description);
Peiyong Lin2542cb02018-04-30 17:29:53 -0700184 // Generate EOTF based from Key.
185 static void generateEOTF(Formatter& fs, const Key& needs);
Peiyong Lin53f320e2018-04-23 17:31:06 -0700186 // Generate necessary tone mapping methods for OOTF.
187 static void generateToneMappingProcess(Formatter& fs, const Key& needs);
Peiyong Lin2542cb02018-04-30 17:29:53 -0700188 // Generate OOTF based from Key.
189 static void generateOOTF(Formatter& fs, const Key& needs);
190 // Generate OETF based from Key.
191 static void generateOETF(Formatter& fs, const Key& needs);
Mathias Agopian3f844832013-08-07 21:24:32 -0700192 // generates a program from the Key
Chia-I Wud3b13cb2018-09-13 13:31:26 -0700193 static std::unique_ptr<Program> generateProgram(const Key& needs);
Mathias Agopian3f844832013-08-07 21:24:32 -0700194 // generates the vertex shader from the Key
195 static String8 generateVertexShader(const Key& needs);
196 // generates the fragment shader from the Key
197 static String8 generateFragmentShader(const Key& needs);
198
199 // Key/Value map used for caching Programs. Currently the cache
Chia-I Wud3b13cb2018-09-13 13:31:26 -0700200 // is never shrunk (and the GL program objects are never deleted).
201 std::unordered_map<Key, std::unique_ptr<Program>, Key::Hash> mCache;
Mathias Agopian3f844832013-08-07 21:24:32 -0700202};
203
Peiyong Lin46080ef2018-10-26 18:43:14 -0700204} // namespace gl
205} // namespace renderengine
Mathias Agopian3f844832013-08-07 21:24:32 -0700206
Peiyong Lin833074a2018-08-28 11:53:54 -0700207ANDROID_BASIC_TYPES_TRAITS(renderengine::gl::ProgramCache::Key)
208
Peiyong Lin46080ef2018-10-26 18:43:14 -0700209} // namespace android
Mathias Agopian3f844832013-08-07 21:24:32 -0700210
211#endif /* SF_RENDER_ENGINE_PROGRAMCACHE_H */