blob: d60f6cefc2405c932ee309673cf9b8b6e05c9d73 [file] [log] [blame]
Romain Guyac670c02010-07-27 17:39:27 -07001/*
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>
Romain Guy06f96e22010-07-30 19:18:16 -070022#include <utils/String8.h>
Romain Guyac670c02010-07-27 17:39:27 -070023
Romain Guy889f8d12010-07-29 14:37:42 -070024#include <GLES2/gl2.h>
25
Romain Guyac670c02010-07-27 17:39:27 -070026#include <SkXfermode.h>
27
28#include "Program.h"
29
30namespace android {
31namespace uirenderer {
32
33///////////////////////////////////////////////////////////////////////////////
34// Defines
35///////////////////////////////////////////////////////////////////////////////
36
37// Debug
Romain Guy889f8d12010-07-29 14:37:42 -070038#define DEBUG_PROGRAM_CACHE 1
Romain Guyac670c02010-07-27 17:39:27 -070039
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
Romain Guy889f8d12010-07-29 14:37:42 -070055#define PROGRAM_KEY_BITMAP_NPOT 0x100
56
57#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
58#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800
Romain Guyac670c02010-07-27 17:39:27 -070059
60// Support only the 12 Porter-Duff modes for now
61#define PROGRAM_MAX_XFERMODE 0xC
62#define PROGRAM_XFERMODE_SHADER_SHIFT 24
63#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20
64
Romain Guy889f8d12010-07-29 14:37:42 -070065#define PROGRAM_BITMAP_WRAPS_SHIFT 9
66#define PROGRAM_BITMAP_WRAPT_SHIFT 11
67
Romain Guyac670c02010-07-27 17:39:27 -070068///////////////////////////////////////////////////////////////////////////////
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),
Romain Guy889f8d12010-07-29 14:37:42 -070093 hasBitmap(false), isBitmapNpot(false), hasGradient(false),
94 shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false),
95 bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE),
Romain Guyac670c02010-07-27 17:39:27 -070096 colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode) {
97 }
98
99 // Texturing
100 bool hasTexture;
101 bool hasAlpha8Texture;
102
103 // Shaders
104 bool hasBitmap;
Romain Guy889f8d12010-07-29 14:37:42 -0700105 bool isBitmapNpot;
Romain Guyac670c02010-07-27 17:39:27 -0700106 bool hasGradient;
107 SkXfermode::Mode shadersMode;
108 bool isBitmapFirst;
Romain Guy889f8d12010-07-29 14:37:42 -0700109 GLenum bitmapWrapS;
110 GLenum bitmapWrapT;
Romain Guyac670c02010-07-27 17:39:27 -0700111
112 // Color operations
113 int colorOp;
114 SkXfermode::Mode colorMode;
115
Romain Guy889f8d12010-07-29 14:37:42 -0700116 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
Romain Guyac670c02010-07-27 17:39:27 -0700128 programid key() const {
129 programid key = 0;
130 if (hasTexture) key |= PROGRAM_KEY_TEXTURE;
131 if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE;
Romain Guy889f8d12010-07-29 14:37:42 -0700132 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 }
Romain Guyac670c02010-07-27 17:39:27 -0700140 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 generatePorterDuffBlend(String8& shader, const char* name, SkXfermode::Mode mode);
Romain Guy889f8d12010-07-29 14:37:42 -0700181 void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT);
Romain Guyac670c02010-07-27 17:39:27 -0700182
183 KeyedVector<programid, Program*> mCache;
184
185}; // class ProgramCache
186
187}; // namespace uirenderer
188}; // namespace android
189
190#endif // ANDROID_UI_PROGRAM_CACHE_H