SkiaShader.h revision 01d065795794fa56be660d6346e4830eb7e90a41
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 void describe(ProgramDescription& description, const Extensions& extensions); 60 virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 61 GLuint* textureUnit); 62 63 inline SkShader *getSkShader() { 64 return mKey; 65 } 66 67 inline bool blend() const { 68 return mBlend; 69 } 70 71 Type type() const { 72 return mType; 73 } 74 75 virtual void set(TextureCache* textureCache, GradientCache* gradientCache) { 76 mTextureCache = textureCache; 77 mGradientCache = gradientCache; 78 } 79 80 virtual void updateTransforms(Program* program, const mat4& modelView, 81 const Snapshot& snapshot) { 82 } 83 84 void setMatrix(SkMatrix* matrix) { 85 updateLocalMatrix(matrix); 86 } 87 88 void updateLocalMatrix(const SkMatrix* matrix) { 89 if (matrix) { 90 mat4 localMatrix(*matrix); 91 mShaderMatrix.loadInverse(localMatrix); 92 } else { 93 mShaderMatrix.loadIdentity(); 94 } 95 } 96 97 void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); 98 99protected: 100 /** 101 * The appropriate texture unit must have been activated prior to invoking 102 * this method. 103 */ 104 inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT); 105 106 Type mType; 107 SkShader* mKey; 108 SkShader::TileMode mTileX; 109 SkShader::TileMode mTileY; 110 bool mBlend; 111 112 TextureCache* mTextureCache; 113 GradientCache* mGradientCache; 114 115 mat4 mUnitMatrix; 116 mat4 mShaderMatrix; 117}; // struct SkiaShader 118 119 120/////////////////////////////////////////////////////////////////////////////// 121// Implementations 122/////////////////////////////////////////////////////////////////////////////// 123 124/** 125 * A shader that draws a bitmap. 126 */ 127struct SkiaBitmapShader: public SkiaShader { 128 SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, 129 SkShader::TileMode tileY, SkMatrix* matrix, bool blend); 130 131 void describe(ProgramDescription& description, const Extensions& extensions); 132 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 133 GLuint* textureUnit); 134 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot); 135 136private: 137 /** 138 * This method does not work for n == 0. 139 */ 140 inline bool isPowerOfTwo(unsigned int n) { 141 return !(n & (n - 1)); 142 } 143 144 SkBitmap* mBitmap; 145 Texture* mTexture; 146 GLenum mWrapS; 147 GLenum mWrapT; 148}; // struct SkiaBitmapShader 149 150/** 151 * A shader that draws a linear gradient. 152 */ 153struct SkiaLinearGradientShader: public SkiaShader { 154 SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, int count, 155 SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 156 ~SkiaLinearGradientShader(); 157 158 void describe(ProgramDescription& description, const Extensions& extensions); 159 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 160 GLuint* textureUnit); 161 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot); 162 163private: 164 float* mBounds; 165 uint32_t* mColors; 166 float* mPositions; 167 int mCount; 168}; // struct SkiaLinearGradientShader 169 170/** 171 * A shader that draws a sweep gradient. 172 */ 173struct SkiaSweepGradientShader: public SkiaShader { 174 SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, int count, 175 SkShader* key, SkMatrix* matrix, bool blend); 176 ~SkiaSweepGradientShader(); 177 178 virtual void describe(ProgramDescription& description, const Extensions& extensions); 179 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 180 GLuint* textureUnit); 181 void updateTransforms(Program* program, const mat4& modelView, const Snapshot& snapshot); 182 183protected: 184 SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions, 185 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 186 187 uint32_t* mColors; 188 float* mPositions; 189 int mCount; 190}; // struct SkiaSweepGradientShader 191 192/** 193 * A shader that draws a circular gradient. 194 */ 195struct SkiaCircularGradientShader: public SkiaSweepGradientShader { 196 SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, float* positions, 197 int count, SkShader* key,SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 198 199 void describe(ProgramDescription& description, const Extensions& extensions); 200}; // struct SkiaCircularGradientShader 201 202/** 203 * A shader that draws two shaders, composited with an xfermode. 204 */ 205struct SkiaComposeShader: public SkiaShader { 206 SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, SkShader* key); 207 208 void set(TextureCache* textureCache, GradientCache* gradientCache); 209 210 void describe(ProgramDescription& description, const Extensions& extensions); 211 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 212 GLuint* textureUnit); 213 214private: 215 SkiaShader* mFirst; 216 SkiaShader* mSecond; 217 SkXfermode::Mode mMode; 218}; // struct SkiaComposeShader 219 220}; // namespace uirenderer 221}; // namespace android 222 223#endif // ANDROID_HWUI_SKIA_SHADER_H 224