SkiaShader.h revision dcfc836b457a87881da409e1acf251515f121446
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 33namespace android { 34namespace 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 */ 44struct 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 68 inline SkShader* getSkShader() { 69 return mKey; 70 } 71 72 inline bool blend() const { 73 return mBlend; 74 } 75 76 Type type() const { 77 return mType; 78 } 79 80 virtual void set(TextureCache* textureCache, GradientCache* gradientCache) { 81 mTextureCache = textureCache; 82 mGradientCache = gradientCache; 83 } 84 85 uint32_t getGenerationId() { 86 return mGenerationId; 87 } 88 89 void setMatrix(SkMatrix* matrix) { 90 updateLocalMatrix(matrix); 91 mGenerationId++; 92 } 93 94 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 105protected: 106 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 127private: 128 uint32_t mGenerationId; 129}; // struct SkiaShader 130 131 132/////////////////////////////////////////////////////////////////////////////// 133// Implementations 134/////////////////////////////////////////////////////////////////////////////// 135 136/** 137 * A shader that draws a bitmap. 138 */ 139struct 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 148private: 149 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 */ 161struct 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 171private: 172 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 */ 185struct 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 195protected: 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); 198 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 */ 210struct 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 218private: 219 SkiaCircularGradientShader() { 220 } 221}; // struct SkiaCircularGradientShader 222 223/** 224 * A shader that draws two shaders, composited with an xfermode. 225 */ 226struct 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 238private: 239 SkiaComposeShader(): mCleanup(false) { 240 } 241 242 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