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/Singleton.h>
23 #include <utils/KeyedVector.h>
24 #include <utils/TypeHelpers.h>
25 
26 #include "Description.h"
27 
28 namespace android {
29 
30 class Description;
31 class Program;
32 class String8;
33 
34 /*
35  * This class generates GLSL programs suitable to handle a given
36  * Description. It's responsible for figuring out what to
37  * generate from a Description.
38  * It also maintains a cache of these Programs.
39  */
40 class ProgramCache : public Singleton<ProgramCache> {
41 public:
42     /*
43      * Key is used to retrieve a Program in the cache.
44      * A Key is generated from a Description.
45      */
46     class Key {
47         friend class ProgramCache;
48         typedef uint32_t key_t;
49         key_t mKey;
50     public:
51         enum {
52             BLEND_PREMULT           =       0x00000001,
53             BLEND_NORMAL            =       0x00000000,
54             BLEND_MASK              =       0x00000001,
55 
56             OPACITY_OPAQUE          =       0x00000002,
57             OPACITY_TRANSLUCENT     =       0x00000000,
58             OPACITY_MASK            =       0x00000002,
59 
60             PLANE_ALPHA_LT_ONE      =       0x00000004,
61             PLANE_ALPHA_EQ_ONE      =       0x00000000,
62             PLANE_ALPHA_MASK        =       0x00000004,
63 
64             TEXTURE_OFF             =       0x00000000,
65             TEXTURE_EXT             =       0x00000008,
66             TEXTURE_2D              =       0x00000010,
67             TEXTURE_MASK            =       0x00000018,
68 
69             COLOR_MATRIX_OFF        =       0x00000000,
70             COLOR_MATRIX_ON         =       0x00000020,
71             COLOR_MATRIX_MASK       =       0x00000020,
72         };
73 
Key()74         inline Key() : mKey(0) { }
Key(const Key & rhs)75         inline Key(const Key& rhs) : mKey(rhs.mKey) { }
76 
set(key_t mask,key_t value)77         inline Key& set(key_t mask, key_t value) {
78             mKey = (mKey & ~mask) | value;
79             return *this;
80         }
81 
isTexturing()82         inline bool isTexturing() const {
83             return (mKey & TEXTURE_MASK) != TEXTURE_OFF;
84         }
getTextureTarget()85         inline int getTextureTarget() const {
86             return (mKey & TEXTURE_MASK);
87         }
isPremultiplied()88         inline bool isPremultiplied() const {
89             return (mKey & BLEND_MASK) == BLEND_PREMULT;
90         }
isOpaque()91         inline bool isOpaque() const {
92             return (mKey & OPACITY_MASK) == OPACITY_OPAQUE;
93         }
hasPlaneAlpha()94         inline bool hasPlaneAlpha() const {
95             return (mKey & PLANE_ALPHA_MASK) == PLANE_ALPHA_LT_ONE;
96         }
hasColorMatrix()97         inline bool hasColorMatrix() const {
98             return (mKey & COLOR_MATRIX_MASK) == COLOR_MATRIX_ON;
99         }
100 
101         // this is the definition of a friend function -- not a method of class Needs
strictly_order_type(const Key & lhs,const Key & rhs)102         friend inline int strictly_order_type(const Key& lhs, const Key& rhs) {
103             return  (lhs.mKey < rhs.mKey) ? 1 : 0;
104         }
105     };
106 
107     ProgramCache();
108     ~ProgramCache();
109 
110     // useProgram lookup a suitable program in the cache or generates one
111     // if none can be found.
112     void useProgram(const Description& description);
113 
114 private:
115     // Generate shaders to populate the cache
116     void primeCache();
117     // compute a cache Key from a Description
118     static Key computeKey(const Description& description);
119     // generates a program from the Key
120     static Program* generateProgram(const Key& needs);
121     // generates the vertex shader from the Key
122     static String8 generateVertexShader(const Key& needs);
123     // generates the fragment shader from the Key
124     static String8 generateFragmentShader(const Key& needs);
125 
126     // Key/Value map used for caching Programs. Currently the cache
127     // is never shrunk.
128     DefaultKeyedVector<Key, Program*> mCache;
129 };
130 
131 
132 ANDROID_BASIC_TYPES_TRAITS(ProgramCache::Key)
133 
134 } /* namespace android */
135 
136 #endif /* SF_RENDER_ENGINE_PROGRAMCACHE_H */
137