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