blob: 4fa80111d358b0a46c1adf3afb4449625732dabf [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 Guyf607bdc2010-09-10 19:20:06 -070038#define DEBUG_PROGRAM_CACHE 0
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
Romain Guyf607bdc2010-09-10 19:20:06 -070056#define PROGRAM_KEY_SWAP_SRC_DST 0x2000
Romain Guy889f8d12010-07-29 14:37:42 -070057
58#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600
59#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800
Romain Guyac670c02010-07-27 17:39:27 -070060
Romain Guy48daa542010-08-10 19:21:34 -070061// Encode the xfermodes on 6 bits
62#define PROGRAM_MAX_XFERMODE 0x1f
63#define PROGRAM_XFERMODE_SHADER_SHIFT 26
Romain Guyac670c02010-07-27 17:39:27 -070064#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20
Romain Guya5aed0d2010-09-09 14:42:43 -070065#define PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT 14
Romain Guyac670c02010-07-27 17:39:27 -070066
Romain Guy889f8d12010-07-29 14:37:42 -070067#define PROGRAM_BITMAP_WRAPS_SHIFT 9
68#define PROGRAM_BITMAP_WRAPT_SHIFT 11
69
Romain Guyee916f12010-09-20 17:53:08 -070070#define PROGRAM_GRADIENT_TYPE_SHIFT 33
71
Romain Guyac670c02010-07-27 17:39:27 -070072///////////////////////////////////////////////////////////////////////////////
73// Types
74///////////////////////////////////////////////////////////////////////////////
75
Romain Guyee916f12010-09-20 17:53:08 -070076typedef uint64_t programid;
Romain Guyac670c02010-07-27 17:39:27 -070077
78///////////////////////////////////////////////////////////////////////////////
79// Cache
80///////////////////////////////////////////////////////////////////////////////
81
82/**
83 * Describe the features required for a given program. The features
84 * determine the generation of both the vertex and fragment shaders.
85 * A ProgramDescription must be used in conjunction with a ProgramCache.
86 */
87struct ProgramDescription {
88 enum ColorModifier {
89 kColorNone,
90 kColorMatrix,
91 kColorLighting,
92 kColorBlend
93 };
94
Romain Guyee916f12010-09-20 17:53:08 -070095 enum Gradient {
96 kGradientLinear,
97 kGradientCircular,
98 kGradientSweep
99 };
100
Romain Guyac670c02010-07-27 17:39:27 -0700101 ProgramDescription():
102 hasTexture(false), hasAlpha8Texture(false),
Romain Guy889f8d12010-07-29 14:37:42 -0700103 hasBitmap(false), isBitmapNpot(false), hasGradient(false),
Romain Guyee916f12010-09-20 17:53:08 -0700104 gradientType(kGradientLinear),
Romain Guy889f8d12010-07-29 14:37:42 -0700105 shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false),
106 bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE),
Romain Guya5aed0d2010-09-09 14:42:43 -0700107 colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode),
Romain Guyf607bdc2010-09-10 19:20:06 -0700108 framebufferMode(SkXfermode::kClear_Mode), swapSrcDst(false) {
Romain Guyac670c02010-07-27 17:39:27 -0700109 }
110
111 // Texturing
112 bool hasTexture;
113 bool hasAlpha8Texture;
114
115 // Shaders
116 bool hasBitmap;
Romain Guy889f8d12010-07-29 14:37:42 -0700117 bool isBitmapNpot;
Romain Guyee916f12010-09-20 17:53:08 -0700118
Romain Guyac670c02010-07-27 17:39:27 -0700119 bool hasGradient;
Romain Guyee916f12010-09-20 17:53:08 -0700120 Gradient gradientType;
121
Romain Guyac670c02010-07-27 17:39:27 -0700122 SkXfermode::Mode shadersMode;
Romain Guyee916f12010-09-20 17:53:08 -0700123
Romain Guyac670c02010-07-27 17:39:27 -0700124 bool isBitmapFirst;
Romain Guy889f8d12010-07-29 14:37:42 -0700125 GLenum bitmapWrapS;
126 GLenum bitmapWrapT;
Romain Guyac670c02010-07-27 17:39:27 -0700127
128 // Color operations
129 int colorOp;
130 SkXfermode::Mode colorMode;
131
Romain Guya5aed0d2010-09-09 14:42:43 -0700132 // Framebuffer blending (requires Extensions.hasFramebufferFetch())
133 // Ignored for all values < SkXfermode::kPlus_Mode
134 SkXfermode::Mode framebufferMode;
Romain Guyf607bdc2010-09-10 19:20:06 -0700135 bool swapSrcDst;
Romain Guya5aed0d2010-09-09 14:42:43 -0700136
Romain Guy889f8d12010-07-29 14:37:42 -0700137 inline uint32_t getEnumForWrap(GLenum wrap) const {
138 switch (wrap) {
139 case GL_CLAMP_TO_EDGE:
140 return 0;
141 case GL_REPEAT:
142 return 1;
143 case GL_MIRRORED_REPEAT:
144 return 2;
145 }
146 return 0;
147 }
148
Romain Guyac670c02010-07-27 17:39:27 -0700149 programid key() const {
150 programid key = 0;
151 if (hasTexture) key |= PROGRAM_KEY_TEXTURE;
152 if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE;
Romain Guy889f8d12010-07-29 14:37:42 -0700153 if (hasBitmap) {
154 key |= PROGRAM_KEY_BITMAP;
155 if (isBitmapNpot) {
156 key |= PROGRAM_KEY_BITMAP_NPOT;
157 key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT;
158 key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT;
159 }
160 }
Romain Guyac670c02010-07-27 17:39:27 -0700161 if (hasGradient) key |= PROGRAM_KEY_GRADIENT;
Romain Guyee916f12010-09-20 17:53:08 -0700162 key |= programid(gradientType) << PROGRAM_GRADIENT_TYPE_SHIFT;
163 if (isBitmapFirst) key |= PROGRAM_KEY_BITMAP_FIRST;
Romain Guyac670c02010-07-27 17:39:27 -0700164 if (hasBitmap && hasGradient) {
165 key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT;
166 }
167 switch (colorOp) {
168 case kColorMatrix:
169 key |= PROGRAM_KEY_COLOR_MATRIX;
170 break;
171 case kColorLighting:
172 key |= PROGRAM_KEY_COLOR_LIGHTING;
173 break;
174 case kColorBlend:
175 key |= PROGRAM_KEY_COLOR_BLEND;
176 key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT;
177 break;
178 case kColorNone:
179 break;
180 }
Romain Guya5aed0d2010-09-09 14:42:43 -0700181 key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT;
Romain Guyf607bdc2010-09-10 19:20:06 -0700182 if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST;
Romain Guyac670c02010-07-27 17:39:27 -0700183 return key;
184 }
Romain Guyee916f12010-09-20 17:53:08 -0700185
186 void log(const char* message) const {
187 programid k = key();
188 PROGRAM_LOGD("%s (key = 0x%.8x%.8x)", message, uint32_t(k >> 32),
189 uint32_t(k & 0xffffffff));
190 }
Romain Guyac670c02010-07-27 17:39:27 -0700191}; // struct ProgramDescription
192
193/**
194 * Generates and caches program. Programs are generated based on
195 * ProgramDescriptions.
196 */
197class ProgramCache {
198public:
199 ProgramCache();
200 ~ProgramCache();
201
202 Program* get(const ProgramDescription& description);
203
204 void clear();
205
206private:
207 Program* generateProgram(const ProgramDescription& description, programid key);
208 String8 generateVertexShader(const ProgramDescription& description);
209 String8 generateFragmentShader(const ProgramDescription& description);
Romain Guy48daa542010-08-10 19:21:34 -0700210 void generateBlend(String8& shader, const char* name, SkXfermode::Mode mode);
Romain Guy889f8d12010-07-29 14:37:42 -0700211 void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT);
Romain Guyac670c02010-07-27 17:39:27 -0700212
Romain Guydb1938e2010-08-02 18:50:22 -0700213 void printLongString(const String8& shader) const;
214
Romain Guyac670c02010-07-27 17:39:27 -0700215 KeyedVector<programid, Program*> mCache;
Romain Guyac670c02010-07-27 17:39:27 -0700216}; // class ProgramCache
217
218}; // namespace uirenderer
219}; // namespace android
220
221#endif // ANDROID_UI_PROGRAM_CACHE_H