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