blob: cead75bcae2cc0cd0e3bec4ed5939ee50ad54872 [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"
30
31namespace android {
32namespace uirenderer {
33
34///////////////////////////////////////////////////////////////////////////////
35// Defines
36///////////////////////////////////////////////////////////////////////////////
37
38// Debug
Romain Guyc15008e2010-11-10 11:59:15 -080039#if DEBUG_PROGRAMS
Romain Guyac670c02010-07-27 17:39:27 -070040 #define PROGRAM_LOGD(...) LOGD(__VA_ARGS__)
41#else
42 #define PROGRAM_LOGD(...)
43#endif
44
Romain Guy707b2f72010-10-11 16:34:59 -070045// TODO: This should be set in properties
Romain Guydbc26d22010-10-11 17:58:29 -070046#define PANEL_BIT_DEPTH 20
Romain Guy707b2f72010-10-11 16:34:59 -070047#define COLOR_COMPONENT_THRESHOLD (1.0f - (0.5f / PANEL_BIT_DEPTH))
48#define COLOR_COMPONENT_INV_THRESHOLD (0.5f / PANEL_BIT_DEPTH)
49
Romain Guyac670c02010-07-27 17:39:27 -070050#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
Romain Guy889f8d12010-07-29 14:37:42 -070058#define PROGRAM_KEY_BITMAP_NPOT 0x100
Romain Guyf607bdc2010-09-10 19:20:06 -070059#define PROGRAM_KEY_SWAP_SRC_DST 0x2000
Chet Haase5b0200b2011-04-13 17:58:08 -070060#define PROGRAM_KEY_VERTEX_WIDTH 0x4000
Romain Guy889f8d12010-07-29 14:37:42 -070061
62#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
63#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800
Romain Guyac670c02010-07-27 17:39:27 -070064
Romain Guy48daa542010-08-10 19:21:34 -070065// Encode the xfermodes on 6 bits
66#define PROGRAM_MAX_XFERMODE 0x1f
67#define PROGRAM_XFERMODE_SHADER_SHIFT 26
Romain Guyac670c02010-07-27 17:39:27 -070068#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20
Romain Guya5aed0d2010-09-09 14:42:43 -070069#define PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT 14
Romain Guyac670c02010-07-27 17:39:27 -070070
Romain Guy889f8d12010-07-29 14:37:42 -070071#define PROGRAM_BITMAP_WRAPS_SHIFT 9
72#define PROGRAM_BITMAP_WRAPT_SHIFT 11
73
Romain Guyee916f12010-09-20 17:53:08 -070074#define PROGRAM_GRADIENT_TYPE_SHIFT 33
Romain Guyed6fcb02011-03-21 13:11:28 -070075#define PROGRAM_MODULATE_SHIFT 35
76
77#define PROGRAM_IS_POINT_SHIFT 36
Romain Guyee916f12010-09-20 17:53:08 -070078
Romain Guyac670c02010-07-27 17:39:27 -070079///////////////////////////////////////////////////////////////////////////////
80// Types
81///////////////////////////////////////////////////////////////////////////////
82
Romain Guyee916f12010-09-20 17:53:08 -070083typedef uint64_t programid;
Romain Guyac670c02010-07-27 17:39:27 -070084
85///////////////////////////////////////////////////////////////////////////////
86// Cache
87///////////////////////////////////////////////////////////////////////////////
88
89/**
90 * Describe the features required for a given program. The features
91 * determine the generation of both the vertex and fragment shaders.
92 * A ProgramDescription must be used in conjunction with a ProgramCache.
93 */
94struct ProgramDescription {
95 enum ColorModifier {
96 kColorNone,
97 kColorMatrix,
98 kColorLighting,
99 kColorBlend
100 };
101
Romain Guyee916f12010-09-20 17:53:08 -0700102 enum Gradient {
103 kGradientLinear,
104 kGradientCircular,
105 kGradientSweep
106 };
107
Romain Guy70ca14e2010-12-13 18:24:33 -0800108 ProgramDescription() {
109 reset();
Romain Guyac670c02010-07-27 17:39:27 -0700110 }
111
112 // Texturing
113 bool hasTexture;
114 bool hasAlpha8Texture;
115
Romain Guy707b2f72010-10-11 16:34:59 -0700116 // Modulate, this should only be set when setColor() return true
117 bool modulate;
118
Romain Guyac670c02010-07-27 17:39:27 -0700119 // Shaders
120 bool hasBitmap;
Romain Guy889f8d12010-07-29 14:37:42 -0700121 bool isBitmapNpot;
Romain Guyee916f12010-09-20 17:53:08 -0700122
Chet Haase5b0200b2011-04-13 17:58:08 -0700123 bool hasWidth;
124
Romain Guyac670c02010-07-27 17:39:27 -0700125 bool hasGradient;
Romain Guyee916f12010-09-20 17:53:08 -0700126 Gradient gradientType;
127
Romain Guyac670c02010-07-27 17:39:27 -0700128 SkXfermode::Mode shadersMode;
Romain Guyee916f12010-09-20 17:53:08 -0700129
Romain Guyac670c02010-07-27 17:39:27 -0700130 bool isBitmapFirst;
Romain Guy889f8d12010-07-29 14:37:42 -0700131 GLenum bitmapWrapS;
132 GLenum bitmapWrapT;
Romain Guyac670c02010-07-27 17:39:27 -0700133
134 // Color operations
Romain Guy4afdf662010-10-13 21:31:28 -0700135 ColorModifier colorOp;
Romain Guyac670c02010-07-27 17:39:27 -0700136 SkXfermode::Mode colorMode;
137
Romain Guya5aed0d2010-09-09 14:42:43 -0700138 // Framebuffer blending (requires Extensions.hasFramebufferFetch())
139 // Ignored for all values < SkXfermode::kPlus_Mode
140 SkXfermode::Mode framebufferMode;
Romain Guyf607bdc2010-09-10 19:20:06 -0700141 bool swapSrcDst;
Romain Guya5aed0d2010-09-09 14:42:43 -0700142
Romain Guyed6fcb02011-03-21 13:11:28 -0700143 bool isPoint;
144 float pointSize;
145
Romain Guy707b2f72010-10-11 16:34:59 -0700146 /**
Romain Guy70ca14e2010-12-13 18:24:33 -0800147 * Resets this description. All fields are reset back to the default
148 * values they hold after building a new instance.
149 */
150 void reset() {
151 hasTexture = false;
152 hasAlpha8Texture = false;
153
Chet Haase5b0200b2011-04-13 17:58:08 -0700154 hasWidth = false;
155
Romain Guy70ca14e2010-12-13 18:24:33 -0800156 modulate = false;
157
158 hasBitmap = false;
159 isBitmapNpot = false;
160
161 hasGradient = false;
162 gradientType = kGradientLinear;
163
164 shadersMode = SkXfermode::kClear_Mode;
165
166 isBitmapFirst = false;
167 bitmapWrapS = GL_CLAMP_TO_EDGE;
168 bitmapWrapT = GL_CLAMP_TO_EDGE;
169
170 colorOp = kColorNone;
171 colorMode = SkXfermode::kClear_Mode;
172
173 framebufferMode = SkXfermode::kClear_Mode;
174 swapSrcDst = false;
Romain Guyed6fcb02011-03-21 13:11:28 -0700175
176 isPoint = false;
177 pointSize = 0.0f;
Romain Guy70ca14e2010-12-13 18:24:33 -0800178 }
179
180 /**
Romain Guy707b2f72010-10-11 16:34:59 -0700181 * Indicates, for a given color, whether color modulation is required in
182 * the fragment shader. When this method returns true, the program should
183 * be provided with a modulation color.
184 */
185 bool setColor(const float r, const float g, const float b, const float a) {
186 modulate = a < COLOR_COMPONENT_THRESHOLD || r < COLOR_COMPONENT_THRESHOLD ||
187 g < COLOR_COMPONENT_THRESHOLD || b < COLOR_COMPONENT_THRESHOLD;
188 return modulate;
Romain Guy889f8d12010-07-29 14:37:42 -0700189 }
190
Romain Guy707b2f72010-10-11 16:34:59 -0700191 /**
192 * Indicates, for a given color, whether color modulation is required in
193 * the fragment shader. When this method returns true, the program should
194 * be provided with a modulation color.
195 */
196 bool setAlpha8Color(const float r, const float g, const float b, const float a) {
197 modulate = a < COLOR_COMPONENT_THRESHOLD || r > COLOR_COMPONENT_INV_THRESHOLD ||
198 g > COLOR_COMPONENT_INV_THRESHOLD || b > COLOR_COMPONENT_INV_THRESHOLD;
199 return modulate;
200 }
201
202 /**
203 * Computes the unique key identifying this program.
204 */
Romain Guyac670c02010-07-27 17:39:27 -0700205 programid key() const {
206 programid key = 0;
207 if (hasTexture) key |= PROGRAM_KEY_TEXTURE;
Chet Haase5b0200b2011-04-13 17:58:08 -0700208 if (hasWidth) key |= PROGRAM_KEY_VERTEX_WIDTH;
Romain Guyac670c02010-07-27 17:39:27 -0700209 if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE;
Romain Guy889f8d12010-07-29 14:37:42 -0700210 if (hasBitmap) {
211 key |= PROGRAM_KEY_BITMAP;
212 if (isBitmapNpot) {
213 key |= PROGRAM_KEY_BITMAP_NPOT;
214 key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT;
215 key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT;
216 }
217 }
Romain Guyac670c02010-07-27 17:39:27 -0700218 if (hasGradient) key |= PROGRAM_KEY_GRADIENT;
Romain Guyee916f12010-09-20 17:53:08 -0700219 key |= programid(gradientType) << PROGRAM_GRADIENT_TYPE_SHIFT;
220 if (isBitmapFirst) key |= PROGRAM_KEY_BITMAP_FIRST;
Romain Guyac670c02010-07-27 17:39:27 -0700221 if (hasBitmap && hasGradient) {
222 key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT;
223 }
224 switch (colorOp) {
225 case kColorMatrix:
226 key |= PROGRAM_KEY_COLOR_MATRIX;
227 break;
228 case kColorLighting:
229 key |= PROGRAM_KEY_COLOR_LIGHTING;
230 break;
231 case kColorBlend:
232 key |= PROGRAM_KEY_COLOR_BLEND;
233 key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
234 break;
235 case kColorNone:
236 break;
237 }
Romain Guya5aed0d2010-09-09 14:42:43 -0700238 key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
Romain Guyf607bdc2010-09-10 19:20:06 -0700239 if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
Romain Guyed6fcb02011-03-21 13:11:28 -0700240 if (modulate) key |= programid(0x1) << PROGRAM_MODULATE_SHIFT;
241 if (isPoint) key |= programid(0x1) << PROGRAM_IS_POINT_SHIFT;
Romain Guyac670c02010-07-27 17:39:27 -0700242 return key;
243 }
Romain Guyee916f12010-09-20 17:53:08 -0700244
Romain Guy707b2f72010-10-11 16:34:59 -0700245 /**
246 * Logs the specified message followed by the key identifying this program.
247 */
Romain Guyee916f12010-09-20 17:53:08 -0700248 void log(const char* message) const {
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700249#if DEBUG_PROGRAMS
Romain Guyee916f12010-09-20 17:53:08 -0700250 programid k = key();
251 PROGRAM_LOGD("%s (key = 0x%.8x%.8x)", message, uint32_t(k >> 32),
252 uint32_t(k & 0xffffffff));
Romain Guy7b5b6ab2011-03-14 18:05:08 -0700253#endif
Romain Guyee916f12010-09-20 17:53:08 -0700254 }
Romain Guy707b2f72010-10-11 16:34:59 -0700255
256private:
257 inline uint32_t getEnumForWrap(GLenum wrap) const {
258 switch (wrap) {
259 case GL_CLAMP_TO_EDGE:
260 return 0;
261 case GL_REPEAT:
262 return 1;
263 case GL_MIRRORED_REPEAT:
264 return 2;
265 }
266 return 0;
267 }
268
Romain Guyac670c02010-07-27 17:39:27 -0700269}; // struct ProgramDescription
270
271/**
272 * Generates and caches program. Programs are generated based on
273 * ProgramDescriptions.
274 */
275class ProgramCache {
276public:
277 ProgramCache();
278 ~ProgramCache();
279
280 Program* get(const ProgramDescription& description);
281
282 void clear();
283
284private:
285 Program* generateProgram(const ProgramDescription& description, programid key);
286 String8 generateVertexShader(const ProgramDescription& description);
287 String8 generateFragmentShader(const ProgramDescription& description);
Romain Guy48daa542010-08-10 19:21:34 -0700288 void generateBlend(String8& shader, const char* name, SkXfermode::Mode mode);
Romain Guy889f8d12010-07-29 14:37:42 -0700289 void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT);
Romain Guyac670c02010-07-27 17:39:27 -0700290
Romain Guydb1938e2010-08-02 18:50:22 -0700291 void printLongString(const String8& shader) const;
292
Romain Guyac670c02010-07-27 17:39:27 -0700293 KeyedVector<programid, Program*> mCache;
Romain Guyac670c02010-07-27 17:39:27 -0700294}; // class ProgramCache
295
296}; // namespace uirenderer
297}; // namespace android
298
Romain Guy5b3b3522010-10-27 18:57:51 -0700299#endif // ANDROID_HWUI_PROGRAM_CACHE_H