SkiaShader.h revision 920287399aa640a5352e02ab19fd23b67a8c975b
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 */ 46struct SkiaShader { 47 /** 48 * Type of Skia shader in use. 49 */ 50 enum Type { 51 kNone, 52 kBitmap, 53 kLinearGradient, 54 kCircularGradient, 55 kSweepGradient, 56 kCompose 57 }; 58 59 ANDROID_API SkiaShader(Type type, SkShader* key, SkShader::TileMode tileX, 60 SkShader::TileMode tileY, SkMatrix* matrix, bool blend); 61 virtual ~SkiaShader(); 62 63 virtual SkiaShader* copy() = 0; 64 void copyFrom(const SkiaShader& shader); 65 66 virtual void describe(ProgramDescription& description, const Extensions& extensions); 67 virtual void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 68 GLuint* textureUnit); 69 70 inline SkShader* getSkShader() { 71 return mKey; 72 } 73 74 inline bool blend() const { 75 return mBlend; 76 } 77 78 Type type() const { 79 return mType; 80 } 81 82 virtual void setCaches(Caches& caches) { 83 mCaches = &caches; 84 } 85 86 uint32_t getGenerationId() { 87 return mGenerationId; 88 } 89 90 void setMatrix(SkMatrix* matrix) { 91 updateLocalMatrix(matrix); 92 mGenerationId++; 93 } 94 95 void updateLocalMatrix(const SkMatrix* matrix) { 96 if (matrix) { 97 mat4 localMatrix(*matrix); 98 mShaderMatrix.loadInverse(localMatrix); 99 } else { 100 mShaderMatrix.loadIdentity(); 101 } 102 } 103 104 void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); 105 106protected: 107 SkiaShader(); 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 Caches* mCaches; 122 123 mat4 mUnitMatrix; 124 mat4 mShaderMatrix; 125 126private: 127 uint32_t mGenerationId; 128}; // struct SkiaShader 129 130 131/////////////////////////////////////////////////////////////////////////////// 132// Implementations 133/////////////////////////////////////////////////////////////////////////////// 134 135/** 136 * A shader that draws a bitmap. 137 */ 138struct SkiaBitmapShader: public SkiaShader { 139 ANDROID_API SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::TileMode tileX, 140 SkShader::TileMode tileY, SkMatrix* matrix, bool blend); 141 SkiaShader* copy(); 142 143 void describe(ProgramDescription& description, const Extensions& extensions); 144 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 145 GLuint* textureUnit); 146 147private: 148 SkiaBitmapShader() : mBitmap(NULL), mTexture(NULL) { 149 } 150 151 SkBitmap* mBitmap; 152 Texture* mTexture; 153 GLenum mWrapS; 154 GLenum mWrapT; 155}; // struct SkiaBitmapShader 156 157/** 158 * A shader that draws a linear gradient. 159 */ 160struct SkiaLinearGradientShader: public SkiaShader { 161 ANDROID_API SkiaLinearGradientShader(float* bounds, uint32_t* colors, float* positions, 162 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 163 ~SkiaLinearGradientShader(); 164 SkiaShader* copy(); 165 166 void describe(ProgramDescription& description, const Extensions& extensions); 167 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 168 GLuint* textureUnit); 169 170private: 171 SkiaLinearGradientShader() { 172 } 173 174 bool mIsSimple; 175 float* mBounds; 176 uint32_t* mColors; 177 float* mPositions; 178 int mCount; 179}; // struct SkiaLinearGradientShader 180 181/** 182 * A shader that draws a sweep gradient. 183 */ 184struct SkiaSweepGradientShader: public SkiaShader { 185 ANDROID_API SkiaSweepGradientShader(float x, float y, uint32_t* colors, float* positions, 186 int count, SkShader* key, SkMatrix* matrix, bool blend); 187 ~SkiaSweepGradientShader(); 188 SkiaShader* copy(); 189 190 virtual void describe(ProgramDescription& description, const Extensions& extensions); 191 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 192 GLuint* textureUnit); 193 194protected: 195 SkiaSweepGradientShader(Type type, float x, float y, uint32_t* colors, float* positions, 196 int count, SkShader* key, SkShader::TileMode tileMode, SkMatrix* matrix, bool blend); 197 SkiaSweepGradientShader() { 198 } 199 200 bool mIsSimple; 201 uint32_t* mColors; 202 float* mPositions; 203 int mCount; 204}; // struct SkiaSweepGradientShader 205 206/** 207 * A shader that draws a circular gradient. 208 */ 209struct SkiaCircularGradientShader: public SkiaSweepGradientShader { 210 ANDROID_API SkiaCircularGradientShader(float x, float y, float radius, uint32_t* colors, 211 float* positions, int count, SkShader* key,SkShader::TileMode tileMode, 212 SkMatrix* matrix, bool blend); 213 SkiaShader* copy(); 214 215 void describe(ProgramDescription& description, const Extensions& extensions); 216 217private: 218 SkiaCircularGradientShader() { 219 } 220}; // struct SkiaCircularGradientShader 221 222/** 223 * A shader that draws two shaders, composited with an xfermode. 224 */ 225struct SkiaComposeShader: public SkiaShader { 226 ANDROID_API SkiaComposeShader(SkiaShader* first, SkiaShader* second, SkXfermode::Mode mode, 227 SkShader* key); 228 ~SkiaComposeShader(); 229 SkiaShader* copy(); 230 231 void setCaches(Caches& caches) { 232 SkiaShader::setCaches(caches); 233 mFirst->setCaches(caches); 234 mSecond->setCaches(caches); 235 } 236 237 void describe(ProgramDescription& description, const Extensions& extensions); 238 void setupProgram(Program* program, const mat4& modelView, const Snapshot& snapshot, 239 GLuint* textureUnit); 240 241private: 242 SkiaComposeShader(): mCleanup(false) { 243 } 244 245 void cleanup() { 246 mCleanup = true; 247 } 248 249 SkiaShader* mFirst; 250 SkiaShader* mSecond; 251 SkXfermode::Mode mMode; 252 253 bool mCleanup; 254}; // struct SkiaComposeShader 255 256}; // namespace uirenderer 257}; // namespace android 258 259#endif // ANDROID_HWUI_SKIA_SHADER_H 260