Home | History | Annotate | Download | only in RenderEngine
      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 
    105         inline Key() : mKey(0) {}
    106         inline Key(const Key& rhs) : mKey(rhs.mKey) {}
    107 
    108         inline Key& set(key_t mask, key_t value) {
    109             mKey = (mKey & ~mask) | value;
    110             return *this;
    111         }
    112 
    113         inline bool isTexturing() const { return (mKey & TEXTURE_MASK) != TEXTURE_OFF; }
    114         inline int getTextureTarget() const { return (mKey & TEXTURE_MASK); }
    115         inline bool isPremultiplied() const { return (mKey & BLEND_MASK) == BLEND_PREMULT; }
    116         inline bool isOpaque() const { return (mKey & OPACITY_MASK) == OPACITY_OPAQUE; }
    117         inline bool hasAlpha() const { return (mKey & ALPHA_MASK) == ALPHA_LT_ONE; }
    118         inline bool hasInputTransformMatrix() const {
    119             return (mKey & INPUT_TRANSFORM_MATRIX_MASK) == INPUT_TRANSFORM_MATRIX_ON;
    120         }
    121         inline bool hasOutputTransformMatrix() const {
    122             return (mKey & OUTPUT_TRANSFORM_MATRIX_MASK) == OUTPUT_TRANSFORM_MATRIX_ON;
    123         }
    124         inline bool hasTransformMatrix() const {
    125             return hasInputTransformMatrix() || hasOutputTransformMatrix();
    126         }
    127         inline int getInputTF() const { return (mKey & INPUT_TF_MASK); }
    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
    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         }
    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
    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