ProgramCache.h revision 48daa54d31fc59ec969dcff65eb3cbb0ce879a8d
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 1 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#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 55#define PROGRAM_KEY_BITMAP_NPOT 0x100 56 57#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600 58#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800 59 60// Encode the xfermodes on 6 bits 61#define PROGRAM_MAX_XFERMODE 0x1f 62#define PROGRAM_XFERMODE_SHADER_SHIFT 26 63#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20 64 65#define PROGRAM_BITMAP_WRAPS_SHIFT 9 66#define PROGRAM_BITMAP_WRAPT_SHIFT 11 67 68/////////////////////////////////////////////////////////////////////////////// 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), 93 hasBitmap(false), isBitmapNpot(false), hasGradient(false), 94 shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false), 95 bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE), 96 colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode) { 97 } 98 99 // Texturing 100 bool hasTexture; 101 bool hasAlpha8Texture; 102 103 // Shaders 104 bool hasBitmap; 105 bool isBitmapNpot; 106 bool hasGradient; 107 SkXfermode::Mode shadersMode; 108 bool isBitmapFirst; 109 GLenum bitmapWrapS; 110 GLenum bitmapWrapT; 111 112 // Color operations 113 int colorOp; 114 SkXfermode::Mode colorMode; 115 116 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 128 programid key() const { 129 programid key = 0; 130 if (hasTexture) key |= PROGRAM_KEY_TEXTURE; 131 if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE; 132 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 } 140 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 generateBlend(String8& shader, const char* name, SkXfermode::Mode mode); 181 void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT); 182 183 void printLongString(const String8& shader) const; 184 185 KeyedVector<programid, Program*> mCache; 186 187}; // class ProgramCache 188 189}; // namespace uirenderer 190}; // namespace android 191 192#endif // ANDROID_UI_PROGRAM_CACHE_H 193