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