1 /* 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 20 #include <GLES2/gl2.h> 21 22 #include <utils/KeyedVector.h> 23 #include <utils/Singleton.h> 24 #include <utils/TypeHelpers.h> 25 26 #include "Description.h" 27 28 namespace android { 29 30 class Description; 31 class Formatter; 32 class Program; 33 class String8; 34 35 /* 36 * This class generates GLSL programs suitable to handle a given 37 * Description. It's responsible for figuring out what to 38 * generate from a Description. 39 * It also maintains a cache of these Programs. 40 */ 41 class ProgramCache : public Singleton<ProgramCache> { 42 public: 43 /* 44 * Key is used to retrieve a Program in the cache. 45 * A Key is generated from a Description. 46 */ 47 class Key { 48 friend class ProgramCache; 49 typedef uint32_t key_t; 50 key_t mKey; 51 52 public: 53 enum { 54 BLEND_SHIFT = 0, 55 BLEND_MASK = 1 << BLEND_SHIFT, 56 BLEND_PREMULT = 1 << BLEND_SHIFT, 57 BLEND_NORMAL = 0 << BLEND_SHIFT, 58 59 OPACITY_SHIFT = 1, 60 OPACITY_MASK = 1 << OPACITY_SHIFT, 61 OPACITY_OPAQUE = 1 << OPACITY_SHIFT, 62 OPACITY_TRANSLUCENT = 0 << OPACITY_SHIFT, 63 64 ALPHA_SHIFT = 2, 65 ALPHA_MASK = 1 << ALPHA_SHIFT, 66 ALPHA_LT_ONE = 1 << ALPHA_SHIFT, 67 ALPHA_EQ_ONE = 0 << ALPHA_SHIFT, 68 69 TEXTURE_SHIFT = 3, 70 TEXTURE_MASK = 3 << TEXTURE_SHIFT, 71 TEXTURE_OFF = 0 << TEXTURE_SHIFT, 72 TEXTURE_EXT = 1 << TEXTURE_SHIFT, 73 TEXTURE_2D = 2 << TEXTURE_SHIFT, 74 75 INPUT_TRANSFORM_MATRIX_SHIFT = 5, 76 INPUT_TRANSFORM_MATRIX_MASK = 1 << INPUT_TRANSFORM_MATRIX_SHIFT, 77 INPUT_TRANSFORM_MATRIX_OFF = 0 << INPUT_TRANSFORM_MATRIX_SHIFT, 78 INPUT_TRANSFORM_MATRIX_ON = 1 << INPUT_TRANSFORM_MATRIX_SHIFT, 79 80 OUTPUT_TRANSFORM_MATRIX_SHIFT = 6, 81 OUTPUT_TRANSFORM_MATRIX_MASK = 1 << OUTPUT_TRANSFORM_MATRIX_SHIFT, 82 OUTPUT_TRANSFORM_MATRIX_OFF = 0 << OUTPUT_TRANSFORM_MATRIX_SHIFT, 83 OUTPUT_TRANSFORM_MATRIX_ON = 1 << OUTPUT_TRANSFORM_MATRIX_SHIFT, 84 85 INPUT_TF_SHIFT = 7, 86 INPUT_TF_MASK = 3 << INPUT_TF_SHIFT, 87 INPUT_TF_LINEAR = 0 << INPUT_TF_SHIFT, 88 INPUT_TF_SRGB = 1 << INPUT_TF_SHIFT, 89 INPUT_TF_ST2084 = 2 << INPUT_TF_SHIFT, 90 INPUT_TF_HLG = 3 << INPUT_TF_SHIFT, 91 92 OUTPUT_TF_SHIFT = 9, 93 OUTPUT_TF_MASK = 3 << OUTPUT_TF_SHIFT, 94 OUTPUT_TF_LINEAR = 0 << OUTPUT_TF_SHIFT, 95 OUTPUT_TF_SRGB = 1 << OUTPUT_TF_SHIFT, 96 OUTPUT_TF_ST2084 = 2 << OUTPUT_TF_SHIFT, 97 OUTPUT_TF_HLG = 3 << OUTPUT_TF_SHIFT, 98 99 Y410_BT2020_SHIFT = 11, 100 Y410_BT2020_MASK = 1 << Y410_BT2020_SHIFT, 101 Y410_BT2020_OFF = 0 << Y410_BT2020_SHIFT, 102 Y410_BT2020_ON = 1 << Y410_BT2020_SHIFT, 103 }; 104 Key()105 inline Key() : mKey(0) {} Key(const Key & rhs)106 inline Key(const Key& rhs) : mKey(rhs.mKey) {} 107 set(key_t mask,key_t value)108 inline Key& set(key_t mask, key_t value) { 109 mKey = (mKey & ~mask) | value; 110 return *this; 111 } 112 isTexturing()113 inline bool isTexturing() const { return (mKey & TEXTURE_MASK) != TEXTURE_OFF; } getTextureTarget()114 inline int getTextureTarget() const { return (mKey & TEXTURE_MASK); } isPremultiplied()115 inline bool isPremultiplied() const { return (mKey & BLEND_MASK) == BLEND_PREMULT; } isOpaque()116 inline bool isOpaque() const { return (mKey & OPACITY_MASK) == OPACITY_OPAQUE; } hasAlpha()117 inline bool hasAlpha() const { return (mKey & ALPHA_MASK) == ALPHA_LT_ONE; } hasInputTransformMatrix()118 inline bool hasInputTransformMatrix() const { 119 return (mKey & INPUT_TRANSFORM_MATRIX_MASK) == INPUT_TRANSFORM_MATRIX_ON; 120 } hasOutputTransformMatrix()121 inline bool hasOutputTransformMatrix() const { 122 return (mKey & OUTPUT_TRANSFORM_MATRIX_MASK) == OUTPUT_TRANSFORM_MATRIX_ON; 123 } hasTransformMatrix()124 inline bool hasTransformMatrix() const { 125 return hasInputTransformMatrix() || hasOutputTransformMatrix(); 126 } getInputTF()127 inline int getInputTF() const { return (mKey & INPUT_TF_MASK); } getOutputTF()128 inline int getOutputTF() const { return (mKey & OUTPUT_TF_MASK); } 129 130 // When HDR and non-HDR contents are mixed, or different types of HDR contents are 131 // mixed, we will do a tone mapping process to tone map the input content to output 132 // content. Currently, the following conversions handled, they are: 133 // * SDR -> HLG 134 // * SDR -> PQ 135 // * HLG -> PQ needsToneMapping()136 inline bool needsToneMapping() const { 137 int inputTF = getInputTF(); 138 int outputTF = getOutputTF(); 139 140 // Return false when converting from SDR to SDR. 141 if (inputTF == Key::INPUT_TF_SRGB && outputTF == Key::OUTPUT_TF_LINEAR) { 142 return false; 143 } 144 if (inputTF == Key::INPUT_TF_LINEAR && outputTF == Key::OUTPUT_TF_SRGB) { 145 return false; 146 } 147 148 inputTF >>= Key::INPUT_TF_SHIFT; 149 outputTF >>= Key::OUTPUT_TF_SHIFT; 150 return inputTF != outputTF; 151 } isY410BT2020()152 inline bool isY410BT2020() const { return (mKey & Y410_BT2020_MASK) == Y410_BT2020_ON; } 153 154 // this is the definition of a friend function -- not a method of class Needs strictly_order_type(const Key & lhs,const Key & rhs)155 friend inline int strictly_order_type(const Key& lhs, const Key& rhs) { 156 return (lhs.mKey < rhs.mKey) ? 1 : 0; 157 } 158 }; 159 160 ProgramCache(); 161 ~ProgramCache(); 162 163 // Generate shaders to populate the cache 164 void primeCache(bool hasWideColor); 165 166 // useProgram lookup a suitable program in the cache or generates one 167 // if none can be found. 168 void useProgram(const Description& description); 169 170 private: 171 // compute a cache Key from a Description 172 static Key computeKey(const Description& description); 173 // Generate EOTF based from Key. 174 static void generateEOTF(Formatter& fs, const Key& needs); 175 // Generate necessary tone mapping methods for OOTF. 176 static void generateToneMappingProcess(Formatter& fs, const Key& needs); 177 // Generate OOTF based from Key. 178 static void generateOOTF(Formatter& fs, const Key& needs); 179 // Generate OETF based from Key. 180 static void generateOETF(Formatter& fs, const Key& needs); 181 // generates a program from the Key 182 static Program* generateProgram(const Key& needs); 183 // generates the vertex shader from the Key 184 static String8 generateVertexShader(const Key& needs); 185 // generates the fragment shader from the Key 186 static String8 generateFragmentShader(const Key& needs); 187 188 // Key/Value map used for caching Programs. Currently the cache 189 // is never shrunk. 190 DefaultKeyedVector<Key, Program*> mCache; 191 }; 192 193 ANDROID_BASIC_TYPES_TRAITS(ProgramCache::Key) 194 195 } /* namespace android */ 196 197 #endif /* SF_RENDER_ENGINE_PROGRAMCACHE_H */ 198