ProgramCache.h revision f607bdc167f66b3e7003acaa4736ae46d78c1492
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 0 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/* 48 * IMPORTANT: All 32 bits are used, switch to a long. 49 */ 50#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 58#define PROGRAM_KEY_BITMAP_NPOT 0x100 59#define PROGRAM_KEY_SWAP_SRC_DST 0x2000 60 61#define PROGRAM_KEY_BITMAP_WRAPS_MASK 0x600 62#define PROGRAM_KEY_BITMAP_WRAPT_MASK 0x1800 63 64// Encode the xfermodes on 6 bits 65#define PROGRAM_MAX_XFERMODE 0x1f 66#define PROGRAM_XFERMODE_SHADER_SHIFT 26 67#define PROGRAM_XFERMODE_COLOR_OP_SHIFT 20 68#define PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT 14 69 70#define PROGRAM_BITMAP_WRAPS_SHIFT 9 71#define PROGRAM_BITMAP_WRAPT_SHIFT 11 72 73/////////////////////////////////////////////////////////////////////////////// 74// Types 75/////////////////////////////////////////////////////////////////////////////// 76 77/* 78 * IMPORTANT: All 32 bits are used, switch to a long. 79 */ 80typedef uint32_t programid; 81 82/////////////////////////////////////////////////////////////////////////////// 83// Cache 84/////////////////////////////////////////////////////////////////////////////// 85 86/** 87 * Describe the features required for a given program. The features 88 * determine the generation of both the vertex and fragment shaders. 89 * A ProgramDescription must be used in conjunction with a ProgramCache. 90 */ 91struct ProgramDescription { 92 enum ColorModifier { 93 kColorNone, 94 kColorMatrix, 95 kColorLighting, 96 kColorBlend 97 }; 98 99 ProgramDescription(): 100 hasTexture(false), hasAlpha8Texture(false), 101 hasBitmap(false), isBitmapNpot(false), hasGradient(false), 102 shadersMode(SkXfermode::kClear_Mode), isBitmapFirst(false), 103 bitmapWrapS(GL_CLAMP_TO_EDGE), bitmapWrapT(GL_CLAMP_TO_EDGE), 104 colorOp(kColorNone), colorMode(SkXfermode::kClear_Mode), 105 framebufferMode(SkXfermode::kClear_Mode), swapSrcDst(false) { 106 } 107 108 // Texturing 109 bool hasTexture; 110 bool hasAlpha8Texture; 111 112 // Shaders 113 bool hasBitmap; 114 bool isBitmapNpot; 115 bool hasGradient; 116 SkXfermode::Mode shadersMode; 117 bool isBitmapFirst; 118 GLenum bitmapWrapS; 119 GLenum bitmapWrapT; 120 121 // Color operations 122 int colorOp; 123 SkXfermode::Mode colorMode; 124 125 // Framebuffer blending (requires Extensions.hasFramebufferFetch()) 126 // Ignored for all values < SkXfermode::kPlus_Mode 127 SkXfermode::Mode framebufferMode; 128 bool swapSrcDst; 129 130 inline uint32_t getEnumForWrap(GLenum wrap) const { 131 switch (wrap) { 132 case GL_CLAMP_TO_EDGE: 133 return 0; 134 case GL_REPEAT: 135 return 1; 136 case GL_MIRRORED_REPEAT: 137 return 2; 138 } 139 return 0; 140 } 141 142 programid key() const { 143 programid key = 0; 144 if (hasTexture) key |= PROGRAM_KEY_TEXTURE; 145 if (hasAlpha8Texture) key |= PROGRAM_KEY_A8_TEXTURE; 146 if (hasBitmap) { 147 key |= PROGRAM_KEY_BITMAP; 148 if (isBitmapNpot) { 149 key |= PROGRAM_KEY_BITMAP_NPOT; 150 key |= getEnumForWrap(bitmapWrapS) << PROGRAM_BITMAP_WRAPS_SHIFT; 151 key |= getEnumForWrap(bitmapWrapT) << PROGRAM_BITMAP_WRAPT_SHIFT; 152 } 153 } 154 if (hasGradient) key |= PROGRAM_KEY_GRADIENT; 155 if (isBitmapFirst) key |= PROGRAM_KEY_BITMAP_FIRST; 156 if (hasBitmap && hasGradient) { 157 key |= (shadersMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_SHADER_SHIFT; 158 } 159 switch (colorOp) { 160 case kColorMatrix: 161 key |= PROGRAM_KEY_COLOR_MATRIX; 162 break; 163 case kColorLighting: 164 key |= PROGRAM_KEY_COLOR_LIGHTING; 165 break; 166 case kColorBlend: 167 key |= PROGRAM_KEY_COLOR_BLEND; 168 key |= (colorMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_COLOR_OP_SHIFT; 169 break; 170 case kColorNone: 171 break; 172 } 173 key |= (framebufferMode & PROGRAM_MAX_XFERMODE) << PROGRAM_XFERMODE_FRAMEBUFFER_SHIFT; 174 if (swapSrcDst) key |= PROGRAM_KEY_SWAP_SRC_DST; 175 return key; 176 } 177}; // struct ProgramDescription 178 179/** 180 * Generates and caches program. Programs are generated based on 181 * ProgramDescriptions. 182 */ 183class ProgramCache { 184public: 185 ProgramCache(); 186 ~ProgramCache(); 187 188 Program* get(const ProgramDescription& description); 189 190 void clear(); 191 192private: 193 Program* generateProgram(const ProgramDescription& description, programid key); 194 String8 generateVertexShader(const ProgramDescription& description); 195 String8 generateFragmentShader(const ProgramDescription& description); 196 void generateBlend(String8& shader, const char* name, SkXfermode::Mode mode); 197 void generateTextureWrap(String8& shader, GLenum wrapS, GLenum wrapT); 198 199 void printLongString(const String8& shader) const; 200 201 KeyedVector<programid, Program*> mCache; 202}; // class ProgramCache 203 204}; // namespace uirenderer 205}; // namespace android 206 207#endif // ANDROID_UI_PROGRAM_CACHE_H 208