SkiaShader.h revision 43ccf4663c822ddd435b7683cc05221f6169c6c3
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 31namespace android { 32namespace 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 */ 42struct 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 66 inline SkShader *getSkShader() { 67 return mKey; 68 } 69 70 inline bool blend() const { 71 return mBlend; 72 } 73 74 Type type() const { 75 return mType; 76 } 77 78 virtual void set(TextureCache* textureCache, GradientCache* gradientCache) { 79 mTextureCache = textureCache; 80 mGradientCache = gradientCache; 81 } 82 83 virtual void updateTransforms(Program* program, const mat4& modelView, 84 const Snapshot& snapshot) { 85 } 86 87 uint32_t getGenerationId() { 88 return mGenerationId; 89 } 90 91 void setMatrix(SkMatrix* matrix) { 92 updateLocalMatrix(matrix); 93 mGenerationId++; 94 } 95 96 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 107protected: 108 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 129private: 130 uint32_t mGenerationId; 131}; // struct SkiaShader 132 133 134/////////////////////////////////////////////////////////////////////////////// 135// Implementations 136/////////////////////////////////////////////////////////////////////////////// 137 138/** 139 * A shader that draws a bitmap. 140 */ 141struct 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 151private: 152 SkiaBitmapShader() { 153 } 154 155 /** 156 * This method does not work for n == 0. 157 */ 158 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 */ 171struct 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 182private: 183 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 */ 195struct 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 206protected: 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); 209 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 */ 220struct 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 227private: 228 SkiaCircularGradientShader() { 229 } 230}; // struct SkiaCircularGradientShader 231 232/** 233 * A shader that draws two shaders, composited with an xfermode. 234 */ 235struct 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 246private: 247 SkiaComposeShader(): mCleanup(false) { 248 } 249 250 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