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 getSkShaderSkiaShader68 inline SkShader* getSkShader() { 69 return mKey; 70 } 71 blendSkiaShader72 inline bool blend() const { 73 return mBlend; 74 } 75 typeSkiaShader76 Type type() const { 77 return mType; 78 } 79 setSkiaShader80 virtual void set(TextureCache* textureCache, GradientCache* gradientCache) { 81 mTextureCache = textureCache; 82 mGradientCache = gradientCache; 83 } 84 getGenerationIdSkiaShader85 uint32_t getGenerationId() { 86 return mGenerationId; 87 } 88 setMatrixSkiaShader89 void setMatrix(SkMatrix* matrix) { 90 updateLocalMatrix(matrix); 91 mGenerationId++; 92 } 93 updateLocalMatrixSkiaShader94 void updateLocalMatrix(const SkMatrix* matrix) { 95 if (matrix) { 96 mat4 localMatrix(*matrix); 97 mShaderMatrix.loadInverse(localMatrix); 98 } else { 99 mShaderMatrix.loadIdentity(); 100 } 101 } 102 103 void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); 104 105 protected: SkiaShaderSkiaShader106 SkiaShader() { 107 } 108 109 /** 110 * The appropriate texture unit must have been activated prior to invoking 111 * this method. 112 */ 113 inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT); 114 115 Type mType; 116 SkShader* mKey; 117 SkShader::TileMode mTileX; 118 SkShader::TileMode mTileY; 119 bool mBlend; 120 121 TextureCache* mTextureCache; 122 GradientCache* mGradientCache; 123 124 mat4 mUnitMatrix; 125 mat4 mShaderMatrix; 126 127 private: 128 uint32_t mGenerationId; 129 }; // struct SkiaShader 130 131 132 /////////////////////////////////////////////////////////////////////////////// 133 // Implementations 134 /////////////////////////////////////////////////////////////////////////////// 135 136 /** 137 * A shader that draws a bitmap. 138 */ 139 struct SkiaBitmapShader: public SkiaShader { 140 ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, 141 SkShader::TileMode tileY, SkMatrix* matrix, bool blend); 142 SkiaShader* copy(); 143 144 void describe(ProgramDescription& description, const Extensions& extensions); 145 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 146 GLuint* textureUnit); 147 148 private: SkiaBitmapShaderSkiaBitmapShader149 SkiaBitmapShader() { 150 } 151 152 SkBitmap* mBitmap; 153 Texture* mTexture; 154 GLenum mWrapS; 155 GLenum mWrapT; 156 }; // struct SkiaBitmapShader 157 158 /** 159 * A shader that draws a linear gradient. 160 */ 161 struct SkiaLinearGradientShader: public SkiaShader { 162 ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, 163 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 164 ~SkiaLinearGradientShader(); 165 SkiaShader* copy(); 166 167 void describe(ProgramDescription& description, const Extensions& extensions); 168 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 169 GLuint* textureUnit); 170 171 private: SkiaLinearGradientShaderSkiaLinearGradientShader172 SkiaLinearGradientShader() { 173 } 174 175 bool mIsSimple; 176 float* mBounds; 177 uint32_t* mColors; 178 float* mPositions; 179 int mCount; 180 }; // struct SkiaLinearGradientShader 181 182 /** 183 * A shader that draws a sweep gradient. 184 */ 185 struct SkiaSweepGradientShader: public SkiaShader { 186 ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, 187 int count, SkShader* key, SkMatrix* matrix, bool blend); 188 ~SkiaSweepGradientShader(); 189 SkiaShader* copy(); 190 191 virtual void describe(ProgramDescription& description, const Extensions& extensions); 192 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 193 GLuint* textureUnit); 194 195 protected: 196 SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions, 197 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); SkiaSweepGradientShaderSkiaSweepGradientShader198 SkiaSweepGradientShader() { 199 } 200 201 bool mIsSimple; 202 uint32_t* mColors; 203 float* mPositions; 204 int mCount; 205 }; // struct SkiaSweepGradientShader 206 207 /** 208 * A shader that draws a circular gradient. 209 */ 210 struct SkiaCircularGradientShader: public SkiaSweepGradientShader { 211 ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, 212 float* positions, int count, SkShader* key,SkShader::TileMode tileMode, 213 SkMatrix* matrix, bool blend); 214 SkiaShader* copy(); 215 216 void describe(ProgramDescription& description, const Extensions& extensions); 217 218 private: SkiaCircularGradientShaderSkiaCircularGradientShader219 SkiaCircularGradientShader() { 220 } 221 }; // struct SkiaCircularGradientShader 222 223 /** 224 * A shader that draws two shaders, composited with an xfermode. 225 */ 226 struct SkiaComposeShader: public SkiaShader { 227 ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, 228 SkShader* key); 229 ~SkiaComposeShader(); 230 SkiaShader* copy(); 231 232 void set(TextureCache* textureCache, GradientCache* gradientCache); 233 234 void describe(ProgramDescription& description, const Extensions& extensions); 235 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 236 GLuint* textureUnit); 237 238 private: SkiaComposeShaderSkiaComposeShader239 SkiaComposeShader(): mCleanup(false) { 240 } 241 cleanupSkiaComposeShader242 void cleanup() { 243 mCleanup = true; 244 } 245 246 SkiaShader* mFirst; 247 SkiaShader* mSecond; 248 SkXfermode::Mode mMode; 249 250 bool mCleanup; 251 }; // struct SkiaComposeShader 252 253 }; // namespace uirenderer 254 }; // namespace android 255 256 #endif // ANDROID_HWUI_SKIA_SHADER_H 257