ProgramCache.h revision 48daa54d31fc59ec969dcff65eb3cbb0ce879a8d
1/*
2 * Copyright (C) 2010 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 ANDROID_UI_PROGRAM_CACHE_H
18#define ANDROID_UI_PROGRAM_CACHE_H
19
20#include <utils/KeyedVector.h>
21#include <utils/Log.h>
22#include <utils/String8.h>
23
24#include <GLES2/gl2.h>
25
26#include <SkXfermode.h>
27
28#include "Program.h"
29
30namespace android {
31namespace uirenderer {
32
33///////////////////////////////////////////////////////////////////////////////
34// Defines
35///////////////////////////////////////////////////////////////////////////////
36
37// Debug
38#define DEBUG_PROGRAM_CACHE 1
39
40// Debug
41#if DEBUG_PROGRAM_CACHE
42    #define PROGRAM_LOGD(...) LOGD(__VA_ARGS__)
43#else
44    #define PROGRAM_LOGD(...)
45#endif
46
47#define PROGRAM_KEY_TEXTURE 0x1
48#define PROGRAM_KEY_A8_TEXTURE 0x2
49#define PROGRAM_KEY_BITMAP 0x4
50#define PROGRAM_KEY_GRADIENT 0x8
51#define PROGRAM_KEY_BITMAP_FIRST 0x10
52#define PROGRAM_KEY_COLOR_MATRIX 0x20
53#define PROGRAM_KEY_COLOR_LIGHTING 0x40
54#define PROGRAM_KEY_COLOR_BLEND 0x80
55#define PROGRAM_KEY_BITMAP_NPOT 0x100
56
57#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
58#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800
59
60// Encode the xfermodes on 6 bits
61#define PROGRAM_MAX_XFERMODE 0x1f
62#define PROGRAM_XFERMODE_SHADER_SHIFT 26
63#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20
64
65#define PROGRAM_BITMAP_WRAPS_SHIFT 9
66#define PROGRAM_BITMAP_WRAPT_SHIFT 11
67
68///////////////////////////////////////////////////////////////////////////////
69// Types
70///////////////////////////////////////////////////////////////////////////////
71
72typedef uint32_t programid;
73
74///////////////////////////////////////////////////////////////////////////////
75// Cache
76///////////////////////////////////////////////////////////////////////////////
77
78/**
79 * Describe the features required for a given program. The features
80 * determine the generation of both the vertex and fragment shaders.
81 * A ProgramDescription must be used in conjunction with a ProgramCache.
82 */
83struct ProgramDescription {
84    enum ColorModifier {
85        kColorNone,
86        kColorMatrix,
87        kColorLighting,
88        kColorBlend
89    };
90
91    ProgramDescription():
92        hasTexture(false), hasAlpha8Texture(false),
93        hasBitmap(false), isBitmapNpot(false), hasGradient(false),
94        shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false),
95        bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE),
96        colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode) {
97    }
98
99    // Texturing
100    bool hasTexture;
101    bool hasAlpha8Texture;
102
103    // Shaders
104    bool hasBitmap;
105    bool isBitmapNpot;
106    bool hasGradient;
107    SkXfermode::Mode shadersMode;
108    bool isBitmapFirst;
109    GLenum bitmapWrapS;
110    GLenum bitmapWrapT;
111
112    // Color operations
113    int colorOp;
114    SkXfermode::Mode colorMode;
115
116    inline uint32_t getEnumForWrap(GLenum wrap) const {
117        switch (wrap) {
118            case GL_CLAMP_TO_EDGE:
119                return 0;
120            case GL_REPEAT:
121                return 1;
122            case GL_MIRRORED_REPEAT:
123                return 2;
124        }
125        return 0;
126    }
127
128    programid key() const {
129        programid key = 0;
130        if (hasTexture) key |= PROGRAM_KEY_TEXTURE;
131        if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE;
132        if (hasBitmap) {
133            key |= PROGRAM_KEY_BITMAP;
134            if (isBitmapNpot) {
135                key |= PROGRAM_KEY_BITMAP_NPOT;
136                key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT;
137                key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT;
138            }
139        }
140        if (hasGradient) key |= PROGRAM_KEY_GRADIENT;
141        if (isBitmapFirst) key  |= PROGRAM_KEY_BITMAP_FIRST;
142        if (hasBitmap && hasGradient) {
143            key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT;
144        }
145        switch (colorOp) {
146            case kColorMatrix:
147                key |= PROGRAM_KEY_COLOR_MATRIX;
148                break;
149            case kColorLighting:
150                key |= PROGRAM_KEY_COLOR_LIGHTING;
151                break;
152            case kColorBlend:
153                key |= PROGRAM_KEY_COLOR_BLEND;
154                key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
155                break;
156            case kColorNone:
157                break;
158        }
159        return key;
160    }
161}; // struct ProgramDescription
162
163/**
164 * Generates and caches program. Programs are generated based on
165 * ProgramDescriptions.
166 */
167class ProgramCache {
168public:
169    ProgramCache();
170    ~ProgramCache();
171
172    Program* get(const ProgramDescription& description);
173
174    void clear();
175
176private:
177    Program* generateProgram(const ProgramDescription& description, programid key);
178    String8 generateVertexShader(const ProgramDescription& description);
179    String8 generateFragmentShader(const ProgramDescription& description);
180    void generateBlend(String8& shader, const char* name, SkXfermode::Mode mode);
181    void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT);
182
183    void printLongString(const String8& shader) const;
184
185    KeyedVector<programid, Program*> mCache;
186
187}; // class ProgramCache
188
189}; // namespace uirenderer
190}; // namespace android
191
192#endif // ANDROID_UI_PROGRAM_CACHE_H
193