blob: 441db8c8cb0af29474b7f5935f91cedf38b51ff3 [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
Romain Guy5b3b3522010-10-27 18:57:51 -070017#ifndef ANDROID_HWUI_PROGRAM_CACHE_H
18#define ANDROID_HWUI_PROGRAM_CACHE_H
Romain Guyac670c02010-07-27 17:39:27 -070019
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
Romain Guyc15008e2010-11-10 11:59:15 -080028#include "Debug.h"
Romain Guyac670c02010-07-27 17:39:27 -070029#include "Program.h"
Romain Guy24edca82011-12-09 13:08:06 -080030#include "Properties.h"
Romain Guyac670c02010-07-27 17:39:27 -070031
32namespace android {
33namespace uirenderer {
34
35///////////////////////////////////////////////////////////////////////////////
36// Defines
37///////////////////////////////////////////////////////////////////////////////
38
39// Debug
Romain Guyc15008e2010-11-10 11:59:15 -080040#if DEBUG_PROGRAMS
Romain Guyac670c02010-07-27 17:39:27 -070041 #define PROGRAM_LOGD(...) LOGD(__VA_ARGS__)
42#else
43 #define PROGRAM_LOGD(...)
44#endif
45
Romain Guy707b2f72010-10-11 16:34:59 -070046#define COLOR_COMPONENT_THRESHOLD (1.0f - (0.5f / PANEL_BIT_DEPTH))
47#define COLOR_COMPONENT_INV_THRESHOLD (0.5f / PANEL_BIT_DEPTH)
48
Romain Guyac670c02010-07-27 17:39:27 -070049#define PROGRAM_KEY_TEXTURE 0x1
50#define PROGRAM_KEY_A8_TEXTURE 0x2
51#define PROGRAM_KEY_BITMAP 0x4
52#define PROGRAM_KEY_GRADIENT 0x8
53#define PROGRAM_KEY_BITMAP_FIRST 0x10
54#define PROGRAM_KEY_COLOR_MATRIX 0x20
55#define PROGRAM_KEY_COLOR_LIGHTING 0x40
56#define PROGRAM_KEY_COLOR_BLEND 0x80
Romain Guy889f8d12010-07-29 14:37:42 -070057#define PROGRAM_KEY_BITMAP_NPOT 0x100
Romain Guyf607bdc2010-09-10 19:20:06 -070058#define PROGRAM_KEY_SWAP_SRC_DST 0x2000
Romain Guy889f8d12010-07-29 14:37:42 -070059
60#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
61#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800
Romain Guyac670c02010-07-27 17:39:27 -070062
Romain Guy48daa542010-08-10 19:21:34 -070063// Encode the xfermodes on 6 bits
64#define PROGRAM_MAX_XFERMODE 0x1f
65#define PROGRAM_XFERMODE_SHADER_SHIFT 26
Romain Guyac670c02010-07-27 17:39:27 -070066#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20
Romain Guya5aed0d2010-09-09 14:42:43 -070067#define PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT 14
Romain Guyac670c02010-07-27 17:39:27 -070068
Romain Guy889f8d12010-07-29 14:37:42 -070069#define PROGRAM_BITMAP_WRAPS_SHIFT 9
70#define PROGRAM_BITMAP_WRAPT_SHIFT 11
71
Romain Guyee916f12010-09-20 17:53:08 -070072#define PROGRAM_GRADIENT_TYPE_SHIFT 33
Romain Guyed6fcb02011-03-21 13:11:28 -070073#define PROGRAM_MODULATE_SHIFT 35
74
75#define PROGRAM_IS_POINT_SHIFT 36
Romain Guyee916f12010-09-20 17:53:08 -070076
Chet Haase99585ad2011-05-02 15:00:16 -070077#define PROGRAM_HAS_AA_SHIFT 37
Chet Haase6fca9882011-04-25 14:49:07 -070078
Romain Guyaa6c24c2011-04-28 18:40:04 -070079#define PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT 38
Romain Guy8f0095c2011-05-02 17:24:22 -070080#define PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT 39
Romain Guyaa6c24c2011-04-28 18:40:04 -070081
Romain Guyac670c02010-07-27 17:39:27 -070082///////////////////////////////////////////////////////////////////////////////
83// Types
84///////////////////////////////////////////////////////////////////////////////
85
Romain Guyee916f12010-09-20 17:53:08 -070086typedef uint64_t programid;
Romain Guyac670c02010-07-27 17:39:27 -070087
88///////////////////////////////////////////////////////////////////////////////
89// Cache
90///////////////////////////////////////////////////////////////////////////////
91
92/**
93 * Describe the features required for a given program. The features
94 * determine the generation of both the vertex and fragment shaders.
95 * A ProgramDescription must be used in conjunction with a ProgramCache.
96 */
97struct ProgramDescription {
98 enum ColorModifier {
99 kColorNone,
100 kColorMatrix,
101 kColorLighting,
102 kColorBlend
103 };
104
Romain Guyee916f12010-09-20 17:53:08 -0700105 enum Gradient {
106 kGradientLinear,
107 kGradientCircular,
108 kGradientSweep
109 };
110
Romain Guy70ca14e2010-12-13 18:24:33 -0800111 ProgramDescription() {
112 reset();
Romain Guyac670c02010-07-27 17:39:27 -0700113 }
114
115 // Texturing
116 bool hasTexture;
117 bool hasAlpha8Texture;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700118 bool hasExternalTexture;
Romain Guy8f0095c2011-05-02 17:24:22 -0700119 bool hasTextureTransform;
Romain Guyac670c02010-07-27 17:39:27 -0700120
Romain Guy707b2f72010-10-11 16:34:59 -0700121 // Modulate, this should only be set when setColor() return true
122 bool modulate;
123
Romain Guyac670c02010-07-27 17:39:27 -0700124 // Shaders
125 bool hasBitmap;
Romain Guy889f8d12010-07-29 14:37:42 -0700126 bool isBitmapNpot;
Romain Guyee916f12010-09-20 17:53:08 -0700127
Chet Haase99585ad2011-05-02 15:00:16 -0700128 bool isAA;
Chet Haase5b0200b2011-04-13 17:58:08 -0700129
Romain Guyac670c02010-07-27 17:39:27 -0700130 bool hasGradient;
Romain Guyee916f12010-09-20 17:53:08 -0700131 Gradient gradientType;
132
Romain Guyac670c02010-07-27 17:39:27 -0700133 SkXfermode::Mode shadersMode;
Romain Guyee916f12010-09-20 17:53:08 -0700134
Romain Guyac670c02010-07-27 17:39:27 -0700135 bool isBitmapFirst;
Romain Guy889f8d12010-07-29 14:37:42 -0700136 GLenum bitmapWrapS;
137 GLenum bitmapWrapT;
Romain Guyac670c02010-07-27 17:39:27 -0700138
139 // Color operations
Romain Guy4afdf662010-10-13 21:31:28 -0700140 ColorModifier colorOp;
Romain Guyac670c02010-07-27 17:39:27 -0700141 SkXfermode::Mode colorMode;
142
Romain Guya5aed0d2010-09-09 14:42:43 -0700143 // Framebuffer blending (requires Extensions.hasFramebufferFetch())
144 // Ignored for all values < SkXfermode::kPlus_Mode
145 SkXfermode::Mode framebufferMode;
Romain Guyf607bdc2010-09-10 19:20:06 -0700146 bool swapSrcDst;
Romain Guya5aed0d2010-09-09 14:42:43 -0700147
Romain Guyed6fcb02011-03-21 13:11:28 -0700148 bool isPoint;
149 float pointSize;
150
Romain Guy707b2f72010-10-11 16:34:59 -0700151 /**
Romain Guy70ca14e2010-12-13 18:24:33 -0800152 * Resets this description. All fields are reset back to the default
153 * values they hold after building a new instance.
154 */
155 void reset() {
156 hasTexture = false;
157 hasAlpha8Texture = false;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700158 hasExternalTexture = false;
Romain Guy8f0095c2011-05-02 17:24:22 -0700159 hasTextureTransform = false;
Romain Guy70ca14e2010-12-13 18:24:33 -0800160
Chet Haase99585ad2011-05-02 15:00:16 -0700161 isAA = false;
Chet Haase5b0200b2011-04-13 17:58:08 -0700162
Romain Guy70ca14e2010-12-13 18:24:33 -0800163 modulate = false;
164
165 hasBitmap = false;
166 isBitmapNpot = false;
167
168 hasGradient = false;
169 gradientType = kGradientLinear;
170
171 shadersMode = SkXfermode::kClear_Mode;
172
173 isBitmapFirst = false;
174 bitmapWrapS = GL_CLAMP_TO_EDGE;
175 bitmapWrapT = GL_CLAMP_TO_EDGE;
176
177 colorOp = kColorNone;
178 colorMode = SkXfermode::kClear_Mode;
179
180 framebufferMode = SkXfermode::kClear_Mode;
181 swapSrcDst = false;
Romain Guyed6fcb02011-03-21 13:11:28 -0700182
183 isPoint = false;
184 pointSize = 0.0f;
Romain Guy70ca14e2010-12-13 18:24:33 -0800185 }
186
187 /**
Romain Guy707b2f72010-10-11 16:34:59 -0700188 * Indicates, for a given color, whether color modulation is required in
189 * the fragment shader. When this method returns true, the program should
190 * be provided with a modulation color.
191 */
192 bool setColor(const float r, const float g, const float b, const float a) {
193 modulate = a < COLOR_COMPONENT_THRESHOLD || r < COLOR_COMPONENT_THRESHOLD ||
194 g < COLOR_COMPONENT_THRESHOLD || b < COLOR_COMPONENT_THRESHOLD;
195 return modulate;
Romain Guy889f8d12010-07-29 14:37:42 -0700196 }
197
Romain Guy707b2f72010-10-11 16:34:59 -0700198 /**
199 * Indicates, for a given color, whether color modulation is required in
200 * the fragment shader. When this method returns true, the program should
201 * be provided with a modulation color.
202 */
203 bool setAlpha8Color(const float r, const float g, const float b, const float a) {
204 modulate = a < COLOR_COMPONENT_THRESHOLD || r > COLOR_COMPONENT_INV_THRESHOLD ||
205 g > COLOR_COMPONENT_INV_THRESHOLD || b > COLOR_COMPONENT_INV_THRESHOLD;
206 return modulate;
207 }
208
209 /**
210 * Computes the unique key identifying this program.
211 */
Romain Guyac670c02010-07-27 17:39:27 -0700212 programid key() const {
213 programid key = 0;
214 if (hasTexture) key |= PROGRAM_KEY_TEXTURE;
215 if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE;
Romain Guy889f8d12010-07-29 14:37:42 -0700216 if (hasBitmap) {
217 key |= PROGRAM_KEY_BITMAP;
218 if (isBitmapNpot) {
219 key |= PROGRAM_KEY_BITMAP_NPOT;
220 key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT;
221 key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT;
222 }
223 }
Romain Guyac670c02010-07-27 17:39:27 -0700224 if (hasGradient) key |= PROGRAM_KEY_GRADIENT;
Romain Guyee916f12010-09-20 17:53:08 -0700225 key |= programid(gradientType) << PROGRAM_GRADIENT_TYPE_SHIFT;
226 if (isBitmapFirst) key |= PROGRAM_KEY_BITMAP_FIRST;
Romain Guyac670c02010-07-27 17:39:27 -0700227 if (hasBitmap && hasGradient) {
228 key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT;
229 }
230 switch (colorOp) {
231 case kColorMatrix:
232 key |= PROGRAM_KEY_COLOR_MATRIX;
233 break;
234 case kColorLighting:
235 key |= PROGRAM_KEY_COLOR_LIGHTING;
236 break;
237 case kColorBlend:
238 key |= PROGRAM_KEY_COLOR_BLEND;
239 key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
240 break;
241 case kColorNone:
242 break;
243 }
Romain Guya5aed0d2010-09-09 14:42:43 -0700244 key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
Romain Guyf607bdc2010-09-10 19:20:06 -0700245 if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
Romain Guyed6fcb02011-03-21 13:11:28 -0700246 if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
247 if (isPoint) key |= programid(0x1) << PROGRAM_IS_POINT_SHIFT;
Chet Haase99585ad2011-05-02 15:00:16 -0700248 if (isAA) key |= programid(0x1) << PROGRAM_HAS_AA_SHIFT;
Romain Guyaa6c24c2011-04-28 18:40:04 -0700249 if (hasExternalTexture) key |= programid(0x1) << PROGRAM_HAS_EXTERNAL_TEXTURE_SHIFT;
Romain Guy8f0095c2011-05-02 17:24:22 -0700250 if (hasTextureTransform) key |= programid(0x1) << PROGRAM_HAS_TEXTURE_TRANSFORM_SHIFT;
Romain Guyac670c02010-07-27 17:39:27 -0700251 return key;
252 }
Romain Guyee916f12010-09-20 17:53:08 -0700253
Romain Guy707b2f72010-10-11 16:34:59 -0700254 /**
255 * Logs the specified message followed by the key identifying this program.
256 */
Romain Guyee916f12010-09-20 17:53:08 -0700257 void log(const char* message) const {
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700258#if DEBUG_PROGRAMS
Romain Guyee916f12010-09-20 17:53:08 -0700259 programid k = key();
260 PROGRAM_LOGD("%s (key = 0x%.8x%.8x)", message, uint32_t(k >> 32),
261 uint32_t(k & 0xffffffff));
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700262#endif
Romain Guyee916f12010-09-20 17:53:08 -0700263 }
Romain Guy707b2f72010-10-11 16:34:59 -0700264
265private:
266 inline uint32_t getEnumForWrap(GLenum wrap) const {
267 switch (wrap) {
268 case GL_CLAMP_TO_EDGE:
269 return 0;
270 case GL_REPEAT:
271 return 1;
272 case GL_MIRRORED_REPEAT:
273 return 2;
274 }
275 return 0;
276 }
277
Romain Guyac670c02010-07-27 17:39:27 -0700278}; // struct ProgramDescription
279
280/**
281 * Generates and caches program. Programs are generated based on
282 * ProgramDescriptions.
283 */
284class ProgramCache {
285public:
286 ProgramCache();
287 ~ProgramCache();
288
289 Program* get(const ProgramDescription& description);
290
291 void clear();
292
293private:
294 Program* generateProgram(const ProgramDescription& description, programid key);
295 String8 generateVertexShader(const ProgramDescription& description);
296 String8 generateFragmentShader(const ProgramDescription& description);
Romain Guy48daa542010-08-10 19:21:34 -0700297 void generateBlend(String8& shader, const char* name, SkXfermode::Mode mode);
Romain Guy889f8d12010-07-29 14:37:42 -0700298 void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT);
Romain Guyac670c02010-07-27 17:39:27 -0700299
Romain Guydb1938e2010-08-02 18:50:22 -0700300 void printLongString(const String8& shader) const;
301
Romain Guyac670c02010-07-27 17:39:27 -0700302 KeyedVector<programid, Program*> mCache;
Romain Guyac670c02010-07-27 17:39:27 -0700303}; // class ProgramCache
304
305}; // namespace uirenderer
306}; // namespace android
307
Romain Guy5b3b3522010-10-27 18:57:51 -0700308#endif // ANDROID_HWUI_PROGRAM_CACHE_H