SkiaShader.h revision 564acf7c9bff822f608cda0d5df0a64a9f9aaefd
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 36class 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 */ 46class SkiaShader { 47public: 48 /** 49 * Type of Skia shader in use. 50 */ 51 enum Type { 52 kNone, 53 kBitmap, 54 kLinearGradient, 55 kCircularGradient, 56 kSweepGradient, 57 kCompose 58 }; 59 60 ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, 61 SkShader::TileMode tileY, SkMatrix* matrix, bool blend); 62 virtual ~SkiaShader(); 63 64 virtual SkiaShader* copy() = 0; 65 void copyFrom(const SkiaShader& shader); 66 67 virtual void describe(ProgramDescription& description, const Extensions& extensions); 68 virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 69 GLuint* textureUnit); 70 71 inline SkShader* getSkShader() { 72 return mKey; 73 } 74 75 inline bool blend() const { 76 return mBlend; 77 } 78 79 Type type() const { 80 return mType; 81 } 82 83 virtual void setCaches(Caches& caches) { 84 mCaches = &caches; 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 * The appropriate texture unit must have been activated prior to invoking 112 * this method. 113 */ 114 inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT); 115 116 Type mType; 117 SkShader* mKey; 118 SkShader::TileMode mTileX; 119 SkShader::TileMode mTileY; 120 bool mBlend; 121 122 Caches* mCaches; 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, 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 setCaches(Caches& caches) { 233 SkiaShader::setCaches(caches); 234 mFirst->setCaches(caches); 235 mSecond->setCaches(caches); 236 } 237 238 void describe(ProgramDescription& description, const Extensions& extensions); 239 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 240 GLuint* textureUnit); 241 242private: 243 SkiaComposeShader(): mCleanup(false) { 244 } 245 246 void cleanup() { 247 mCleanup = true; 248 } 249 250 SkiaShader* mFirst; 251 SkiaShader* mSecond; 252 SkXfermode::Mode mMode; 253 254 bool mCleanup; 255}; // struct SkiaComposeShader 256 257}; // namespace uirenderer 258}; // namespace android 259 260#endif // ANDROID_HWUI_SKIA_SHADER_H 261