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_HWUI_SKIA_SHADER_H 18 #define ANDROID_HWUI_SKIA_SHADER_H 19 20 #include <SkShader.h> 21 #include <SkXfermode.h> 22 23 #include <GLES2/gl2.h> 24 25 #include <cutils/compiler.h> 26 27 #include "Extensions.h" 28 #include "ProgramCache.h" 29 #include "TextureCache.h" 30 #include "GradientCache.h" 31 #include "Snapshot.h" 32 33 namespace android { 34 namespace uirenderer { 35 36 /////////////////////////////////////////////////////////////////////////////// 37 // Base shader 38 /////////////////////////////////////////////////////////////////////////////// 39 40 /** 41 * Represents a Skia shader. A shader will modify the GL context and active 42 * program to recreate the original effect. 43 */ 44 struct SkiaShader { 45 /** 46 * Type of Skia shader in use. 47 */ 48 enum Type { 49 kNone, 50 kBitmap, 51 kLinearGradient, 52 kCircularGradient, 53 kSweepGradient, 54 kCompose 55 }; 56 57 ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, 58 SkShader::TileMode tileY, SkMatrix* matrix, bool blend); 59 virtual ~SkiaShader(); 60 61 virtual SkiaShader* copy() = 0; 62 void copyFrom(const SkiaShader& shader); 63 64 virtual void describe(ProgramDescription& description, const Extensions& extensions); 65 virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 66 GLuint* textureUnit); 67 68 inline SkShader *getSkShader() { 69 return mKey; 70 } 71 72 inline bool blend() const { 73 return mBlend; 74 } 75 76 Type type() const { 77 return mType; 78 } 79 80 virtual void set(TextureCache* textureCache, GradientCache* gradientCache) { 81 mTextureCache = textureCache; 82 mGradientCache = gradientCache; 83 } 84 85 virtual void updateTransforms(Program* program, const mat4& modelView, 86 const Snapshot& snapshot) { 87 } 88 89 uint32_t getGenerationId() { 90 return mGenerationId; 91 } 92 93 void setMatrix(SkMatrix* matrix) { 94 updateLocalMatrix(matrix); 95 mGenerationId++; 96 } 97 98 void updateLocalMatrix(const SkMatrix* matrix) { 99 if (matrix) { 100 mat4 localMatrix(*matrix); 101 mShaderMatrix.loadInverse(localMatrix); 102 } else { 103 mShaderMatrix.loadIdentity(); 104 } 105 } 106 107 void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); 108 109 protected: 110 SkiaShader() { 111 } 112 113 /** 114 * The appropriate texture unit must have been activated prior to invoking 115 * this method. 116 */ 117 inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT); 118 119 Type mType; 120 SkShader* mKey; 121 SkShader::TileMode mTileX; 122 SkShader::TileMode mTileY; 123 bool mBlend; 124 125 TextureCache* mTextureCache; 126 GradientCache* mGradientCache; 127 128 mat4 mUnitMatrix; 129 mat4 mShaderMatrix; 130 131 private: 132 uint32_t mGenerationId; 133 }; // struct SkiaShader 134 135 136 /////////////////////////////////////////////////////////////////////////////// 137 // Implementations 138 /////////////////////////////////////////////////////////////////////////////// 139 140 /** 141 * A shader that draws a bitmap. 142 */ 143 struct SkiaBitmapShader: public SkiaShader { 144 ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, 145 SkShader::TileMode tileY, SkMatrix* matrix, bool blend); 146 SkiaShader* copy(); 147 148 void describe(ProgramDescription& description, const Extensions& extensions); 149 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 150 GLuint* textureUnit); 151 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot); 152 153 private: 154 SkiaBitmapShader() { 155 } 156 157 /** 158 * This method does not work for n == 0. 159 */ 160 inline bool isPowerOfTwo(unsigned int n) { 161 return !(n & (n - 1)); 162 } 163 164 SkBitmap* mBitmap; 165 Texture* mTexture; 166 GLenum mWrapS; 167 GLenum mWrapT; 168 }; // struct SkiaBitmapShader 169 170 /** 171 * A shader that draws a linear gradient. 172 */ 173 struct SkiaLinearGradientShader: public SkiaShader { 174 ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, 175 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 176 ~SkiaLinearGradientShader(); 177 SkiaShader* copy(); 178 179 void describe(ProgramDescription& description, const Extensions& extensions); 180 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 181 GLuint* textureUnit); 182 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot); 183 184 private: 185 SkiaLinearGradientShader() { 186 } 187 188 float* mBounds; 189 uint32_t* mColors; 190 float* mPositions; 191 int mCount; 192 }; // struct SkiaLinearGradientShader 193 194 /** 195 * A shader that draws a sweep gradient. 196 */ 197 struct SkiaSweepGradientShader: public SkiaShader { 198 ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, 199 int count, SkShader* key, SkMatrix* matrix, bool blend); 200 ~SkiaSweepGradientShader(); 201 SkiaShader* copy(); 202 203 virtual void describe(ProgramDescription& description, const Extensions& extensions); 204 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 205 GLuint* textureUnit); 206 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot); 207 208 protected: 209 SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions, 210 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 211 SkiaSweepGradientShader() { 212 } 213 214 uint32_t* mColors; 215 float* mPositions; 216 int mCount; 217 }; // struct SkiaSweepGradientShader 218 219 /** 220 * A shader that draws a circular gradient. 221 */ 222 struct SkiaCircularGradientShader: public SkiaSweepGradientShader { 223 ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, 224 float* positions, int count, SkShader* key,SkShader::TileMode tileMode, 225 SkMatrix* matrix, bool blend); 226 SkiaShader* copy(); 227 228 void describe(ProgramDescription& description, const Extensions& extensions); 229 230 private: 231 SkiaCircularGradientShader() { 232 } 233 }; // struct SkiaCircularGradientShader 234 235 /** 236 * A shader that draws two shaders, composited with an xfermode. 237 */ 238 struct SkiaComposeShader: public SkiaShader { 239 ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, 240 SkShader* key); 241 ~SkiaComposeShader(); 242 SkiaShader* copy(); 243 244 void set(TextureCache* textureCache, GradientCache* gradientCache); 245 246 void describe(ProgramDescription& description, const Extensions& extensions); 247 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 248 GLuint* textureUnit); 249 250 private: 251 SkiaComposeShader(): mCleanup(false) { 252 } 253 254 void cleanup() { 255 mCleanup = true; 256 } 257 258 SkiaShader* mFirst; 259 SkiaShader* mSecond; 260 SkXfermode::Mode mMode; 261 262 bool mCleanup; 263 }; // struct SkiaComposeShader 264 265 }; // namespace uirenderer 266 }; // namespace android 267 268 #endif // ANDROID_HWUI_SKIA_SHADER_H 269