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